/*
ESUP-portail is a french academic project developed under the GPL (General Public License) augmented according to the following :
A binary or source file developped by ESUP-portail can be used or compiled with products under Apache license.
The official english text of the GPL can be found here : http://www.gnu.org/licenses/gpl.html .
A non official french translation can be found here : http://www.linux-France.org/article/these/gpl.html .
The different kinds of licenses governing the products developed by the Apache foundation can be found here : http://www.apache.org/licenses .
It follows that you can as well as use download contents as well modify and redistribute them provided you respect the GPL terms.
Downloading and using such contents do not provide any guaranty.
Be sure that you have well understood the terms of the license before using the contents it covers.
The ESUP-portail distribution includes the following distributions :
    * UPortal :
      software developed by JA-SIG (Java Architecture - Special Interest Group)
      You can find the license page here : http://mis105.udel.edu/ja-sig/uportal/license.html
    * CAS :
      SSO solution developed by Yale University
      You can find the project page here : http://www.yale.edu/tp/auth
    * Cocoon :
      XML framework distributed by the Apache foundation under Apache license;
      Please find the full text here : http://cocoon.apache.org/2.1/license.html
    * Mod_dav:
      A DAV module for Apache web server
      You can find the project page here : http://www.webdav.org/mod_dav
    * IMP :
      webmail from Horde application framework
      You can find the project page here : http://www.horde.org
    * …. To be completed
*/
package org.esupportail.portal.channels.CStockage.channelAction.injac.acl;
 
import java.util.Enumeration;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.esupportail.portal.channels.CStockage.channelAction.injac.metadata.InjacSpaceManagementProperties;
import org.esupportail.portal.channels.CStockage.config.Space;
import org.esupportail.portal.channels.CStockage.exception.AclAccessException;
import org.esupportail.portal.channels.CStockage.exception.AclReadException;
import org.esupportail.portal.channels.CStockage.exception.AclWriteException;
import org.esupportail.portal.channels.CStockage.exception.ApplicationException;
import org.esupportail.portal.channels.CStockage.exception.DataBaseException;
import org.esupportail.portal.channels.CStockage.exception.NotSupportedAclException;
import org.esupportail.portal.channels.CStockage.exception.PropertiesException;
import org.esupportail.portal.channels.CStockage.exception.ServerException;
import org.esupportail.portal.channels.CStockage.provider.access.ServerAccess;
import org.esupportail.portal.channels.CStockage.spacesPersonalization.target.GroupForPersonalization;
import org.esupportail.portal.channels.CStockage.spacesPersonalization.target.OtherPrincipalForPersonalization;
import org.esupportail.portal.channels.CStockage.spacesPersonalization.target.UserForPersonalization;
import org.esupportail.portal.utils.webdav.acl.EsupPermission;
import org.esupportail.portal.utils.webdav.acl.EsupPermissions;


/**
 * Id: InjacAclManager.java,v 1.0 10 nov. 2004
 * Copyright (c) 2004 Esup Portail (www.esup-portail.org)
 * Classes: InjacAclManager
 * Original Author: Yohan Colmant
 * Use to manage the acl used in injac
 */
public class InjacAclManager {


