/*
 * $Id: VKCAcl.java,v 1.30 2007/01/03 13:09:27 korowa Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: VKCAcl.java,v $
 * Revision 1.30  2007/01/03 13:09:27  korowa
 * bugfixing bei Delete-Funktion
 *
 * Revision 1.29  2006/12/20 09:20:31  korowa
 * Funktionen deleteAclEntry(), hasGroupEntry(VKCGroup), hasPublicEntry() für den vkc.external hinzugefügt.
 *
 * Revision 1.28  2005/08/09 22:43:27  marbobo
 * - Unnötige Import-Anweisungen entfernt
 *
 * Revision 1.27  2005/05/30 16:12:11  jonyp
 * added getAccessorPermString method
 *
 * Revision 1.26  2005/05/30 06:13:38  jonyp
 * *** empty log message ***
 *
 * Revision 1.25  2005/05/24 14:06:15  jonyp
 * neue funktionen
 *
 * Revision 1.24  2005/01/18 11:59:41  jonyp
 * - delete obsolete method hashCode()
 * - added creator/created to toString()
 *
 * Revision 1.23  2005/01/17 23:30:23  jonyp
 * added permString for unauthenticated/ldap-user/ldap-group
 *
 * Revision 1.22  2004/12/01 16:44:53  jonyp
 * added comment
 *
 * Revision 1.21  2004/07/20 08:38:46  jonyp
 * added copyright info + cvs log
 *
 *
 */

package vkc.security;

import java.io.Serializable;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
import java.util.HashMap;

import vkc.db.entities.VKCAclEntry;
import vkc.db.entities.VKCAclType;
import vkc.db.entities.VKCGroup;
import vkc.db.entities.VKCUser;
import vkc.db.entities.VKCPermission;
import vkc.db.serializer.VKCPermissionSerializer;
import vkc.exception.AclException;
import vkc.exception.DBException;

public class VKCAcl implements Serializable{

  private Vector aclEntries = new Vector();
  private Integer aclId = null;

  public VKCAcl() {
  }


  public Integer getAclId(){

      return aclId;
  }

  public void setAclId( Integer aclId ){
      this.aclId = aclId;
      for( int i = 0; i < aclEntries.size(); i++ ){
	  ((VKCAclEntry)aclEntries.elementAt(i)).setAclId( aclId );
      }
  }


  public boolean contains( VKCAclEntry ae ) {
      return aclEntries.contains( ae );
  }

  public void addAclEntry(VKCAclEntry ae) throws AclException{

      if( aclId == null ) {
	  aclId = ae.getAclId();

      } else {
	      if( ae.getAclId() == null ) {
	          ae.setAclId( this.getAclId() );
	      }
      }

      // Assert.notNull( aclId );
      if( aclId != null && !aclId.equals( ae.getAclId() ) )
	  throw new AclException( "aclId of that entry does not correspond to aclId of this VKCAcl!" );

      aclEntries.add(ae);
  }

  public void deleteAclEntry(VKCAclEntry ae) {
      aclEntries.remove(ae);
  }

  public Vector getAclEntries() {
      return this.aclEntries;
  }

  public String getUserPermString(Integer userId) {
      return getPermString( new Integer(VKCAclType.USER_TYPE), userId);
  }

  public String getGroupPermString(Integer groupId) {
      return getPermString( new Integer(VKCAclType.GROUP_TYPE), groupId);
  }

  public String getAnyotherPermString() {
      return getPermString( new Integer(VKCAclType.ANYOTHER_TYPE), null );
  }

  public String getMaskPermString() {
      return getPermString( new Integer(VKCAclType.MASK_TYPE), null );
  }

  public String getUnauthenticatedPermString() {
    return getPermString( new Integer(VKCAclType.UNAUTHENTICATED_TYPE), null );
  }
  
  public String getLdapGroupPermString() {
    return getPermString( new Integer(VKCAclType.LDAP_GROUP_TYPE), null );
  }
  
  public String getLdapUserPermString() {
    return getPermString( new Integer(VKCAclType.LDAP_USER_TYPE), null );
  }  
  
  public Vector getEntriesOfType(int aclTypeId) {

  	Vector entries = new Vector();
  	
  	for (Enumeration e = aclEntries.elements(); e.hasMoreElements(); ) {

        VKCAclEntry ae = (VKCAclEntry) e.nextElement();
        if (ae.getAclType().getAclTypeId().intValue() == aclTypeId ){
        	entries.add(ae);
        }
    }
  	
  	return entries;
  }
  
  public Vector getAccessorPermString(int aclTypeId) {
      
      Vector aclEntries = getEntriesOfType(aclTypeId);
      HashMap accessors = new HashMap(); 
      
      for (Enumeration e = aclEntries.elements(); e.hasMoreElements(); ) {
          VKCAclEntry ae = (VKCAclEntry) e.nextElement();

          // do this to filter doublettes out...
          accessors.put(ae.getAccessorId(), ae);    
      }
      
      // final resulting vector
      Vector accessorPermStrings = new Vector();
      
      for (Iterator iter = accessors.values().iterator(); iter.hasNext();) {
          VKCAclEntry ae = (VKCAclEntry) iter.next();

          AccessorPermPair app = new AccessorPermPair();
          app.setAccessorId(ae.getAccessorId());
          app.setAclTypeId(ae.getAclType().getAclTypeId());
          app.setPermTokenString(getPermString(ae.getAclType().getAclTypeId(), ae.getAccessorId()));
          
          accessorPermStrings.add(app);
      }   
      
      return (accessorPermStrings);
  }
  
  private String getPermString( Integer aclTypeId, Integer accessorId ) {
      String permString = "";
      VKCAclEntry ae;

      for (Enumeration e = aclEntries.elements(); e.hasMoreElements(); ) {

          ae = (VKCAclEntry) e.nextElement();
          if (ae.getAclType().getAclTypeId().intValue() == aclTypeId.intValue() ){
              if (accessorId != null) {
                  if (ae.getAccessorId().intValue() == accessorId.intValue()) {
                      permString = permString + ae.getPermission().getToken();
                  }
              } else {
                  permString = permString + ae.getPermission().getToken();
              }
          }
      }

      return permString;
  }

  /**
   * Returns a string representation of a VKCAcl
   * @return look at the description!
   */
  public String toString() {

      StringBuffer b = new StringBuffer();
      b.append( "AclId : AclEntryId : AclTypeId : AclType : AccessorId : PermToken : Creator : Created\n" );
      b.append( "-----------------------------------------------------\n" );

      for (Enumeration e = aclEntries.elements(); e.hasMoreElements(); ) {
          VKCAclEntry ae = (VKCAclEntry) e.nextElement();

		  b.append( ae.getAclId() );
		  b.append( " : " );
		  b.append( ae.getAclEntryId() );
		  b.append( " : " );
		  b.append( ae.getAclType().getAclTypeId() );
		  b.append( " : " );
		  b.append( ae.getAclType().getName() );
		  b.append( " : " );
		  b.append( ae.getAccessorId() );
		  b.append( " : " );
		  b.append( ae.getPermission().getToken() );
		  b.append( " : " );
		  b.append( ae.getCreatorId());
		  b.append( " : " );
		  b.append( ae.getCreated());
		  b.append( "\n" );
      }

      return b.toString();
  }

  public boolean hasUserEntry(VKCUser user) {

      VKCAclEntry ae;

      for (Enumeration e = aclEntries.elements(); e.hasMoreElements(); ) {
          ae = (VKCAclEntry) e.nextElement();
          if (ae.getAclType().getAclTypeId().intValue() == VKCAclType.USER_TYPE){
              if (ae.getAccessorId().intValue() == user.getUserId().intValue()) {
                  return true;
              }
          }
      }

      return false;
  }

  public boolean hasGroupEntry(VKCUser user) {

      VKCAclEntry ae;
     
      for (Enumeration e = aclEntries.elements(); e.hasMoreElements(); ) {
          ae = (VKCAclEntry) e.nextElement();

          if (ae.getAclType().getAclTypeId().intValue() == VKCAclType.GROUP_TYPE){
              if (user.isMemberOf(ae.getAccessorId()) == true) {
                  return true;
              }
          }
      }

      return false;
  }

  public String getEffectivePermissionString(VKCUser user) 
  	throws DBException {
  
      String effPerm = "";

      if (user.getAdminPrivileges() || user.getAdminPrivilegesByGroup()) {
          effPerm = VKCPermissionSerializer.retrieveContextPermissionsString(VKCPermission.CONTEXT_CATEGORY, true);
      } else {
          effPerm = this.getUserPermString(user.getUserId());
          //effPerm = this.getGroupPermString(userId);
          effPerm = effPerm + this.getAnyotherPermString();
          effPerm = effPerm + this.getMaskPermString();
      }
      return effPerm;
  }
  
  /**
   * 
   * @return true falls die Acl den Eintrag für die übergebene Gruppe enthält und false sonst
   */
  public boolean hasGroupEntry(VKCGroup group) {

      VKCAclEntry ae;
     
      for (Enumeration e = aclEntries.elements(); e.hasMoreElements(); ) {
          ae = (VKCAclEntry) e.nextElement();

          if (ae.getAclType().getAclTypeId().intValue() == VKCAclType.GROUP_TYPE){
              if (group.getGroupId().intValue() == ae.getAccessorId().intValue()) {
                  return true;
              }
          }
      }

      return false;
  }
  
  /**
   * 
   * @return true falls die Acl den Eintrag für ANYOTHER_TYPE enthält und false sonst
   */
  public boolean hasPublicEntry() {

      VKCAclEntry ae;
     
      for (Enumeration e = aclEntries.elements(); e.hasMoreElements(); ) {
          ae = (VKCAclEntry) e.nextElement();

          if (ae.getAclType().getAclTypeId().intValue() == VKCAclType.ANYOTHER_TYPE){              
                  return true;              
          }
      }

      return false;
  }

	/**
	 * Diese Funktion löscht alle VKCAclEntry für den eingegebenen
	 * Benutzer oder Gruppe
	 * 
	 * @param accesorType
	 * 		ID des VKCAclType von zu löschenden VKCAclEntry(Benutzer, Gruppe, ...)
	 * @param accesorId
	 * 		die Id des Benutzers oder der Gruppe (spielt bei accesorType public keine Rolle)
	 * 
	 */
public void deleteAclEntry(int accesorType,int accesorId) {
	 VKCAclEntry ae;
	 Iterator iter = aclEntries.iterator();
	 Vector temp = new Vector();
     while(iter.hasNext()) {
         ae = (VKCAclEntry) iter.next();
         if (!(ae.getAclType().getAclTypeId().intValue() == accesorType) || !(ae.getAccessorId().intValue() == accesorId)){        	 
            temp.add(ae);
          }         
     }
     aclEntries = temp;
}
  
}