	/**
	 * Logger object
	 */
	protected static final Log log = LogFactory.getLog(InjacAclManager.class);
	
	
	
	
	
	
	/**
	 * Set the acl for reading set by manager on a space
	 * @param currentSpace the current space used
	 * @param path the resource path
	 * @param smp object containing all properties
	 * @throws ServerException
	 * @throws ApplicationException
	 * @throws AclReadException
	 * @throws AclAccessException
	 * @throws AclWriteException
	 * @throws NotSupportedAclException
	 */
	public static void setReadersAclOnSpace(Space currentSpace, String path, InjacSpaceManagementProperties smp) throws ServerException, ApplicationException, AclReadException, AclAccessException, AclWriteException, NotSupportedAclException {		

		// the properties before modifications
		Vector usersBefore = smp.getReaderUsers();
		Vector groupsBefore = smp.getReaderGroups();	
		Vector othersBefore = smp.getReaderOthers();	
		
		// the properties after modifications
		Vector usersAfter = smp.getModifiedReaderUsers();
		Vector groupsAfter = smp.getModifiedReaderGroups();
		Vector othersAfter = smp.getModifiedReaderOthers();
		
		// public
		boolean isPublic = smp.isPublicReading();
		
		/**
		 * ADD
		 */
		
		
		// the users which has been added
		Enumeration iter = usersAfter.elements();
		Vector usersToAdd = new Vector();
		while(iter.hasMoreElements()) {
			UserForPersonalization userAfter = (UserForPersonalization)iter.nextElement();
			String key = (String)userAfter.getKey();

			// check if we found the good key in the groups before
			UserForPersonalization userBefore = null;
			for (int i=0; i<usersBefore.size() && userBefore==null; i++) {
				UserForPersonalization userTemp = (UserForPersonalization)usersBefore.get(i);
				if (userTemp.getKey().equals(key)) {
					userBefore = userTemp;
				}
			}
			
			if (userBefore == null) {
				if (userAfter.getPersonalization().getReading()==1 || userAfter.getPersonalization().getWriting()==1 || userAfter.getPersonalization().getSharing()==1) {
					usersToAdd.add(userAfter);
				}
			}
			else {
				if (userBefore.getPersonalization().isInheritedAcl()) {
					usersToAdd.add(userAfter);
				}
			}
		}
		
		// the groups which has been added
		iter = groupsAfter.elements();
		Vector groupsToAdd = new Vector();
		while(iter.hasMoreElements()) {
			GroupForPersonalization groupAfter = (GroupForPersonalization)iter.nextElement();
			String key = (String)groupAfter.getKey();			
			
			// check if we found the good key in the groups before
			GroupForPersonalization groupBefore = null;
			for (int i=0; i<groupsBefore.size() && groupBefore==null; i++) {
				GroupForPersonalization groupTemp = (GroupForPersonalization)groupsBefore.get(i);
				if (groupTemp.getKey().equals(key)) {
					groupBefore = groupTemp;
				}
			}
			
			if (groupBefore==null) {
				if (groupAfter.getPersonalization().getReading()==1 || groupAfter.getPersonalization().getWriting()==1 || groupAfter.getPersonalization().getSharing()==1) {
					groupsToAdd.add(groupAfter);
				}	
			}
			else {
				if (groupBefore.getPersonalization().isInheritedAcl()) {
					groupsToAdd.add(groupAfter);
				}
			}
		}
		
		// the others which has been added
		iter = othersAfter.elements();
		Vector othersToAdd = new Vector();
		while(iter.hasMoreElements()) {
			OtherPrincipalForPersonalization otherAfter = (OtherPrincipalForPersonalization)iter.nextElement();
			String key = (String)otherAfter.getKey();			
			
			// check if we found the good key in the others before
			OtherPrincipalForPersonalization otherBefore = null;
			for (int i=0; i<othersBefore.size() && otherBefore==null; i++) {
				OtherPrincipalForPersonalization otherTemp = (OtherPrincipalForPersonalization)othersBefore.get(i);
				if (otherTemp.getKey().equals(key)) {
					otherBefore = otherTemp;
				}
			}
			
			if (otherBefore==null) {
				if (otherAfter.getPersonalization().getReading()==1 || otherAfter.getPersonalization().getWriting()==1 || otherAfter.getPersonalization().getSharing()==1) {
					othersToAdd.add(otherAfter);
				}
			}	
			else {
				if (otherBefore.getPersonalization().isInheritedAcl()) {
					othersToAdd.add(otherAfter);
				}
			}
		}
		//log
		if (log.isDebugEnabled()) {
			log.debug("setReadersAclOnSpace"+" :: usersToAdd: "+usersToAdd);
			log.debug("setReadersAclOnSpace"+" :: groupsToAdd: "+groupsToAdd);
			log.debug("setReadersAclOnSpace"+" :: othersToAdd: "+othersToAdd);
			//System.out.println();
			//System.out.println("setReadersAclOnSpace"+" :: usersToAdd: "+usersToAdd);
			//System.out.println("setReadersAclOnSpace"+" :: groupsToAdd: "+groupsToAdd);
			//System.out.println("setReadersAclOnSpace"+" :: othersToAdd: "+othersToAdd);
		}
		addAclForReaders(currentSpace, path, usersToAdd, groupsToAdd, othersToAdd, isPublic);
		
		
		/**
		 * DELETE ... UPDATE
		 */
		
		// the users which has been deleted, or still here
		Vector usersToDelete = new Vector();
		Vector usersToUpdate = new Vector();
		
		iter = usersBefore.elements();
		while(iter.hasMoreElements()) {
			UserForPersonalization userBefore = (UserForPersonalization)iter.nextElement();
			String keyBefore = (String)userBefore.getKey();		
			
			UserForPersonalization userAfter = null;
			for (int i=0; i<usersAfter.size() && userAfter==null; i++) {
				UserForPersonalization userTemp = (UserForPersonalization)usersAfter.get(i);
				if (userTemp.getKey().equals(keyBefore)) {
					userAfter = userTemp;
				}
			}
			
			// deleted
			if (userAfter==null) {
				usersToDelete.add(userBefore);
			}
			
			// still here
			else {
				
				// check if the reading and writing attributes are equals
				if (userBefore.getPersonalization().getReading()==userAfter.getPersonalization().getReading() && userBefore.getPersonalization().getWriting()==userAfter.getPersonalization().getWriting() && userBefore.getPersonalization().getSharing()==userAfter.getPersonalization().getSharing()) {			
				}
				// not equals, we have to update
				else {

					// if not read and not write, we delete
					if (userAfter.getPersonalization().getReading()!=1 && userAfter.getPersonalization().getWriting()!=1 && userAfter.getPersonalization().getSharing()!=1) {
						usersToDelete.add(userBefore);
					}
					// we update
					else {
						usersToUpdate.add(userAfter);
					}
				}
			}		
		}
		
		//log
		if (log.isDebugEnabled()) {
			log.debug("setReadersAclOnSpace"+" :: usersToDelete: "+usersToDelete);
			//System.out.println("setReadersAclOnSpace"+" :: usersToDelete: "+usersToDelete);
		}
		delAclForUsers(currentSpace, path, usersToDelete);
		
		//log
		if (log.isDebugEnabled()) {
			log.debug("setReadersAclOnSpace"+" :: usersToUpdate: "+usersToUpdate);
			//System.out.println("setReadersAclOnSpace"+" :: usersToUpdate: "+usersToUpdate);
		}
		//updateAclForUsers(currentSpace, path, usersToUpdate);
		
		
		// the groups which has been deleted, or still here
		Vector groupsToDelete = new Vector();
		Vector groupsToUpdate = new Vector();
		
		iter = groupsBefore.elements();
		while(iter.hasMoreElements()) {
			GroupForPersonalization groupBefore = (GroupForPersonalization)iter.nextElement();
			String keyBefore = (String)groupBefore.getKey();				
			
			GroupForPersonalization groupAfter = null;
			for (int i=0; i<groupsAfter.size() && groupAfter==null; i++) {
				GroupForPersonalization groupTemp = (GroupForPersonalization)groupsAfter.get(i);
				if (groupTemp.getKey().equals(keyBefore)) {
					groupAfter = groupTemp;
				}
			}
			
			// deleted
			if (groupAfter==null) {
				groupsToDelete.add(groupBefore);
			}
			
			// still here
			else {				
				
				// check if the reading and writing attributes are equals
				if (groupBefore.getPersonalization().getReading()==groupAfter.getPersonalization().getReading() && groupBefore.getPersonalization().getWriting()==groupAfter.getPersonalization().getWriting() && groupBefore.getPersonalization().getSharing()==groupAfter.getPersonalization().getSharing()) {
					
				}
				// not equals, we have to update
				else {
					
					// if not read and not write, we delete
					if (groupAfter.getPersonalization().getReading()!=1 && groupAfter.getPersonalization().getWriting()!=1 && groupAfter.getPersonalization().getSharing()!=1) {
						groupsToDelete.add(groupBefore);
					}
					// we update
					else {
						groupsToUpdate.add(groupAfter);
					}
				}

			}			
		}
		
		//log
		if (log.isDebugEnabled()) {
			log.debug("setReadersAclOnSpace"+" :: groupsToDelete: "+groupsToDelete);
			//System.out.println("setReadersAclOnSpace"+" :: groupsToDelete: "+groupsToDelete);
		}
		delAclForGroups(currentSpace, path, groupsToDelete);
		
		//log
		if (log.isDebugEnabled()) {
			log.debug("setReadersAclOnSpace"+" :: groupsToUpdate: "+groupsToUpdate);
			//System.out.println("setReadersAclOnSpace"+" :: groupsToUpdate: "+groupsToUpdate);
		}
		//updateAclForGroups(currentSpace, path, groupsToUpdate);
		
		

		// the others which has been deleted, or still here
		Vector othersToDelete = new Vector();
		Vector othersToUpdate = new Vector();
		
		iter = othersBefore.elements();
		while(iter.hasMoreElements()) {
			OtherPrincipalForPersonalization otherBefore = (OtherPrincipalForPersonalization)iter.nextElement();
			String keyBefore = (String)otherBefore.getKey();				
			OtherPrincipalForPersonalization otherAfter = null;
			for (int i=0; i<othersAfter.size() && otherAfter==null; i++) {
				OtherPrincipalForPersonalization otherTemp = (OtherPrincipalForPersonalization)othersAfter.get(i);
				if (otherTemp.getKey().equals(keyBefore)) {
					otherAfter = otherTemp;
				}
			}
			
			// deleted
			if (otherAfter==null) {
				othersToDelete.add(otherBefore);
			}
			
			// still here
			else {				
				
				// check if the reading and writing attributes are equals
				if (otherBefore.getPersonalization().getReading()==otherAfter.getPersonalization().getReading() && otherBefore.getPersonalization().getWriting()==otherAfter.getPersonalization().getWriting() && otherBefore.getPersonalization().getSharing()==otherAfter.getPersonalization().getSharing()) {

				}
				// not equals, we have to update
				else {
					
					// if not read and not write, we delete
					if (otherAfter.getPersonalization().getReading()!=1 && otherAfter.getPersonalization().getWriting()!=1 && otherAfter.getPersonalization().getSharing()!=1) {
						othersToDelete.add(otherBefore);
					}
					// we update
					else {
						othersToUpdate.add(otherAfter);
					}
				}
			}			
		}
		
		//log
		if (log.isDebugEnabled()) {
			log.debug("setReadersAclOnSpace"+" :: othersToDelete: "+othersToDelete);
			//System.out.println("setReadersAclOnSpace"+" :: othersToDelete: "+othersToDelete);
		}
		delAclForOthers(currentSpace, path, othersToDelete);
		
		//log
		if (log.isDebugEnabled()) {
			log.debug("setReadersAclOnSpace"+" :: othersToUpdate: "+othersToUpdate);
			//System.out.println("setReadersAclOnSpace"+" :: othersToUpdate: "+othersToUpdate);
		}
		//updateAclForOthers(currentSpace, path, othersToUpdate);
		
		
		
		
	}
	
	
	
	/**
	 * Add sharing properties for the users and groups into the database
	 * @param currentSpace the current space we are using
	 * @param sharedSpace the space we are sharing
	 * @param serverUrl the url of the server
	 * @param fromKey the key of the people who shares
	 * @param path the resource path
	 * @param users the target users
	 * @param groups the target groups
	 * @throws DataBaseException
	 * @throws AclAccessException
	 * @throws AclWriteException
	 * @throws AclReadException
	 * @throws NotSupportedAclException
	 * @throws PropertiesException
	 */
	private static void addAclForReaders(Space currentSpace, String path, Vector users, Vector groups, Vector others, boolean isPublic) throws AclAccessException, AclWriteException, AclReadException, NotSupportedAclException {
	
		ServerAccess access = currentSpace.getServerAccessObject();
		
		// the users
		for (int i=0; i<users.size(); i++) {
			
			UserForPersonalization user = (UserForPersonalization)users.elementAt(i);
			
			/////////////////////
			// set the ACL rights
			String principal = currentSpace.getServer().getAclUserPrefix()+user.getKey();
			if (user.getPersonalization().getSharing()==1 && user.getPersonalization().getReading()==1 && user.getPersonalization().getWriting()==1) {
				access.grant(path, principal, EsupPermission.ALL, true);
			}
			else {
				if (user.getPersonalization().getSharing()==1) {
					access.grant(path, principal, EsupPermission.WRITE_ACL, true);
				}
				if (user.getPersonalization().getReading()==1) {
					access.grant(path, principal, EsupPermission.READ, true);
				}
				if (user.getPersonalization().getWriting()==1) {
					access.grant(path, principal, EsupPermission.WRITE, true);
					access.deny(path, principal, EsupPermission.WRITE_ACL, true);
				}
			}
		}
		

		// the groups
		for (int i=0; i<groups.size(); i++) {
			
			GroupForPersonalization group = (GroupForPersonalization)groups.elementAt(i);
			
			/////////////////////
			// set the ACL rights
			Vector groupHierarchyKey = group.getGroupHierarchy();
			if (groupHierarchyKey!=null) {
				String principal = currentSpace.getServer().getAclGroupPrefix();
				for (int j=0; j<groupHierarchyKey.size(); j++) {
					principal = principal + groupHierarchyKey.elementAt(j);
					if (j!=groupHierarchyKey.size()-1)
						principal = principal + "/";
				}
				if (group.getPersonalization().getSharing()==1 && group.getPersonalization().getReading()==1 && group.getPersonalization().getWriting()==1) {
					access.grant(path, principal, EsupPermission.ALL, true);
				}
				else {
					if (group.getPersonalization().getSharing()==1) {
						access.grant(path, principal, EsupPermission.WRITE_ACL, true);
					}
					if (group.getPersonalization().getReading()==1) {
						access.grant(path, principal, EsupPermission.READ, true);
					}
					if (group.getPersonalization().getWriting()==1) {
						access.grant(path, principal, EsupPermission.WRITE, true);
						access.deny(path, principal, EsupPermission.WRITE_ACL, true);
					}
				}
			}
		}
		
		

		// the others
		for (int i=0; i<others.size(); i++) {
			
			OtherPrincipalForPersonalization other = (OtherPrincipalForPersonalization)others.elementAt(i);
			
			/////////////////////
			// set the ACL rights
			String principal = other.getKey();
			if (other.getPersonalization().getSharing()==1 && other.getPersonalization().getReading()==1 && other.getPersonalization().getWriting()==1) {
				access.grant(path, principal, EsupPermission.ALL, true);
			}
			else {
				if (other.getPersonalization().getSharing()==1) {
					access.grant(path, principal, EsupPermission.WRITE_ACL, true);
				}
				if (other.getPersonalization().getReading()==1) {
					access.grant(path, principal, EsupPermission.READ, true);
				}
				if (other.getPersonalization().getWriting()==1) {
					access.grant(path, principal, EsupPermission.WRITE, true);
					access.deny(path, principal, EsupPermission.WRITE_ACL, true);
				}
			}
		}
		
		// set the public value
		if (isPublic)
			access.grant(path, EsupPermission.PRINCIPAL_ALL, EsupPermission.READ, true);
		else access.revoke(path, EsupPermission.PRINCIPAL_ALL, EsupPermission.READ, true); 
		
		// set the deny all all
		access.deny(path, EsupPermission.PRINCIPAL_ALL, EsupPermission.ALL, true);
		
		
	}
	
	
	
	
	/**
	 * Delete sharing properties for users into the database
	 * @param currentSpace the current space
	 * @param users we want to delete preferences
	 * @param serverId the id of the server
	 * @throws DataBaseException
	 * @throws AclAccessException
	 * @throws AclWriteException
	 * @throws AclReadException
	 * @throws NotSupportedAclException
	 * @throws PropertiesException
	 */
	private static void delAclForUsers(Space currentSpace, String path, Vector users) throws AclAccessException, AclWriteException, AclReadException, NotSupportedAclException {
		
		// for each user
		for(int i=0; i<users.size(); i++) {
		
			UserForPersonalization user = (UserForPersonalization)users.elementAt(i);
		
			// remove the ACL
			String principal = currentSpace.getServer().getAclUserPrefix()+user.getKey();
			currentSpace.getServerAccessObject().revoke(path, principal, EsupPermission.READ, true);
			currentSpace.getServerAccessObject().revoke(path, principal, EsupPermission.WRITE, true);
			currentSpace.getServerAccessObject().revoke(path, principal, EsupPermission.WRITE_ACL, true);
			currentSpace.getServerAccessObject().revoke(path, principal, EsupPermission.ALL, true);
		}
	}
	
	
	
	


	/**
	 * Delete sharing properties for groups into the database
	 * @param currentSpace the current space
	 * @param groups the groups we want to delete sharing
	 * @param serverId the id of the server
	 * @throws DataBaseException
	 * @throws AclAccessException
	 * @throws AclWriteException
	 * @throws AclReadException
	 * @throws NotSupportedAclException
	 * @throws PropertiesException
	 */
	private static void delAclForGroups(Space currentSpace, String path, Vector groups) throws  AclAccessException, AclWriteException, AclReadException, NotSupportedAclException {

		// for each group
		for(int i=0; i<groups.size(); i++) {
		
			GroupForPersonalization group = (GroupForPersonalization)groups.elementAt(i);
			
			// remove the ACL
			Vector groupHierarchyKey = group.getGroupHierarchy();
			if (groupHierarchyKey!=null) {
				String principal = currentSpace.getServer().getAclGroupPrefix();
				for (int j=0; j<groupHierarchyKey.size(); j++) {
					principal = principal + groupHierarchyKey.elementAt(j);
					if (j!=groupHierarchyKey.size()-1)
						principal = principal + "/";
				}
				
				currentSpace.getServerAccessObject().revoke(path, principal, EsupPermission.READ, true);
				currentSpace.getServerAccessObject().revoke(path, principal, EsupPermission.WRITE, true);
				currentSpace.getServerAccessObject().revoke(path, principal, EsupPermission.WRITE_ACL, true);
				currentSpace.getServerAccessObject().revoke(path, principal, EsupPermission.ALL, true);
			}
		}
	}
	
	
	
	/**
	 * Delete sharing properties for others into the acl
	 * @param currentSpace the current space
	 * @param others the others we want to delete sharing
	 * @param serverId the id of the server
	 * @throws DataBaseException
	 * @throws AclAccessException
	 * @throws AclWriteException
	 * @throws AclReadException
	 * @throws NotSupportedAclException
	 * @throws PropertiesException
	 */
	private static void delAclForOthers(Space currentSpace, String path, Vector others) throws AclAccessException, AclWriteException, AclReadException, NotSupportedAclException {

		// for each other
		for(int i=0; i<others.size(); i++) {
		
			OtherPrincipalForPersonalization other = (OtherPrincipalForPersonalization)others.elementAt(i);
			
			// remove the ACL
			String principal = other.getKey();
			currentSpace.getServerAccessObject().revoke(path, principal, EsupPermission.READ, true);
			currentSpace.getServerAccessObject().revoke(path, principal, EsupPermission.WRITE, true);
			currentSpace.getServerAccessObject().revoke(path, principal, EsupPermission.WRITE_ACL, true);
			currentSpace.getServerAccessObject().revoke(path, principal, EsupPermission.ALL, true);
		}

		
	}
	

	
	
	

	/**
	 * Return the ACL for reading on a space
	 * @param access the server access object
	 * @param path the resource path
	 * @param permissions the permissions list
	 * @param users the users
	 * @param groups the groups
	 * @param userPrefix the acl user prefix
	 * @param groupPrefix the acl group prefix
	 * @return true if public, false if not public
	 * @throws AclAccessException
	 * @throws AclReadException
	 * @throws NotSupportedAclException
	 */
	public static boolean getReadersAclOnSpace(Space currentSpace, Vector users, Vector groups, Vector others) throws AclAccessException, AclReadException, NotSupportedAclException, PropertiesException  {		
		
		ServerAccess access = currentSpace.getServerAccessObject();
		String path = currentSpace.getCurrentPath();
		
		String userPrefix = currentSpace.getServer().getAclUserPrefix();
		String groupPrefix = currentSpace.getServer().getAclGroupPrefix();
		
		// check if public
		int publicAccess = -1;
		
		// if we found the security user
		boolean foundNotInheritedSecurityUser = false;
		
		// if we found the security other
		boolean foundNotInheritedSecurityOther = false;
		
		// log
		if (log.isDebugEnabled()){
			log.debug("getReadersAclOnSpace"+" :: "+path+" begin of acl getting");
		}
		
		// get the permissions
		EsupPermissions permissions = access.getPermissions(path);
		
		// for each permission
		Iterator iter = permissions.iterator();
		while (iter.hasNext()) {
			
			// the permission
			EsupPermission perm = (EsupPermission)iter.next();
			
			// if not inherited
			if (!perm.isInherited()) {

				/**
				 * GRANT/DENY ALL NOT INHERITED
				 */
				
				// check if read public
				if (perm.isPrincipalAll()) {
					if (perm.getPermissionType().equals(EsupPermission.READ)) {
						if (perm.isGrantPermission()) {
							publicAccess = 1;
						}
						else {
							publicAccess = 0;
						}
					}
				}
				
				// if grant
				else if (perm.isGrantPermission()) {
				
					/**
					 * GRANT USER NOT INHERITED
					 */
					
					// if user
					if (perm.isPrincipalUser()) {
						String principal = perm.getPrincipal();
						String key = principal.substring(userPrefix.length());
						
						UserForPersonalization user = null;
						
						// if the permission is reading
						if (perm.getPermissionType().equals(EsupPermission.READ)) {
							
							// check if we still have this one
							for (int i=0; i<users.size() && user==null; i++) {
								UserForPersonalization u = (UserForPersonalization)users.elementAt(i);
								
								// if the key is the same
								if (key.equals(u.getKey())) {
								
									// if the both are not inherited
									if (!u.getPersonalization().isInheritedAcl()) {
										user = u;
									}
								}
							}
							
							// if we don't still have it
							if (user==null) {
								user = new UserForPersonalization(key);
								users.addElement(user);
								user.getPersonalization().setModifiable(true);
								user.getPersonalization().setInheritedAcl(false);
								user.getPersonalization().setSecurityRight(false);
								user.getPersonalization().setReading(1);
							}
						}
						
						// not read, but all and injac security user
						else if (perm.getPermissionType().equals(EsupPermission.ALL) && key.equals(currentSpace.getServer().getLogin())) {
							
							// check if we still have this one
							for (int i=0; i<users.size() && user==null; i++) {
								UserForPersonalization u = (UserForPersonalization)users.elementAt(i);
								
								// if the key is the same
								if (key.equals(u.getKey())) {
								
									// if the both are not inherited
									if (!u.getPersonalization().isInheritedAcl()) {
										user = u;
									}
								}
							}
							
							// if we don't still have it
							if (user==null) {
								user = new UserForPersonalization(key);
								users.addElement(user);
								user.getPersonalization().setReading(1);
								user.getPersonalization().setWriting(1);
								user.getPersonalization().setSharing(1);
								user.getPersonalization().setModifiable(false);
								user.getPersonalization().setInheritedAcl(false);
								user.getPersonalization().setSecurityRight(true);
								foundNotInheritedSecurityUser = true;
							}	
						}
					}

					/**
					 * GRANT GROUP NOT INHERITED
					 */
					
					// if group
					else if (perm.isPrincipalGroup() && perm.getPrincipal().startsWith(groupPrefix)) {
						String principal = perm.getPrincipal();
						String hierarchy = principal.substring((groupPrefix).length());
						
						StringTokenizer strToken = new StringTokenizer(hierarchy, "/");
						String key = "";
						while (strToken.hasMoreTokens()) {
							key = strToken.nextToken();
						}
						
						GroupForPersonalization group = null;

						// if the permission is reading
						if (perm.getPermissionType().equals(EsupPermission.READ)) {
							
							// check if we still have this one
							for (int i=0; i<groups.size() && group==null; i++) {
								GroupForPersonalization g = (GroupForPersonalization)groups.elementAt(i);
								
								// if the key is the same
								if (key.equals(g.getKey())) {
								
									// if the both are not inherited
									if (!g.getPersonalization().isInheritedAcl()) {
										group = g;
									}
								}
							}
							
							// if we don't still have it
							try {
								if (group==null) {
									group = new GroupForPersonalization(hierarchy, true, null);
									groups.addElement(group);
									group.getPersonalization().setModifiable(true);
									group.getPersonalization().setInheritedAcl(false);
									group.getPersonalization().setSecurityRight(false);
									group.getPersonalization().setReading(1);
								}
							}
							catch(ServerException e) {

								// log
								if (log.isDebugEnabled()){
									log.debug("getReadersAclOnSpace"+" :: "+e);
								}
							}
						}
					}

					/**
					 * GRANT OTHER NOT INHERITED
					 */
					
					// the administration server security group
					else {
						
						String principal = Space.getPathWithoutFirstAndLastSlash(perm.getPrincipal());
						String security = Space.getPathWithoutFirstAndLastSlash(currentSpace.getServer().getAclSecurity());
						
						if (principal.equals(security)) {
							OtherPrincipalForPersonalization other = new OtherPrincipalForPersonalization(perm.getPrincipal());
							other.getPersonalization().setInheritedAcl(false);
							other.getPersonalization().setModifiable(false);
							other.getPersonalization().setSecurityRight(true);
							other.getPersonalization().setReading(1);
							other.getPersonalization().setWriting(1);
							other.getPersonalization().setSharing(1);
							others.addElement(other);
							foundNotInheritedSecurityOther = true;
						}
					}
				}
			}
		}
	
		// if there is not security acl user
		if (!foundNotInheritedSecurityUser) {
			UserForPersonalization user = new UserForPersonalization(currentSpace.getServer().getLogin());
			users.addElement(user);
			user.getPersonalization().setReading(1);
			user.getPersonalization().setWriting(1);
			user.getPersonalization().setSharing(1);
			user.getPersonalization().setModifiable(false);
			user.getPersonalization().setInheritedAcl(true);
			user.getPersonalization().setSecurityRight(true);
		}
		
		// if there is not security acl other
		if (!foundNotInheritedSecurityOther) {
			OtherPrincipalForPersonalization other = new OtherPrincipalForPersonalization(currentSpace.getServer().getAclSecurity());
			other.getPersonalization().setInheritedAcl(true);
			other.getPersonalization().setModifiable(false);
			other.getPersonalization().setSecurityRight(true);
			other.getPersonalization().setReading(1);
			other.getPersonalization().setWriting(1);
			other.getPersonalization().setSharing(1);
			others.addElement(other);
		}

		// log
		if (log.isDebugEnabled()){
			log.debug("getReadersAclOnSpace"+" :: "+path+" end of acl getting");
		}
		
		// return the result
		if (publicAccess==1) {
			return true;
		}
		else {
			return false;
		}
	}
	
	
	public static boolean getReadersAclOnSpace_old(Space currentSpace, Vector users, Vector groups, Vector others) throws AclAccessException, AclReadException, NotSupportedAclException, PropertiesException  {		
		
		ServerAccess access = currentSpace.getServerAccessObject();
		String path = currentSpace.getCurrentPath();
		
		String userPrefix = currentSpace.getServer().getAclUserPrefix();
		String groupPrefix = currentSpace.getServer().getAclGroupPrefix();
		
		// check if public
		int publicAccess = -1;
		int parentIsPublicAccess = -1;
		
		// if we found the security user
		boolean foundNotInheritedSecurityUser = false;
		boolean foundInheritedSecurityUser = false;
		
		// if we found the security other
		boolean foundNotInheritedSecurityOther = false;
		boolean foundInheritedSecurityOther = false;
		
		// if we use inherited acl or local acl
		boolean useInheritedAcl = true;
		
		// log
		if (log.isDebugEnabled()){
			log.debug("getReadersAclOnSpace"+" :: "+path+" begin of acl getting");
		}
		
		// the parent path
		String parentPath = currentSpace.getParentPathUntilSpaceRoot();
		if (parentPath!=null)
			parentPath = Space.getPathWithoutFirstAndLastSlash(parentPath);
		
		// get the permissions
		EsupPermissions permissions = access.getPermissions(path);
		
		// for each permission
		Iterator iter = permissions.iterator();
		while (iter.hasNext()) {
			
			// the permission
			EsupPermission perm = (EsupPermission)iter.next();
			
			// if not inherited
			if (!perm.isInherited()) {

				/**
				 * GRANT/DENY ALL NOT INHERITED
				 */
				
				// check if read public
				if (perm.isPrincipalAll()) {
					if (perm.getPermissionType().equals(EsupPermission.READ)) {
						useInheritedAcl = false;
						if (perm.isGrantPermission()) {
							publicAccess = 1;
						}
						else {
							publicAccess = 0;
						}
					}
				}
				
				// if grant
				else if (perm.isGrantPermission()) {
				
					/**
					 * GRANT USER NOT INHERITED
					 */
					
					// if user
					if (perm.isPrincipalUser()) {
						String principal = perm.getPrincipal();
						String key = principal.substring(userPrefix.length());
						
						UserForPersonalization user = null;
						
						// if the permission is reading
						if (perm.getPermissionType().equals(EsupPermission.READ)) {
							
							// check if we still have this one
							for (int i=0; i<users.size() && user==null; i++) {
								UserForPersonalization u = (UserForPersonalization)users.elementAt(i);
								
								// if the key is the same
								if (key.equals(u.getKey())) {
								
									// if the both are not inherited
									if (!u.getPersonalization().isInheritedAcl()) {
										user = u;
									}
								}
							}
							
							// if we don't still have it
							if (user==null) {
								user = new UserForPersonalization(key);
								users.addElement(user);
								user.getPersonalization().setModifiable(true);
								user.getPersonalization().setInheritedAcl(false);
								user.getPersonalization().setSecurityRight(false);
								user.getPersonalization().setReading(1);
								useInheritedAcl = false;
							}
						}
						
						// not read, but all and injac security user
						else if (perm.getPermissionType().equals(EsupPermission.ALL) && key.equals(currentSpace.getServer().getLogin())) {
							
							// check if we still have this one
							for (int i=0; i<users.size() && user==null; i++) {
								UserForPersonalization u = (UserForPersonalization)users.elementAt(i);
								
								// if the key is the same
								if (key.equals(u.getKey())) {
								
									// if the both are not inherited
									if (!u.getPersonalization().isInheritedAcl()) {
										user = u;
									}
								}
							}
							
							// if we don't still have it
							if (user==null) {
								user = new UserForPersonalization(key);
								users.addElement(user);
								user.getPersonalization().setReading(1);
								user.getPersonalization().setWriting(1);
								user.getPersonalization().setSharing(1);
								user.getPersonalization().setModifiable(false);
								user.getPersonalization().setInheritedAcl(false);
								user.getPersonalization().setSecurityRight(true);
								foundNotInheritedSecurityUser = true;
								useInheritedAcl = false;
							}	
						}
					}

					/**
					 * GRANT GROUP NOT INHERITED
					 */
					
					// if group
					else if (perm.isPrincipalGroup() && perm.getPrincipal().startsWith(groupPrefix)) {
						String principal = perm.getPrincipal();
						String hierarchy = principal.substring((groupPrefix).length());
						
						StringTokenizer strToken = new StringTokenizer(hierarchy, "/");
						String key = "";
						while (strToken.hasMoreTokens()) {
							key = strToken.nextToken();
						}
						
						GroupForPersonalization group = null;

						// if the permission is reading
						if (perm.getPermissionType().equals(EsupPermission.READ)) {
							
							// check if we still have this one
							for (int i=0; i<groups.size() && group==null; i++) {
								GroupForPersonalization g = (GroupForPersonalization)groups.elementAt(i);
								
								// if the key is the same
								if (key.equals(g.getKey())) {
								
									// if the both are not inherited
									if (!g.getPersonalization().isInheritedAcl()) {
										group = g;
									}
								}
							}
							
							// if we don't still have it
							try {
								if (group==null) {
									group = new GroupForPersonalization(hierarchy, true, null);
									groups.addElement(group);
									group.getPersonalization().setModifiable(true);
									group.getPersonalization().setInheritedAcl(false);
									group.getPersonalization().setSecurityRight(false);
									group.getPersonalization().setReading(1);
									useInheritedAcl = false;
								}
							}
							catch(ServerException e) {

								// log
								if (log.isDebugEnabled()){
									log.debug("getReadersAclOnSpace"+" :: "+e);
								}
							}
						}
					}

					/**
					 * GRANT OTHER NOT INHERITED
					 */
					
					// the administration server security group
					else {
						
						String principal = Space.getPathWithoutFirstAndLastSlash(perm.getPrincipal());
						String security = Space.getPathWithoutFirstAndLastSlash(currentSpace.getServer().getAclSecurity());
						
						if (principal.equals(security)) {
							OtherPrincipalForPersonalization other = new OtherPrincipalForPersonalization(perm.getPrincipal());
							other.getPersonalization().setInheritedAcl(false);
							other.getPersonalization().setModifiable(false);
							other.getPersonalization().setSecurityRight(true);
							other.getPersonalization().setReading(1);
							other.getPersonalization().setWriting(1);
							other.getPersonalization().setSharing(1);
							others.addElement(other);
							foundNotInheritedSecurityOther = true;
							useInheritedAcl = false;
						}
					}
				}
			}
				
			
			// inherited
			else {
				
				String inheritedFrom = perm.getInheritedFrom();
				inheritedFrom = Space.getPathWithoutFirstAndLastSlash(inheritedFrom);
				
				// inherited from parent
				if (parentPath!=null && inheritedFrom.equals(parentPath)) {

					/**
					 * GRANT/DENY ALL NOT INHERITED
					 */
					
					// check if read public
					if (perm.isPrincipalAll()) {
						if (perm.getPermissionType().equals(EsupPermission.READ)) {
							if (perm.isGrantPermission()) {
								parentIsPublicAccess = 1;
							}
							else {
								parentIsPublicAccess = 0;
							}
						}
					}
					
					// if grant
					else if (perm.isGrantPermission()) {
					
						/**
						 * GRANT USER NOT INHERITED
						 */
						
						// if user
						if (perm.isPrincipalUser()) {
							String principal = perm.getPrincipal();
							String key = principal.substring(userPrefix.length());
							
							UserForPersonalization user = null;
							
							// if the permission is reading
							if (perm.getPermissionType().equals(EsupPermission.READ)) {
								
								// check if we still have this one
								for (int i=0; i<users.size() && user==null; i++) {
									UserForPersonalization u = (UserForPersonalization)users.elementAt(i);
									
									// if the key is the same
									if (key.equals(u.getKey())) {
									
										// if the both are not inherited
										if (u.getPersonalization().isInheritedAcl()) {
											user = u;
										}
									}
								}
								
								// if we don't still have it
								if (user==null) {
									user = new UserForPersonalization(key);
									users.addElement(user);
									user.getPersonalization().setModifiable(true);
									user.getPersonalization().setInheritedAcl(true);
									user.getPersonalization().setSecurityRight(false);
									user.getPersonalization().setReading(1);
								}
							}
							
							// not read, but all and injac security user
							else if (perm.getPermissionType().equals(EsupPermission.ALL) && key.equals(currentSpace.getServer().getLogin())) {
								
								// check if we still have this one
								for (int i=0; i<users.size() && user==null; i++) {
									UserForPersonalization u = (UserForPersonalization)users.elementAt(i);
									
									// if the key is the same
									if (key.equals(u.getKey())) {
									
										// if the both are not inherited
										if (u.getPersonalization().isInheritedAcl()) {
											user = u;
										}
									}
								}
								
								// if we don't still have it
								if (user==null) {
									user = new UserForPersonalization(key);
									users.addElement(user);
									user.getPersonalization().setReading(1);
									user.getPersonalization().setWriting(1);
									user.getPersonalization().setSharing(1);
									user.getPersonalization().setModifiable(false);
									user.getPersonalization().setInheritedAcl(true);
									user.getPersonalization().setSecurityRight(true);
									foundInheritedSecurityUser = true;
								}	
							}
						}

						/**
						 * GRANT GROUP NOT INHERITED
						 */
						
						// if group
						else if (perm.isPrincipalGroup() && perm.getPrincipal().startsWith(groupPrefix)) {
							String principal = perm.getPrincipal();
							String hierarchy = principal.substring((groupPrefix).length());
							
							StringTokenizer strToken = new StringTokenizer(hierarchy, "/");
							String key = "";
							while (strToken.hasMoreTokens()) {
								key = strToken.nextToken();
							}
							
							GroupForPersonalization group = null;

							// if the permission is reading
							if (perm.getPermissionType().equals(EsupPermission.READ)) {
								
								// check if we still have this one
								for (int i=0; i<groups.size() && group==null; i++) {
									GroupForPersonalization g = (GroupForPersonalization)groups.elementAt(i);
									
									// if the key is the same
									if (key.equals(g.getKey())) {
									
										// if the both are not inherited
										if (g.getPersonalization().isInheritedAcl()) {
											group = g;
										}
									}
								}
								
								// if we don't still have it
								try {
									if (group==null) {
										group = new GroupForPersonalization(hierarchy, true, null);
										groups.addElement(group);
										group.getPersonalization().setModifiable(true);
										group.getPersonalization().setInheritedAcl(true);
										group.getPersonalization().setSecurityRight(false);
										group.getPersonalization().setReading(1);
									}
								}
								catch(ServerException e) {

									// log
									if (log.isDebugEnabled()){
										log.debug("getReadersAclOnSpace"+" :: "+e);
									}
								}
							}
						}

						/**
						 * GRANT OTHER NOT INHERITED
						 */
						
						// the administration server security group
						else {
							
							String principal = Space.getPathWithoutFirstAndLastSlash(perm.getPrincipal());
							String security = Space.getPathWithoutFirstAndLastSlash(currentSpace.getServer().getAclSecurity());
							
							if (principal.equals(security)) {
								OtherPrincipalForPersonalization other = new OtherPrincipalForPersonalization(perm.getPrincipal());
								other.getPersonalization().setInheritedAcl(true);
								other.getPersonalization().setModifiable(false);
								other.getPersonalization().setSecurityRight(true);
								other.getPersonalization().setReading(1);
								other.getPersonalization().setWriting(1);
								other.getPersonalization().setSharing(1);
								others.addElement(other);
								foundInheritedSecurityOther = true;
							}
						}
					}
					
				}
				
			}
		}
	

		// if we don't use the inherited permissions 
		if (!useInheritedAcl) {
			
			// we delete each inherited permission for users
			for (int i=0; i<users.size(); i++) {
				UserForPersonalization user = (UserForPersonalization)users.elementAt(i);
				if (user.getPersonalization().isInheritedAcl()) {
					users.remove(i);
					i--;
				}
			}
			
			// we delete each inherited permission for groups
			for (int i=0; i<groups.size(); i++) {
				GroupForPersonalization group = (GroupForPersonalization)groups.elementAt(i);
				if (group.getPersonalization().isInheritedAcl()) {
					groups.remove(i);
					i--;
				}
			}

			// we delete each inherited permission for others
			for (int i=0; i<others.size(); i++) {
				OtherPrincipalForPersonalization other = (OtherPrincipalForPersonalization)others.elementAt(i);
				if (other.getPersonalization().isInheritedAcl()) {
					others.remove(i);
					i--;
				}
			}
		}
		else {
			publicAccess = parentIsPublicAccess;
		}

		// if there is not security acl user
		if (!foundNotInheritedSecurityUser && !foundInheritedSecurityUser) {
			UserForPersonalization user = new UserForPersonalization(currentSpace.getServer().getLogin());
			users.addElement(user);
			user.getPersonalization().setReading(1);
			user.getPersonalization().setWriting(1);
			user.getPersonalization().setSharing(1);
			user.getPersonalization().setModifiable(false);
			user.getPersonalization().setInheritedAcl(true);
			user.getPersonalization().setSecurityRight(true);
		}
		
		// if there is not security acl other
		if (!foundNotInheritedSecurityOther && !foundInheritedSecurityOther) {
			OtherPrincipalForPersonalization other = new OtherPrincipalForPersonalization(currentSpace.getServer().getAclSecurity());
			other.getPersonalization().setInheritedAcl(true);
			other.getPersonalization().setModifiable(false);
			other.getPersonalization().setSecurityRight(true);
			other.getPersonalization().setReading(1);
			other.getPersonalization().setWriting(1);
			other.getPersonalization().setSharing(1);
			others.addElement(other);
		}

		// log
		if (log.isDebugEnabled()){
			log.debug("getReadersAclOnSpace"+" :: "+path+" end of acl getting");
		}
		
		// return the result
		if (publicAccess==1) {
			return true;
		}
		else {
			return false;
		}
		
		
		
		
		
		
		
		
		/*
		// if local grant for all
		if (access.hasNotInheritedPermission(path, EsupPermission.PRINCIPAL_ALL, EsupPermission.READ, EsupPermission.GRANT, true)) {
			publicAccess = 1;
		}
		
		// if local deny for all
		else if (access.hasNotInheritedPermission(path, EsupPermission.PRINCIPAL_ALL, EsupPermission.READ, EsupPermission.DENY, true)) {
			publicAccess = 0;
		}
		
		// if no local permissions for all
		else {
			Vector grantPermissions = access.hasInheritedPermission(path, EsupPermission.PRINCIPAL_ALL, EsupPermission.READ, EsupPermission.GRANT, true);
			Vector denyPermissions = access.hasInheritedPermission(path, EsupPermission.PRINCIPAL_ALL, EsupPermission.READ, EsupPermission.DENY, true);
			
			// if we have inherited grant permission(s)
			if (grantPermissions != null) {
				
				// if we have not inherited deny permission(s)
				if (denyPermissions == null) {					
					publicAccess = 1;
					EsupPermission permGrant = (EsupPermission)grantPermissions.elementAt(0);
					inheritedFromPublicAccess = permGrant.getInheritedFrom();
				}

				// if we have inherited deny permission(s)
				else {
					EsupPermission permGrant = (EsupPermission)grantPermissions.elementAt(0);
					EsupPermission permDeny = (EsupPermission)denyPermissions.elementAt(0);
					if (permGrant.getInheritedFrom().compareTo(permDeny.getInheritedFrom()) > 1) {
						publicAccess = 1;
						inheritedFromPublicAccess = permGrant.getInheritedFrom();
					}
					else {
						inheritedFromPublicAccess = permDeny.getInheritedFrom();
					}
				}
			}

			// if we have not inherited grant permission(s)
			else {

				// if we have not inherited deny permission(s)
				if (denyPermissions == null) {					
					publicAccess = 0;					
					inheritedFromPublicAccess = null;
				}

				// if we have inherited deny permission(s)
				else {					
					EsupPermission permDeny = (EsupPermission)denyPermissions.elementAt(0);
					inheritedFromPublicAccess = permDeny.getInheritedFrom();
					publicAccess = 0;
				}
			}
		}		

		//System.out.println("public: "+publicAccess);
		//System.out.println("localPublicAccess: "+localPublicAccess);
		//System.out.println("inheritedFromPublicAccess: "+inheritedFromPublicAccess);
		
		
		// the denied users and groups
		Vector deniedUsers = new Vector();
		Vector deniedGroups = new Vector();
		
		// for each permission
		EsupPermissions perms = access.getPermissions(path);//, EsupPermission.READ);
		permissions.clone(perms);
		
		//System.out.println("je recupere les ACL");
		//System.out.println(perms);
		
		// each permission
		Iterator iter = perms.iterator();
		while(iter.hasNext()) {
			
			EsupPermission perm = (EsupPermission)iter.next();
			boolean inherited = perm.isInherited();
			String inheritedFrom = perm.getInheritedFrom();
			
			// if the type is read
			String type = perm.getPermissionType();
			if (type.equals(EsupPermission.READ)) {
			
				String principal = perm.getPrincipal();
				boolean isGrant = perm.isGrantPermission();
				
				// check if user
				int index = principal.indexOf(userPrefix);
				if (index != -1) {
					String userKey = principal.substring(userPrefix.length());					
					User u = new User(userKey);
					//if (inherited)
						//u.setDisplayName(u.getDisplayName()+" HERITEE de "+inheritedFrom);
					
					// if deny, we add it into the deny vector
					if (!isGrant) {
						deniedUsers.addElement(u);
					}
					else {
						// if not denieded before, and not added to users
						if (!users.contains(u) && !deniedUsers.contains(u)) {						
							users.addElement(u);
						}
					}
				}			
				
				//	check if group
				index = principal.indexOf(groupPrefix);
				if (index != -1) {
					String groupKeysHierarchy = principal.substring(groupPrefix.length());					
					try {
						Group g = new Group(groupKeysHierarchy);
						//if (inherited)
							g.setDisplayName(g.getDisplayName()+" HERITEE de "+inheritedFrom);

						// if deny, we add it into the deny vector
						if (!isGrant) {
							deniedGroups.addElement(g);
						}
						else {
							// if not denieded before, and not added to groups
							if (!groups.contains(g) && !deniedGroups.contains(g)) {						
								groups.addElement(g);
							}
						}
					}
					catch(ServerException e) {

						// log
						if (log.isDebugEnabled()){
							log.debug("getReadersAclOnSpace"+" :: "+e);
						}
					}
				}
			}
		}
		
		// log
		if (log.isDebugEnabled()){
			log.debug("getReadersAclOnSpace"+" :: "+path+" end of acl getting");
		}
		
		return publicAccess;*/
	}
	
	
	
}
