/*
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.classic;
 

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Vector;
 
import org.esupportail.portal.channels.CAnnuaire.CAnnuaireServantFactory;
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.BadFormatException;
import org.esupportail.portal.channels.CStockage.exception.CancelException;
import org.esupportail.portal.channels.CStockage.exception.ConnexionParametersRequired;
import org.esupportail.portal.channels.CStockage.exception.CreateDirectoryException;
import org.esupportail.portal.channels.CStockage.exception.DataBaseException;
import org.esupportail.portal.channels.CStockage.exception.NoneSelectedResourceException;
import org.esupportail.portal.channels.CStockage.exception.NotAuthorizedException;
import org.esupportail.portal.channels.CStockage.exception.NotAuthorizedNewDirException;
import org.esupportail.portal.channels.CStockage.exception.NotEmptyDirectoryException;
import org.esupportail.portal.channels.CStockage.exception.NotExistsResourceException;
import org.esupportail.portal.channels.CStockage.exception.NotSupportedAclException;
import org.esupportail.portal.channels.CStockage.exception.PasteDeletedResourceException;
import org.esupportail.portal.channels.CStockage.exception.PropertiesException;
import org.esupportail.portal.channels.CStockage.exception.ServerException;
import org.esupportail.portal.channels.CStockage.exception.StillExistsException;
import org.esupportail.portal.channels.CStockage.exception.TooMuchSelectedException;
import org.esupportail.portal.channels.CStockage.exception.ChannelException;
import org.esupportail.portal.channels.CStockage.exception.UploadException;
import org.esupportail.portal.channels.CStockage.provider.access.ServerAccess;
import org.esupportail.portal.channels.CStockage.spacesPersonalization.DirectorySharingProperties;
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.channels.CStockage.channelAction.AbstractChannelAction;
import org.esupportail.portal.channels.CStockage.channelAction.BufferAction;
import org.esupportail.portal.channels.CStockage.channelAction.Constants;
import org.esupportail.portal.channels.CStockage.channelAction.classic.DefaultRenderXml;
import org.esupportail.portal.channels.CStockage.channelAction.classic.sharing.SharedSpaceProperties;
import org.esupportail.portal.channels.CStockage.channelAction.classic.sharing.SharingTool;
import org.esupportail.portal.channels.CStockage.config.ChannelConfiguration;
import org.esupportail.portal.channels.CStockage.config.Space;
import org.jasig.portal.ChannelRuntimeData;
import org.jasig.portal.ChannelStaticData;
import org.jasig.portal.MultipartDataSource;
import org.jasig.portal.PortalException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.portal.channels.groupsmanager.CGroupsManagerServantFactory;
import org.jasig.portal.groups.EntityGroupImpl;
import org.jasig.portal.security.IPerson;
import org.jasig.portal.services.GroupService;
import org.jasig.portal.utils.XSLT;
import org.xml.sax.ContentHandler;

/**
 * Id: ChannelAction.java,v 1.0 24 sept. 2004
 * Copyright (c) 2004 Esup Portail (www.esup-portail.org)
 * Classes: ChannelAction
 * Original Author: Yohan Colmant
 * Class used to manage the actions when we are in a classic space context
 */
public class ChannelAction extends AbstractChannelAction {
 

	/**
	 * Logger object
	 */
	protected static final Log log = LogFactory.getLog(ChannelAction.class);
	
	
	
	
	
	/**
	 * Default constructor
	 */
	public ChannelAction() {
		
	}
	
	
	/**
	 * Init the object used to manage the actions of the channel
	 * @param person the uportal person object
	 * @param currentSpace the current space used
	 * @param spaces all the spaces used
	 * @param buffer the buffer used to get for example the clipboard
	 * @param userPortalLogin The user login in the portal
	 * @param userGroups The groups of the user in the portal
	 * @throws ChannelException
	 */
	public void init(IPerson person, Space currentSpace, ArrayList spaces, BufferAction buffer, String userPortalLogin, Vector userGroups) {
		super.init(person, currentSpace, spaces, buffer, userPortalLogin, userGroups);

		// init the current user of the space
		/*if (!currentSpace.getServer().isAskedAuthentication()) {
		initPrivilegesOfTheCurrentViewer();
		}*/
	}
	
	
	


	/**
	 * Init the current viewer of the space
	 * @throws ChannelException
	 */
	private void initPrivilegesOfTheCurrentViewer() throws ChannelException {
		
		// init the current user of the space
		SharedSpaceProperties prop = currentSpace.getCurrentViewer();
		if (prop == null) {
			prop = new SharedSpaceProperties();
			currentSpace.setCurrentViewer(prop);
		}
		
		// the root path
		if (prop.getSpaceRootPath()==null) {
			//if (!currentSpace.isPersonnalSpace()) {
				String spaceRootPath = currentSpace.getSpaceRootPath();
				prop.setSpaceRootPath(spaceRootPath);
			//}
		}
		
		UserForPersonalization user = prop.getUser();
		if (user == null) {
			user = new UserForPersonalization(userPortalLogin);
			prop.setUser(user);
			
			currentSpace.initCurrentUserPrivileges();
		}
		else {
			currentSpace.initCurrentUserPrivileges();
		}
		
		// init the sharing tool
		if (sharingTool==null && currentSpace.allowsSharing())
			sharingTool = new SharingTool();
			
	}
	
	
	
	/**
	 * For the selected mode, we check the properties of the current directory
	 * @throws Exception
	 */
	/*protected void checkCurrentDirectoryProperties() throws Exception {
		// if the current directory sharing properties has not been still initialized
		//if (this.sharingTool!=null && this.currentSpace.getTargetsOfSharing() == null) {
			//initCurrentDirectorySharingProperties();
		//}
	}*/
	
	

	/**
	 * Set the sharing properties of the currentDirectory
	 * @throws ServerException
	 * @throws DataBaseException
	 * @throws PropertiesException
	 * @throws AclReadException
	 * @throws AclAccessException
	 * @throws AclWriteException
	 * @throws NotSupportedAclException
	 */
	private void initCurrentDirectorySharingProperties() throws ServerException, DataBaseException, PropertiesException, AclReadException, AclAccessException, AclWriteException, NotSupportedAclException {

		// if the space supports the acl management
		if (this.currentSpace.allowsSharing()) {
			
			// the directory name we are going to show to the user
			String name = "";
			for (int i=0; i<currentSpace.getPathSize(); i++) {			
				if (i!=0)
					name += " > ";
				String n = currentSpace.getPathElementAt(i);			
				n = n.replaceAll("&","&amp;");
				n = n.replaceAll("\"","&#148;");			
				name += n;
			}
		
			// get the targets
			Object[] res = this.sharingTool.getTargetsOfAvailableSpaceFromAcl(this.currentSpace, this.currentSpace.getUrl());
			
			// the temp shared space
			this.currentSpaceSharing = (Space)res[0];
			this.currentSpaceSharing.setCurrentViewer(this.currentSpace.getCurrentViewer());
		
			// the label
			if (this.currentSpaceSharing.getLabel() == null)
				this.currentSpaceSharing.setLabel(this.currentSpace.getPathElementAt(this.currentSpace.getPathSize()-1));
			
			// the space object
			//System.out.println();
			this.currentSpaceSharing.setTargetsOfSharing(new DirectorySharingProperties(name));
			
			// the users
			Vector users = (Vector)res[1];		
			this.currentSpaceSharing.getTargetsOfSharing().setUsers(users);
			for (int i=0; i<users.size(); i++) {
				UserForPersonalization user = (UserForPersonalization)users.elementAt(i);
				
				// it is not the first time we set rights here
				if (user.getKey().equals(this.currentSpaceSharing.getOwner().getKey())) {
					if (user.getPersonalization().getReading()==1) {
						if (user.getPersonalization().getWriting()==1) {
							if (user.getPersonalization().getSharing()==1) {
								user.getPersonalization().setSecurityRight(true);
								user.getPersonalization().setModifiable(false);
							}	
						}
					}
				}
			}
			
			// the groups		
			Vector groups = (Vector)res[2];
			this.currentSpaceSharing.getTargetsOfSharing().setGroups(groups);
			
			// the others		
			Vector others = (Vector)res[3];
			this.currentSpaceSharing.getTargetsOfSharing().setOthers(others);
			
			// the inherited		
			Vector inherited = (Vector)res[4];
			this.currentSpaceSharing.getTargetsOfSharing().setInherited(inherited);
			
			// if there is a deny all all
			this.currentSpaceSharing.getTargetsOfSharing().setUseInheritedPrivileges(((Boolean)res[5]).booleanValue());
			//System.out.println("    deny all all: "+(!this.currentSpaceSharing.getTargetsOfSharing().useInheritedPrivileges()));
			
			// if there is a grant all read
			this.currentSpaceSharing.getTargetsOfSharing().setPublicDirectory(((Boolean)res[6]).booleanValue());
			//System.out.println("    grant all read: "+(!this.currentSpaceSharing.getTargetsOfSharing().isPublicDirectory()));
			
			
			// we init the Space sharing we are going to use for the edition
			initModifiedSpaceSharing();
		}
		
	}
	
	
	
	
	private void initModifiedSpaceSharing() throws ServerException, PropertiesException, AclWriteException, DataBaseException, AclAccessException, NotSupportedAclException, AclReadException {
		this.modifiedSpaceSharing = (Space)this.currentSpaceSharing.clone();
		
		// if there is none users and groups, we add the users and groups from the parent directory (if they have the rights of management)
		Vector originalUsers = this.currentSpaceSharing.getTargetsOfSharing().getUsers();
		Vector currentUsersClone = new Vector(originalUsers.size());
		for (int i=0; i<originalUsers.size(); i++) {
			UserForPersonalization userBefore = (UserForPersonalization)originalUsers.elementAt(i);
			
			// if this user is the same key that the security rights
			if (userBefore.getKey().equals(this.currentSpaceSharing.getOwner().getKey())) {
				
				// if this one is the real secutiry right
				if (userBefore.getPersonalization().isSecurityRight()) {
					currentUsersClone.addElement(userBefore.clone());
				}
				
				// this one is not the security right
				else {
					currentUsersClone.addElement(this.currentSpaceSharing.getOwner().clone());
				}
			}
			
			else {
				currentUsersClone.addElement(userBefore.clone());
			}
		}
		// if we add none user, we add the security user
		if (currentUsersClone.size()==0) {
			currentUsersClone.addElement(this.currentSpaceSharing.getOwner().clone());
		}
		
		Vector originalGroups = this.currentSpaceSharing.getTargetsOfSharing().getGroups();
		Vector currentGroupsClone = new Vector(originalGroups.size());
		for (int i=0; i<originalGroups.size(); i++) {
			currentGroupsClone.addElement(((GroupForPersonalization)originalGroups.elementAt(i)).clone());
		}
		Vector originalOthers = this.currentSpaceSharing.getTargetsOfSharing().getOthers();
		Vector currentOthersClone = new Vector(originalOthers.size());
		for (int i=0; i<originalOthers.size(); i++) {
			OtherPrincipalForPersonalization otherBefore = (OtherPrincipalForPersonalization)originalOthers.elementAt(i);
			
			// if this one is the same key that the security rights
			if (otherBefore.getKey().equals(this.currentSpace.getAclSecurity())) {
				
				// if this one is the real secutiry right
				if (otherBefore.getPersonalization().isSecurityRight()) {
					currentOthersClone.addElement(otherBefore.clone());
				}
				
				// this one is not the security right
				else {
					OtherPrincipalForPersonalization o = new OtherPrincipalForPersonalization(this.currentSpace.getAclSecurity());
					o.getPersonalization().setReading(1);
					o.getPersonalization().setWriting(1);
					o.getPersonalization().setSharing(1);
					o.getPersonalization().setSecurityRight(true);
					o.getPersonalization().setModifiable(false);
					currentOthersClone.addElement(o);
				}
			}
			
			else {
				currentOthersClone.addElement(otherBefore.clone());
			}
		}
		// if we add none other, we add the security acl
		if (currentOthersClone.size()==0) {
			OtherPrincipalForPersonalization o = new OtherPrincipalForPersonalization(this.currentSpace.getAclSecurity());
			o.getPersonalization().setReading(1);
			o.getPersonalization().setWriting(1);
			o.getPersonalization().setSharing(1);
			o.getPersonalization().setSecurityRight(true);
			o.getPersonalization().setModifiable(false);
			currentOthersClone.addElement(o);
		}
		
		
		Vector originalInherited = this.currentSpaceSharing.getTargetsOfSharing().getInherited();
		
		
		this.modifiedSpaceSharing.getTargetsOfSharing().setUsers(currentUsersClone);
		this.modifiedSpaceSharing.getTargetsOfSharing().setGroups(currentGroupsClone);
		this.modifiedSpaceSharing.getTargetsOfSharing().setOthers(currentOthersClone);
		this.modifiedSpaceSharing.getTargetsOfSharing().setInherited(originalInherited);
		
		
		// we don't inherit the rights
		if (!this.currentSpaceSharing.getTargetsOfSharing().useInheritedPrivileges()) {

			// it's the first time we set acl
			if (this.currentSpaceSharing.getKey() == null) {
				setInheritedAclAsDefault();
			}
		}
	}
	
	
	/**
	 * Set the inherited acl of users and groups as default for the current user
	 *
	 */
	private void setInheritedAclAsDefault() {
		for (int i=0; i<this.modifiedSpaceSharing.getTargetsOfSharing().getInherited().size(); i++) {
			Object o = this.modifiedSpaceSharing.getTargetsOfSharing().getInherited().elementAt(i);
			if (o instanceof UserForPersonalization) {
				UserForPersonalization user = (UserForPersonalization)o;
				
				// we check if this user is still in the list
				boolean found = false;
				for (int j=0; !found && j<this.modifiedSpaceSharing.getTargetsOfSharing().getUsers().size(); j++) {
					UserForPersonalization u = (UserForPersonalization)this.modifiedSpaceSharing.getTargetsOfSharing().getUsers().elementAt(j);
					if (u.getKey().equals(user.getKey()))
						found = true;
				}
				
				if (!found) {
					UserForPersonalization userClone = (UserForPersonalization)user.clone();
					this.modifiedSpaceSharing.getTargetsOfSharing().getUsers().add(userClone);
				}
			}
			else if (o instanceof GroupForPersonalization) {
				GroupForPersonalization group = (GroupForPersonalization)o;

				// we check if this group is still in the list
				boolean found = false;
				for (int j=0; !found && j<this.modifiedSpaceSharing.getTargetsOfSharing().getGroups().size(); j++) {
					GroupForPersonalization g = (GroupForPersonalization)this.modifiedSpaceSharing.getTargetsOfSharing().getGroups().elementAt(j);
					if (g.getKey().equals(group.getKey()))
						found = true;
				}
				if (!found) {
					GroupForPersonalization groupClone = (GroupForPersonalization)group.clone();
					this.modifiedSpaceSharing.getTargetsOfSharing().getGroups().add(groupClone);
				}
			}
		}
	}
	
	
	
	
	
	/**
	 * Manage the specific actions when refreshing the channel for the specific channel mode
	 * @param currentMode the current channel mode
	 * @param staticData the static data channel object
	 * @param runtimeData the runtime data channel object
	 * @param out the contentHandler used in the renderXml
	 * @param xslt the xslt motor object
	 * @param setStaticDataException the excpetion throwed in the setStaticData method
	 * @throws PortalException
	 */
	public StringBuffer specificCheckCalledAction(String currentMode, ChannelStaticData staticData, ChannelRuntimeData runtimeData, ContentHandler out, XSLT xslt, ChannelException setStaticDataException) throws ChannelException, PortalException {		
		
		//////////////////////////////////////////////////////
		// D I R E C T O R Y		
		//prepare create
		if (currentMode.equals(Constants.SET_NAME_FOR_CREATE_DIR_MODE)) {		
			stylesheet = new StringBuffer("setNewDirectory");
			return new StringBuffer();
		}
		//Real create
		else if (currentMode.equals(Constants.CREATE_DIR_MODE)) {					
			createDir(runtimeData);		
			return renderXmlWithInformation("2004");
		}
		
		//////////////////////////////////////////////////////
		// U P L O A D
		//prepare
		else if (currentMode.equals(Constants.SET_FILE_TO_UPLOAD_MODE)) {										
			stylesheet = new StringBuffer("setUpload");
			return new StringBuffer();
		} 
		//Real upload
		else if (currentMode.equals(Constants.UPLOAD_MODE)) {
			upload(runtimeData);			
			return renderXmlWithInformation("2001");
		} 

		//////////////////////////////////////////////////////
		//D E L E T E
		//confirm
		else if (currentMode.equals(Constants.CONFIRM_DELETE_MODE)) {					
			StringBuffer x = renderXmlConfirmDelete(runtimeData);
			//
			if (ChannelConfiguration.getInstance().getConfirmDel()) {
				stylesheet = new StringBuffer("confirmDelete");
				return x;
			}
			
			// sinon, on passe directement au mode supprimer
			else {
				deleteWithoutConfirm();				
				return renderXmlWithInformation("2002");
			}													
		}
		//Real delete
		else if (currentMode.equals(Constants.DELETE_MODE)) {										
			delete(runtimeData);					
			return renderXmlWithInformation("2002");
		}
		
		//////////////////////////////////////////////////////  
		//C O P Y
		//set clipboard
		else if (currentMode.equals(Constants.SET_CLIPBOARD_FOR_COPY_MODE)) {
			setClipboard(Constants.COPY_MODE, runtimeData);
			return renderXmlWithInformation("2007");
		}
		
		// ask if we paste really
		else if (currentMode.equals(Constants.CONFIRM_PASTE_MODE)) {			
			stylesheet = new StringBuffer("confirmPaste");								
			return renderXmlConfirmPaste();
		}
		
		//Real paste
		else if (currentMode.equals(Constants.PASTE_MODE)) {
			stylesheet = new StringBuffer("CStockage");
			return paste(runtimeData);						
		}
		
		//////////////////////////////////////////////////////
		//M O V E
		//set clipboard
		else if (currentMode.equals(Constants.SET_CLIPBOARD_FOR_MOVE_MODE)) {						
			setClipboard(Constants.MOVE_MODE, runtimeData);
			return renderXmlWithInformation("2007");
		}			
		
		//////////////////////////////////////////////////////
		//R E N A M E
		//prepare
		else if (currentMode.equals(Constants.SET_NAME_FOR_RENAME_MODE)) {
			stylesheet = new StringBuffer("setRename");
			return renderXmlSetNameForRename(runtimeData);		
		}
		//Real rename
		else if (currentMode.equals(Constants.RENAME_MODE)) {				
			rename(runtimeData);			
			return renderXmlWithInformation("2003");
		} 
		
		//////////////////////////////////////////////////////
		//S H A R E
		//
		else if (currentMode.equals(ClassicConstants.SHARE_DIRECTORY_MODE)) {
			stylesheet = new StringBuffer("shareFolder");
			return renderXmlShareDirectory(runtimeData, staticData, out);			
		}
		
		// valid the servant results
		else if (currentMode.equals(Constants.VALID_SERVANT_RESULTS)) {		
			stylesheet = new StringBuffer("shareFolder");
			return renderXmlShareDirectoryValidServantResults(runtimeData, staticData);				
		}

		//////////////////////////////////////////////////////
		//S H A R E : Delete privileges
		//
		else if (currentMode.equals(ClassicConstants.CONFIRM_DELETE_PRIVILEGES_MODE)) {
			stylesheet = new StringBuffer("confirmDeletePrivileges");
			return new StringBuffer();			
		}
		
		// delete the privileges of the directory
		else if (currentMode.equals(ClassicConstants.DELETE_PRIVILEGES_MODE)) {		
			return deletePrivileges(runtimeData, staticData, out);
		}
		
		else return new StringBuffer();
	}
	
	
	

	/**
	 * Return the xml when we have to show a information message
	 * @return the xml when we have to show a information message
	 */
	public StringBuffer renderXmlWithInformation(String informationCode) throws ChannelException {
		stylesheet = new StringBuffer("CStockage");

		// check the privileges of the current user
		initPrivilegesOfTheCurrentViewer();
		
		return DefaultRenderXml.getXml(spaces, currentSpace, null, informationCode, this.sharingTool, this.buffer.getCurrentSortType());
	}
	
	
	

	
	
	
	

	
	/**
	 * Return the xml when we have a BadConnexionParameters exception
	 * @param e the throwed exception
	 * @return the xml when we have a BadConnexionParameters exception
	 */
	public StringBuffer renderXmlBadConnexionParametersException(ChannelException e) throws PropertiesException {
		return DefaultRenderXml.getXmlForPasswordSetting(spaces, currentSpace, e);
	}
	
	
	/**
	 * Return the xml when we have a ChannelException exception
	 * @param e the throwed exception
	 * @return the xml when we have a ChannelException exception
	 */
	public StringBuffer renderXmlChannelException(ChannelException e) {
		return DefaultRenderXml.getXml(spaces, currentSpace, e, null, this.sharingTool, this.buffer.getCurrentSortType());		
	}
	
	
	
	
	

	
	/**
	 * Generate the XML String for this mod
	 * @param runtimeData the runtime data channel object
	 * @return the XML for this mod
	 * @throws ChannelException
	 */
	protected StringBuffer renderXmlShowCurrentDir(ChannelRuntimeData runtimeData) throws ChannelException  {
		
		// if it the asked authentication, and none password still set
		if (this.currentSpace.isAskedAuthentication() && this.currentSpace.getPassword()==null) {
			throw new ConnexionParametersRequired();
		}
		
		//When we enter in a sub directory ...		
		String directoryCible = runtimeData.getParameter("targetDirectory");
		if (directoryCible != null) {

			//System.out.println("targetDirectory: "+directoryCible); 
			
			// log
			if (log.isDebugEnabled()){
				log.debug("renderXmlShowCurrentDir"+" :: directoryCible = "+directoryCible);
			}
			
			// test if exists
			String currentPath = this.currentSpace.getCurrentPath();
			ServerAccess access = this.currentSpace.getServerAccessObject();
			
			if (!access.exists(directoryCible, currentPath)) {
				NotExistsResourceException e = new NotExistsResourceException();
				// log
				if (log.isDebugEnabled()){
					log.debug("renderXmlShowCurrentDir"+" ::  "+e);
				}
				throw e;
			}			

			// we add it to path
			currentSpace.addPathElement(directoryCible);
						
			// init the properties of this directory
			//initCurrentDirectorySharingProperties();
			
			// check the privileges of the current user
			initPrivilegesOfTheCurrentViewer();
			
			return DefaultRenderXml.getXml(spaces, currentSpace, null , null, this.sharingTool, this.buffer.getCurrentSortType());
		}
		else {
			//... by naviguation tool
			String dir = runtimeData.getParameter("link");
			if (dir != null) {

				// log
				if (log.isDebugEnabled()){
					log.debug("renderXmlShowCurrentDir"+" :: link = "+dir);
				}
				
				int index = Integer.parseInt(dir);
				int curentDirLength = currentSpace.getPathSize();
				if (index < curentDirLength) {					
					for (int i=0; i< (curentDirLength-(index+1)); i++) {						
						currentSpace.removePathElement(currentSpace.getPathSize()-1);
					}			
				}

				// init the properties of this directory
				//initCurrentDirectorySharingProperties();

				// check the privileges of the current user
				initPrivilegesOfTheCurrentViewer();
				
				return DefaultRenderXml.getXml(spaces, currentSpace, null , null, this.sharingTool, this.buffer.getCurrentSortType());
			}
		}
		
		// check the privileges of the current user
		initPrivilegesOfTheCurrentViewer();
		
		// all others cases
		return DefaultRenderXml.getXml(spaces, currentSpace, null , null, this.sharingTool, this.buffer.getCurrentSortType()); 
	}
	
	
	/**
	 * Go to the parent directory
	 * @throws ChannelException
	 */
	protected void directoryBack() throws ChannelException {

		// log
		if (log.isDebugEnabled()){
			log.debug("directoryBack");
		}

		if (currentSpace.getPathSize()>1) {		

			currentSpace.removePathElement(currentSpace.getPathSize()-1);
			
			// init the properties of this directory
			//initCurrentDirectorySharingProperties();
			
			// check the privileges of the current user
			initPrivilegesOfTheCurrentViewer();
		}		
	}
	
	
	
 

	/**
	 * Create a new directory
	 * @param runtimeData the runtime data channel object
	 */
	private void createDir(ChannelRuntimeData runtimeData) throws CancelException, ApplicationException, CreateDirectoryException, StillExistsException, BadFormatException, NotAuthorizedException, NotAuthorizedNewDirException, NotExistsResourceException, PropertiesException{
		String submit = runtimeData.getParameter("Submit");
		
		if (submit == null) {
			throw new CancelException();
		} 
		else {
				
			String path = currentSpace.getCurrentPath();
			
			String newDirName = runtimeData.getParameter("new_dir");
			this.currentSpace.getServerAccessObject().createDir(newDirName, path);
        	

			// log
			if (log.isDebugEnabled()){
				log.debug("createDir"+" :: newDirName = "+newDirName);
			}

			
		}
	}

	
	
	
	


	/**************************
	 *   Rename/Delete methods
	 **************************/
		
	
	
	
	/**
	 * Generate the XML String for this mod
	 * @param runtimeData the runtime data channel object
	 * @return the XML StringBuffer for this mod
	 * @throws ChannelException
	 */
	private StringBuffer renderXmlSetNameForRename(ChannelRuntimeData runtimeData) throws ChannelException {
		// we get the files we want to rename
		String[] files = runtimeData.getParameterValues("listeFic");
		
		if (files == null) {

			// log
			if (log.isDebugEnabled()){
				log.debug("renderXmlSetNameForRename"+" :: NoneSelectedResourceException");
			}

			stylesheet = new StringBuffer("CStockage");
			throw new NoneSelectedResourceException();
		}		
		else {						
			// if there is more than one file
			if (files.length > 1) {

				// log
				if (log.isDebugEnabled()){
					log.debug("renderXmlSetNameForRename"+" :: TooMuchSelectedException");
				}
				
				stylesheet = new StringBuffer("CStockage");
				throw new TooMuchSelectedException();
			}
			else {			
				String fileToRename = files[0];				

				// System.out.println("fileToRename: "+fileToRename);  
				
				// log
				if (log.isDebugEnabled()){
					log.debug("renderXmlSetNameForRename"+" :: fileToRename = "+fileToRename);
				}
				
				buffer.setFileToRename(fileToRename);
				StringBuffer sb = new StringBuffer();
				sb.append("<OLD>");
				fileToRename = fileToRename.replaceAll("&","&amp;");
				fileToRename = fileToRename.replaceAll("\"","&#148;");
				sb.append(fileToRename);
				sb.append("</OLD>");
				return sb;
			}					
		}
	}
	
	
	/**
	 * Rename the selected resource
	 * @param runtimeData the runtime data channel object
	 */
	private void rename(ChannelRuntimeData runtimeData) throws ChannelException{
		String submit = runtimeData.getParameter("Submit");
		
		if (submit == null) {
			buffer.setFileToRename(null);
			throw new CancelException();
		}
		else {
				
			// we clicked on the validate button: we rename 
			String path = currentSpace.getCurrentPath();		
						
			String newName = runtimeData.getParameter("new_name");
			
			// log
			if (log.isDebugEnabled()){
				log.debug("rename"+" :: newName = "+newName);
			}
			
			this.currentSpace.getServerAccessObject().rename(buffer.getFileToRename(), newName, path);
			
			if (this.currentSpace.allowsSharing()) {			
				// update the database with the new name
				String oldPath = path+buffer.getFileToRename()+"/";
				String newPath = path+newName+"/";
				this.sharingTool.updatePathOfSharing(currentSpace.getUrl(), oldPath, newPath);
			}
			
			buffer.setFileToRename(null);						
		}
	}
		
	
	
	
	
	
	/**
	 * Generate the XML String for this mod
	 * @param runtimeData the runtime data channel object
	 * @return the xml used to confirm a delete
	 * @throws ChannelException
	 */
	private StringBuffer renderXmlConfirmDelete(ChannelRuntimeData runtimeData) throws ChannelException {
		// Xml generated
		StringBuffer xml = new StringBuffer();
		
		String[] filesToDelete = runtimeData.getParameterValues("listeFic");
		buffer.setFilesToDelete(filesToDelete);	
		if (filesToDelete == null) {

			// log
			if (log.isDebugEnabled()){
				log.debug("renderXmlConfirmDelete"+" :: NoneSelectedResourceException");
			}

			throw new NoneSelectedResourceException();			
		}
		
		else {
			//check if it is allowed to delete non empty directory
			boolean authorise = ChannelConfiguration.getInstance().getAllowDelNonEmptyFolder();		

			//For each piece of the selection
			for (int j=0;j<filesToDelete.length;j++){
				String fileName = filesToDelete[j];				

				String path = currentSpace.getCurrentPath();			
				
				//check if it is a directory or a file
				boolean isDirectory = this.currentSpace.getServerAccessObject().isDirectory(fileName, path);																
				if (isDirectory) {	
					
					//check if non empty
					boolean empty = this.currentSpace.getServerAccessObject().isEmpty(fileName, path);														
										
					if (!empty && !authorise) {
						//Delete forbidden for this directory
						buffer.setFilesToDelete(null);						
						throw new NotEmptyDirectoryException();
					}
					else if (!empty && authorise) {
						fileName = fileName.replaceAll("&","&amp;");
						fileName = fileName.replaceAll("\"","&#148;");
						xml.append("<DIR name=\""+fileName+"\" empty=\""+false+"\"/>");
					}
					else if (empty) {			
						fileName = fileName.replaceAll("&","&amp;");
						fileName = fileName.replaceAll("\"","&#148;");
						xml.append("<DIR name=\""+fileName+"\" empty=\""+true+"\"/>");
					}
				}
				
				else if (!isDirectory) {	
					fileName = fileName.replaceAll("&","&amp;");
					fileName = fileName.replaceAll("\"","&#148;");
					xml.append("<FILE name=\""+fileName+"\"/>");
				}
			}			
			return xml;					
		}
	}
	
		
	
	
	
	/**
	 * Delete the specified resource(s)
	 * @param runtimeData the runtime data channel object
	 * @throws ChannelException
	 */
	private void delete(ChannelRuntimeData runtimeData) throws ChannelException  {
		String submit = runtimeData.getParameter("Submit");
		
		if (submit == null) {
			throw new CancelException();
		}
		
		deleteWithoutConfirm();					
	} 
	
	
	
	/**
	 * Delete resource(s) without confirmation
	 * @throws ChannelException
	 */
	private void deleteWithoutConfirm() throws ChannelException {		
			
		String path = currentSpace.getCurrentPath();		
		
		String[] filesToDelete = buffer.getFilesToDelete();
		
		for (int i=0; i<filesToDelete.length; i++) {
			String file = (String)filesToDelete[i];

			// log
			if (log.isDebugEnabled()){
				log.debug("deleteWithoutConfirm"+" :: file = "+file);
			}
			
			// delete
			this.currentSpace.getServerAccessObject().delete(file, path);
			
			// delete sharing preferences
			if (this.currentSpace.allowsSharing()) {		
				this.sharingTool.delStorageAvailableSpaceForSpecifiedPath(this.currentSpace.getUrl(), path+file+"/");
			}
			
		}
			
		buffer.setFilesToDelete(null);									
	}
	
	
	
	
	/**
	 * Start the upload
	 * @param runtimeData the runtime data channel object
	 * @throws ChannelException
	 */
	private void upload(ChannelRuntimeData runtimeData) throws ChannelException {
	       
		String submit = runtimeData.getParameter("Submit");
		Object inputFile = runtimeData.getObjectParameter("input_file");        
	
		if (submit == null) {		
			throw new CancelException();		       		       	
		}
		else {			
			// if file is null
			if (inputFile == null) {	
				// log
				if (log.isDebugEnabled()){
					log.debug("upload"+" :: NotExistsResourceException");
				}
				
				throw new NotExistsResourceException();
			}			
			
			// get a reference to the file
			MultipartDataSource mps = (MultipartDataSource)inputFile;   	        	
			
			try {
				// check the file size				
				InputStream stream = mps.getInputStream();
				String fileName = mps.getName();
				
				
				/*
				
				int fileSize = stream.available();
				System.out.println(fileSize);
				if (fileSize > 29999) {
					stream.close();
					
					if (log.isDebugEnabled()){
						log.debug("upload"+" :: inputFile = "+fileName+" size too important:"+fileSize);
					}
					throw new SizeLimitUploadException();
				}																	
				
				*/
				
				
				// log
				if (log.isDebugEnabled()){
					log.debug("upload"+" :: inputFile = "+fileName);
				}
				
				String path = currentSpace.getCurrentPath();
		        this.currentSpace.getServerAccessObject().upload(fileName, stream, path);
			}
			catch(IOException e) {
				log.error("upload"+" :: inputFile = "+mps.getName()+" "+e);
				throw new UploadException();		
			}			
	        
		}
	}


	
	
	/**
	 * Set the clipboard
	 * @param mode used: copy or move
	 * @param runtimeData the runtime data channel object
	 * @throws NoneSelectedResourceException
	 * @throws ApplicationException
	 * @throws NotAuthorizedException
	 */
	private void setClipboard(String mode, ChannelRuntimeData runtimeData) throws NoneSelectedResourceException, ApplicationException, NotAuthorizedException {			
		
		//check the files/directories from parameters
		String[] files = runtimeData.getParameterValues("listeFic");
		if (files == null) {

			// log
			if (log.isDebugEnabled()){
				log.debug("setClipboard"+" NoneSelectedResourceException");
			}

			throw new NoneSelectedResourceException();
		}		
		else {
			
			// we check if we are authorized to copy all selected resources			
			String tempPath = currentSpace.getCurrentPath();
			for (int j=0;j<files.length;j++){
				String fileName = files[j];
				if (!this.currentSpace.getServerAccessObject().canRead(fileName, tempPath)) {

					// log
					if (log.isDebugEnabled()){
						log.debug("setClipboard"+" :: fileName = "+fileName+" : NotAuthorizedException");
					}

					// we erase the clipboard					
					buffer.setClipboard(null);
					buffer.setClipboardParameter(null);
					buffer.setClipboardPath(null);
					buffer.setClipboardSpace(null);
					
					// we throw an exception
					throw new NotAuthorizedException();
				}
			}
			
			// if none NotAuthorizedException throwed
			
			// files/directories to copy			
			buffer.setClipboard(new Vector());
			buffer.setClipboardPath(currentSpace.getCurrentPath());
			buffer.setClipboardSpace(currentSpace);
			
			for (int j=0;j<files.length;j++){
				String fileName = files[j];

				// log
				if (log.isDebugEnabled()){
					log.debug("setClipboard"+" :: add "+fileName+" into the clipboard");
				}
				
				buffer.getClipboard().addElement(fileName);				
			}			
		}
		

		// log
		if (log.isDebugEnabled()){
			log.debug("setClipboard"+" :: setClipboardParameter("+mode+")");
		}
		
		buffer.setClipboardParameter(mode);
	}
	
	
	
	/**
	 * Generate the XML String for this mod
	 * @return the XML String for this mod
	 * @throws ChannelException
	 */
	private StringBuffer renderXmlConfirmPaste() throws ChannelException {
		
		// we check if we can paste here
		try {
			
			// log
			if (log.isDebugEnabled()){
				log.debug("renderXmlConfirmPaste"+" :: canPaste "+buffer.getClipboard()+" ?");
			}
			
			this.currentSpace.getServerAccessObject().canPaste(buffer.getClipboardSpace(), this.currentSpace.getKey(), buffer.getClipboardPath(), buffer.getClipboard(), buffer.getClipboard(), currentSpace.getCurrentPath());
		}
		catch (PasteDeletedResourceException e) {
			buffer.setClipboard(null);
			buffer.setClipboardParameter(null);
			buffer.setClipboardPath(null);
			buffer.setClipboardSpace(null);
			
			throw e;
		}
		
		// Xml generated
		StringBuffer xml = new StringBuffer();
		
		//For each piece of the selection
		Vector clipboard = buffer.getClipboard();
		for (int j=0;j<clipboard.size();j++){
			String fileName = (String)clipboard.elementAt(j);				
			
			//check if it is a directory or a file
			boolean isDirectory = buffer.getClipboardSpace().getServerAccessObject().isDirectory(fileName, buffer.getClipboardPath());								
						
			if (isDirectory) {	
					
				//check if non empty
				boolean empty = buffer.getClipboardSpace().getServerAccessObject().isEmpty(fileName, buffer.getClipboardPath());														
				
				if (!empty) {
					fileName = fileName.replaceAll("&","&amp;");
					fileName = fileName.replaceAll("\"","&#148;");
					xml.append("<DIR name=\""+fileName+"\" empty=\""+false+"\"/>");
				}
				else if (empty) {
					fileName = fileName.replaceAll("&","&amp;");
					fileName = fileName.replaceAll("\"","&#148;");
					xml.append("<DIR name=\""+fileName+"\" empty=\""+true+"\"/>");
				}
			}				
			else if (!isDirectory) {					
				fileName = fileName.replaceAll("&","&amp;");
				fileName = fileName.replaceAll("\"","&#148;");
				xml.append("<FILE name=\""+fileName+"\"/>");
			}
		}
			
		return xml;							
	}
	
	
	/**
	 * Generate the XML String for this mod
	 * @param runtimeData the runtime data channel object
	 * @return the XML String for this mod
	 * @throws ChannelException
	 */
	private StringBuffer paste(ChannelRuntimeData runtimeData) throws ChannelException {
		String cancel = runtimeData.getParameter("Cancel");
		
		Vector clipboard = buffer.getClipboard();
		String clipboardPath = buffer.getClipboardPath();
		String clipboardParameter = buffer.getClipboardParameter();
		Space clipboardSpace = buffer.getClipboardSpace();
		
		if (cancel == null) {			
			for (int i=0; i<clipboard.size(); i++) {		
				String clipboardElement = ((String)clipboard.elementAt(i));
				
				if (clipboardParameter.equals(Constants.COPY_MODE)) {
					
					// log
					if (log.isDebugEnabled()){
						log.debug("paste"+" :: copy clipboardElement = "+clipboardElement);
					}

					this.currentSpace.getServerAccessObject().copy(clipboardElement, clipboardElement, clipboardSpace, clipboardPath, currentSpace.getKey(), currentSpace.getCurrentPath());
				}
				else {
					
					// log
					if (log.isDebugEnabled()){
						log.debug("paste"+" :: move clipboardElement = "+clipboardElement);
					}
					
					this.currentSpace.getServerAccessObject().move(clipboardElement, clipboardElement, clipboardSpace, clipboardPath, currentSpace.getKey(), currentSpace.getCurrentPath());
					
					if (clipboardSpace.allowsSharing()) {		
					
						// if the server is the same
						if (currentSpace.getServer().getUrl().equals(clipboardSpace.getServer().getUrl())) {
					
							// we update the path
							String oldPath = clipboardPath+clipboardElement+"/";
							String newPath = currentSpace.getCurrentPath()+clipboardElement+"/";
							this.sharingTool.updatePathOfSharing(clipboardSpace.getUrl(), oldPath, newPath);
						}
						else {
						
							// we delete the path
							String oldPath = clipboardPath+clipboardElement+"/";
							this.sharingTool.delStorageAvailableSpaceForSpecifiedPath(clipboardSpace.getUrl(), oldPath);
						}
					}
					
				}						
			}			
		} 		
		else {

			// log
			if (log.isDebugEnabled()){
				log.debug("paste"+" :: CancelException");
			}

			throw new CancelException();
		}				
		
		// if well done
		if (clipboardParameter.equals(Constants.COPY_MODE)) {			
			/*
			// if we want to set empty the clipboard
			clipboard = null;
			clipboardParameter = null;
			clipboardPath = null;
			*/
			return DefaultRenderXml.getXml(spaces, currentSpace, null, "2005", this.sharingTool, this.buffer.getCurrentSortType());	
		}
		else {
			buffer.setClipboard(null);
			buffer.setClipboardParameter(null);
			buffer.setClipboardPath(null);
			buffer.setClipboardSpace(null);
			return DefaultRenderXml.getXml(spaces, currentSpace, null, "2006", this.sharingTool, this.buffer.getCurrentSortType());	
		}
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	

	
	/******************************
	 * Sharing of directory methods
	 ******************************/
	

	/**
	 * sharing directory properties used during the sharing management
	 */
	private Space currentSpaceSharing;
	
	/**
	 * sharing directory properties used during the sharing management
	 */
	private Space modifiedSpaceSharing;
	
	
	/**
	 * Return XML for the directory sharing mode 
	 * @param runtimeData
	 * @param staticData
	 * @param out
	 * @return XML for the directory sharing mode 
	 * @throws PortalException
	 * @throws ChannelException
	 */
	private StringBuffer renderXmlShareDirectory(ChannelRuntimeData runtimeData, ChannelStaticData staticData, ContentHandler out) throws PortalException, ChannelException {	
		
		try {
		
			// init the temporary sharing properties object
			/*if (this.tempSharedSpace == null) {
				this.tempSharedSpace = (Space)this.currentSpace.cloneWithServer();
				this.tempSharedSpace.setLabel(this.currentSpace.getPathElementAt(this.currentSpace.getPathSize()-1));
			}*/
			
			// init the sharing properties
			if (this.currentSpaceSharing == null) {
				initCurrentDirectorySharingProperties();
			}
			
			// if we click on "valid" or "cancel"
			String action = runtimeData.getParameter("mode");
			
			if (action!=null && !action.equals("")) {
				
				if (action.equals("cancel"))
					return renderXmlShareDirectoryCancel();
				else if (action.equals("valid"))
					return renderXmlShareDirectoryValid(runtimeData);
				else if (action.equals("change_inheritance"))
					return renderXmlShareDirectoryChangeInheritance(runtimeData);
				else if (action.equals("change_public"))
					return renderXmlShareDirectoryChangePublic(runtimeData);
				return renderXmlShareDirectoryGenerateXml();
			}
			
			else {
				
					// if click on add user
					String addUserButton = runtimeData.getParameter("add_user");
					if (addUserButton != null)
						return renderXmlShareDirectoryAddUser(runtimeData, staticData, out);
				
					// if click on add group
					String addGroupButton = runtimeData.getParameter("add_group");
					if (addGroupButton != null)
						return renderXmlShareDirectoryAddGroup(runtimeData, staticData, out);
				
					// if click on delete user
					String deleteUserButton = runtimeData.getParameter("delete_user");
					if (deleteUserButton != null)
						return renderXmlShareDirectoryDeleteUser(runtimeData);
				
					// if click on delete group
					String deleteGroupButton = runtimeData.getParameter("delete_group");
					if (deleteGroupButton != null)
						return renderXmlShareDirectoryDeleteGroup(runtimeData);
	
					return renderXmlShareDirectoryGenerateXml();
				}	
		}
		catch(ChannelException e) {
			this.currentSpaceSharing = null;
			throw e;
		}
		catch(PortalException e) {
			this.currentSpaceSharing = null;
			throw e;
		}
		catch(NullPointerException e) {
			this.currentSpaceSharing = null;
			throw new ApplicationException();
		}
	}
	
	
	
	

	/**
	 * When change the inheritance of the sharing
	 * @param runtimeData
	 * @return xml when we valid the sharing
	 * @throws ChannelException
	 */
	private StringBuffer renderXmlShareDirectoryChangeInheritance(ChannelRuntimeData runtimeData) throws ChannelException {
		
		String useInherited = runtimeData.getParameter("useInherited");
		
		this.modifiedSpaceSharing.getTargetsOfSharing().setUseInheritedPrivileges(useInherited);
		
		// if use inherited, we delete each inherited acl from users and groups
		if (useInherited.equals("true")) {
			for (int i=0; i<this.modifiedSpaceSharing.getTargetsOfSharing().getUsers().size(); i++) {
				UserForPersonalization user = (UserForPersonalization)this.modifiedSpaceSharing.getTargetsOfSharing().getUsers().elementAt(i);
				if (user.getPersonalization().isInheritedAcl()) {
					this.modifiedSpaceSharing.getTargetsOfSharing().getUsers().remove(i);
					i--;
				}
			}
			for (int i=0; i<this.modifiedSpaceSharing.getTargetsOfSharing().getGroups().size(); i++) {
				GroupForPersonalization group = (GroupForPersonalization)this.modifiedSpaceSharing.getTargetsOfSharing().getGroups().elementAt(i);
				if (group.getPersonalization().isInheritedAcl()) {
					this.modifiedSpaceSharing.getTargetsOfSharing().getGroups().remove(i);
					i--;
				}
			}
		}
		// if we don't use the inherited acl, and if it is the first time we set acl here, we set inherited acl as default for the current user
		else {
			if (this.currentSpaceSharing.getKey() == null) {
				setInheritedAclAsDefault();
			}
		}
		
		

		// check the parameters
		checkParameters(runtimeData);
		
		return renderXmlShareDirectoryGenerateXml();
	}
	
	

	/**
	 * When change the inheritance of the sharing
	 * @param runtimeData
	 * @return xml when we valid the sharing
	 * @throws ChannelException
	 */
	private StringBuffer renderXmlShareDirectoryChangePublic(ChannelRuntimeData runtimeData) throws ChannelException {
		
		
		this.modifiedSpaceSharing.getTargetsOfSharing().setPublicDirectory(runtimeData.getParameter("isPublic"));

		// check the parameters
		checkParameters(runtimeData);
		
		return renderXmlShareDirectoryGenerateXml();
	}
	
	
	
	/**
	 * When click on cancel
	 * @return the xml when we click on cancel
	 * @throws CancelException
	 */
	private StringBuffer renderXmlShareDirectoryCancel() throws CancelException, ServerException, DataBaseException, PropertiesException, AclReadException, AclAccessException, AclWriteException, NotSupportedAclException {
		//this.tempSharedSpace = null;
		//this.tempSharedSpace = (Space)this.sharedSpace.cloneWithServer();
		/*if (this.currentSpace.allowsSharing())
			initModifiedSpaceSharing();*/
		this.currentSpaceSharing = null;
		
		CancelException e = new CancelException();

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

	/**
	 * When valid the sharing
	 * @param runtimeData
	 */
	private void checkParameters(ChannelRuntimeData runtimeData) throws PropertiesException {

		// the label
		String label = runtimeData.getParameter("label");
		modifiedSpaceSharing.setLabel(label);
		
		// get the readers and writers
		String[] readUserList = runtimeData.getParameterValues("readUserList");
		String[] writeUserList = runtimeData.getParameterValues("writeUserList");
		String[] manageUserList = runtimeData.getParameterValues("manageUserList");
		
		String[] readGroupList = runtimeData.getParameterValues("readGroupList");
		String[] writeGroupList = runtimeData.getParameterValues("writeGroupList");
		String[] manageGroupList = runtimeData.getParameterValues("manageGroupList");
		
		// get the users and the groups
		Vector users = modifiedSpaceSharing.getTargetsOfSharing().getUsers();
		Vector groups = modifiedSpaceSharing.getTargetsOfSharing().getGroups();
		
		// if use inherited changed
		boolean changeInheritance = runtimeData.getParameter("mode")!=null && runtimeData.getParameter("mode").equals("change_inheritance");
		boolean useInherited = runtimeData.getParameter("useInherited")!=null && runtimeData.getParameter("useInherited").equals("true");
		
		// for each user, we check if he has read and/or write rights
		Enumeration iter = users.elements();
		while (iter.hasMoreElements()) {
			UserForPersonalization u = (UserForPersonalization)iter.nextElement();
			String key = u.getKey();
			
			if (u.getPersonalization().isModifiable() && !(u.getPersonalization().isInheritedAcl() && changeInheritance && !useInherited)) {
				// check if he can read
				boolean contains = false;
				for (int i=0; readUserList!=null && i<readUserList.length && !contains; i++) {
					if (readUserList[i].equals(key))
						contains = true;
				}
				if (contains) {
					u.getPersonalization().setReading(1);
				}
				else {
					u.getPersonalization().setReading(0);
				}
			
				// check if he can write
				contains = false;
				for (int i=0; writeUserList!=null && i<writeUserList.length && !contains; i++) {
					if (writeUserList[i].equals(key))
						contains = true;
				}			
				if (contains) {
					u.getPersonalization().setWriting(1);
					//u.getPersonalization().setReading(1);
				}
				else {
					u.getPersonalization().setWriting(0);
				}
			
				// check if he can manage
				contains = false;
				for (int i=0; manageUserList!=null && i<manageUserList.length && !contains; i++) {
					if (manageUserList[i].equals(key))
						contains = true;
				}			
				if (contains) {
					//u.getPersonalization().setWriting(1);
					//u.getPersonalization().setReading(1);
					u.getPersonalization().setSharing(1);
				}
				else {
					u.getPersonalization().setSharing(0);
				}

			}
		}

		// for each group, we check if he has read and/or write rights
		iter = groups.elements();
		while (iter.hasMoreElements()) {
			GroupForPersonalization g = (GroupForPersonalization)iter.nextElement();
			String key = g.getKey();
			
			if (g.getPersonalization().isModifiable() && !(g.getPersonalization().isInheritedAcl() && changeInheritance && !useInherited)) {
				// check if he can read
				boolean contains = false;
				for (int i=0; readGroupList!=null && i<readGroupList.length && !contains; i++) {
					if (readGroupList[i].equals(key))
						contains = true;
				}			
				if (contains) {
					g.getPersonalization().setReading(1);
				}
				else {
					g.getPersonalization().setReading(0);
				}
				
				// check if he can write
				contains = false;
				for (int i=0; writeGroupList!=null && i<writeGroupList.length && !contains; i++) {
					if (writeGroupList[i].equals(key))
						contains = true;
				}			
				if (contains) {
					g.getPersonalization().setWriting(1);
					//g.getPersonalization().setReading(1);
				}
				else {
					g.getPersonalization().setWriting(0);
				}
	
				// check if he can manage
				contains = false;
				for (int i=0; manageGroupList!=null && i<manageGroupList.length && !contains; i++) {
					if (manageGroupList[i].equals(key))
						contains = true;
				}			
				if (contains) {
					//g.getPersonalization().setWriting(1);
					//g.getPersonalization().setReading(1);
					g.getPersonalization().setSharing(1);
				}
				else {
					g.getPersonalization().setSharing(0);
				}
				
			}
		}
	}
	
	
	
	
	/**
	 * When valid the sharing
	 * @param runtimeData
	 * @return xml when we valid the sharing
	 * @throws ChannelException
	 */
	private StringBuffer renderXmlShareDirectoryValid(ChannelRuntimeData runtimeData) throws ChannelException {
		// check the parameters
		checkParameters(runtimeData);
		
		// set ACL and put into database
		try {
			setSharingProperties();
		}
		catch(ChannelException e) {

			// set the temporary properties to null
			this.modifiedSpaceSharing = null;
			
			throw e;
		}
		
		// set the temporary properties to null
		//this.tempSharedSpace = null;
		
		stylesheet = new StringBuffer("CStockage");
		return DefaultRenderXml.getXml(spaces, currentSpace, null, "2014", this.sharingTool, this.buffer.getCurrentSortType());
	}
	
	
	
	
	
	/**
	 * When we want to add a user
	 * @param runtimeData the runtime data object used in this channel
	 * @param staticData the static data object used in this channel
	 * @param out the output object used for the rendering
	 * @return the xml when we add somebody
	 * @throws PropertiesException
	 * @throws PortalException
	 */
	private StringBuffer renderXmlShareDirectoryAddUser(ChannelRuntimeData runtimeData, ChannelStaticData staticData, ContentHandler out) throws PropertiesException, PortalException {		
		
		// check the parameters
		checkParameters(runtimeData);
		
		staticData.setParameter("returnServant", "multiple");
		slave = CAnnuaireServantFactory.getAnnuaireServant(staticData);

		slave.setRuntimeData(runtimeData);		
		slave.renderXML(out);	
	
		return null;
	}
	
	
	
	
	

	/**
	 * When we want to add a group
	 * @param runtimeData the runtime data object used in this channel
	 * @param staticData the static data object used in this channel
	 * @param out the output object used for the rendering
	 * @return the xml when we add somebody
	 * @throws PropertiesException
	 * @throws PortalException
	 */
	private StringBuffer renderXmlShareDirectoryAddGroup(ChannelRuntimeData runtimeData, ChannelStaticData staticData, ContentHandler out) throws PropertiesException, PortalException {		

		// check the parameters
		checkParameters(runtimeData);
		
		slave = CGroupsManagerServantFactory.getGroupsServantforSelection(staticData, null, GroupService.EVERYONE, true, true);

		slave.setRuntimeData(runtimeData);		
		slave.renderXML(out);
	
		return null;
	}
	
	
	
	/**
	 * When we check the servant results
	 * @param runtimeData the runtime data object used in this channel
	 * @param staticData the static data object used in this channel
	 * @return the xml after getting the servant results
	 * @throws PropertiesException
	 */
	private StringBuffer renderXmlShareDirectoryValidServantResults(ChannelRuntimeData runtimeData, ChannelStaticData staticData) throws PropertiesException {
		
		// get the results
		Object[] objs = slave.getResults();
		if (objs!=null) {
			for (int i=0; i<objs.length; i++) {
				Object obj = objs[i];
			
				// if we have a people from the CAnnuaire servant
				if (obj instanceof org.esupportail.portal.channels.CAnnuaire.Personne) {
					org.esupportail.portal.channels.CAnnuaire.Personne pers = (org.esupportail.portal.channels.CAnnuaire.Personne)obj;
					
					UserForPersonalization user = new UserForPersonalization(pers);
					user.getPersonalization().setReading(1);
					
					// check if we still have this user
					boolean found = false;
					for (int j=0; !found && j<this.modifiedSpaceSharing.getTargetsOfSharing().getUsers().size(); j++) {
						UserForPersonalization u = (UserForPersonalization)this.modifiedSpaceSharing.getTargetsOfSharing().getUsers().elementAt(j);
						if (u.getKey().equals(pers.getIdentifier())) {
							found = true;
						}
					}
					if (!found)
						this.modifiedSpaceSharing.getTargetsOfSharing().getUsers().addElement(user);
				}
			
				// if we have a group from the CGroupManager servant
				else if (obj instanceof org.jasig.portal.groups.EntityGroupImpl) {
					EntityGroupImpl egi = (EntityGroupImpl)obj;
					String leafType = egi.getLeafType().getName();
				
					// if the selection is really a group of persons
					if (leafType.equals("org.jasig.portal.security.IPerson")) {					
					
						try {
							GroupForPersonalization group = new GroupForPersonalization(egi);
							group.getPersonalization().setReading(1);

							// check if we still have this user
							boolean found = false;
							for (int j=0; !found && j<this.modifiedSpaceSharing.getTargetsOfSharing().getGroups().size(); j++) {
								GroupForPersonalization g = (GroupForPersonalization)this.modifiedSpaceSharing.getTargetsOfSharing().getGroups().elementAt(j);
								if (g.getKey().equals(group.getKey())) {
									found = true;
								}
							}
							if (!found)
								this.modifiedSpaceSharing.getTargetsOfSharing().getGroups().addElement(group);
						}
						catch(ServerException e) {							
							log.error("renderXmlShareDirectoryValidServantResults"+" :: "+e);							
						}
					}
				}									
			}
		}
		
		slave = null;		
		staticData.setParameter("groupManagerFinished", "false");	
		return renderXmlShareDirectoryGenerateXml();
	}
	
	
	
	
	/**
	 * When we delete a user
	 * @param runtimeData the runtime data object used in the channel
	 * @return the xml when we delete somebody
	 * @throws PropertiesException
	 */
	private StringBuffer renderXmlShareDirectoryDeleteUser(ChannelRuntimeData runtimeData) throws PropertiesException {

		// check the parameters
		checkParameters(runtimeData);
		
		// the selection
		String[] selection = selection = runtimeData.getParameterValues("usersList");
		
		// if none selected
		if (selection==null || selection.length==0)
			return renderXmlShareDirectoryGenerateXml();
		
		// for each user, we delete it
		Vector users = this.modifiedSpaceSharing.getTargetsOfSharing().getUsers();
		for (int i=0; i<selection.length; i++) {
			boolean found = false;
			for (int j=0; !found && j<users.size(); j++) {
				UserForPersonalization user = (UserForPersonalization)users.elementAt(j);
				if (user.getKey().equals(selection[i])) {
					users.remove(j);
					j--;
					found = true;
				}
			}
		}
		
		return renderXmlShareDirectoryGenerateXml();
	}
	
	
	
	

	
	/**
	 * When we delete a group
	 * @param runtimeData the runtime data object used in the channel
	 * @return the xml when we delete somebody
	 * @throws PropertiesException
	 */
	private StringBuffer renderXmlShareDirectoryDeleteGroup(ChannelRuntimeData runtimeData) throws PropertiesException {

		// check the parameters
		checkParameters(runtimeData);
		
		// the selection
		String[] selection = selection = runtimeData.getParameterValues("groupsList");
		
		// if none selected
		if (selection==null || selection.length==0)
			return renderXmlShareDirectoryGenerateXml();
		
		// for each group, we delete it
		Vector groups = this.modifiedSpaceSharing.getTargetsOfSharing().getGroups();
		for (int i=0; i<selection.length; i++) {
			boolean found = false;
			for (int j=0; !found && j<groups.size(); j++) {
				GroupForPersonalization group = (GroupForPersonalization)groups.elementAt(j);
				if (group.getKey().equals(selection[i])) {
					groups.remove(j);
					j--;
					found = true;
				}
			}
		}
		
		return renderXmlShareDirectoryGenerateXml();
	}
	
	
	
	
	/**
	 * Generate xml for the directory sharing
	 * @return the xml for the directory sharing
	 */
	private StringBuffer renderXmlShareDirectoryGenerateXml() throws PropertiesException {
		return modifiedSpaceSharing.getTargetsOfSharing().getXml(modifiedSpaceSharing.getLabel(), modifiedSpaceSharing.allowsSharing(), currentSpace);		
	}
	
	
	
	/**
	 * Set the properties for the current directory
	 */	
	private void setSharingProperties() throws DataBaseException, PropertiesException, ServerException, AclAccessException, AclWriteException, AclReadException, NotSupportedAclException, ChannelException {

		// the properties before modifications
		Vector usersBefore = this.currentSpaceSharing.getTargetsOfSharing().getUsers();
		Vector groupsBefore = this.currentSpaceSharing.getTargetsOfSharing().getGroups();	
		Vector othersBefore = this.currentSpaceSharing.getTargetsOfSharing().getOthers();	
		
		// the properties after modifications
		Vector usersAfter = this.modifiedSpaceSharing.getTargetsOfSharing().getUsers();
		Vector groupsAfter = this.modifiedSpaceSharing.getTargetsOfSharing().getGroups();
		Vector othersAfter = this.modifiedSpaceSharing.getTargetsOfSharing().getOthers();
		
		/**
		 * 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 && (userAfter.getPersonalization().getReading()==1 || userAfter.getPersonalization().getWriting()==1 || userAfter.getPersonalization().getSharing()==1)) {// || u.getPersonalization().isAddInDatabase())) {
				usersToAdd.add(userAfter);
			}
		}
		
		// the groups which has been added
		iter = groupsAfter.elements();
		Vector groupsToAdd = new Vector();
		while(iter.hasMoreElements()) {
			GroupForPersonalization group = (GroupForPersonalization)iter.nextElement();
			String key = (String)group.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 && (group.getPersonalization().getReading()==1 || group.getPersonalization().getWriting()==1 || group.getPersonalization().getSharing()==1)) {
				groupsToAdd.add(group);
			}			
		}
		
		// the others which has been added
		iter = othersAfter.elements();
		Vector othersToAdd = new Vector();
		while(iter.hasMoreElements()) {
			OtherPrincipalForPersonalization other = (OtherPrincipalForPersonalization)iter.nextElement();
			String key = (String)other.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 && (other.getPersonalization().getReading()==1 || other.getPersonalization().getWriting()==1 || other.getPersonalization().getSharing()==1)) {
				othersToAdd.add(other);
			}			
		}
		//log
		if (log.isDebugEnabled()) {
			log.debug("setSharingProperties"+" :: usersToAdd: "+usersToAdd);
			log.debug("setSharingProperties"+" :: groupsToAdd: "+groupsToAdd);
			log.debug("setSharingProperties"+" :: othersToAdd: "+othersToAdd);
		}
		sharingTool.addStorageAvailableSpace(currentSpace, modifiedSpaceSharing, currentSpace.getUrl(), userPortalLogin, currentSpace.getCurrentPath(), usersToAdd, groupsToAdd, othersToAdd, new Boolean(modifiedSpaceSharing.getTargetsOfSharing().useInheritedPrivileges()), new Boolean(modifiedSpaceSharing.getTargetsOfSharing().isPublicDirectory()), modifiedSpaceSharing);
		
		
		/**
		 * 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("setSharingProperties"+" :: usersToDelete: "+usersToDelete);
		}
		sharingTool.delStorageAvailableSpaceForUsers(currentSpace, usersToDelete, modifiedSpaceSharing.getServer().getId());
		
		//log
		if (log.isDebugEnabled()) {
			log.debug("setSharingProperties"+" :: usersToUpdate: "+usersToUpdate);
		}
		sharingTool.updateReadAndWriteAndShareSpaceUsers(currentSpace, 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("setSharingProperties"+" :: groupsToDelete: "+groupsToDelete);
		}
		sharingTool.delStorageAvailableSpaceForGroups(currentSpace, groupsToDelete, modifiedSpaceSharing.getServer().getId());
		
		//log
		if (log.isDebugEnabled()) {
			log.debug("setSharingProperties"+" :: groupsToUpdate: "+groupsToUpdate);
		}
		sharingTool.updateReadAndWriteAndShareSpaceGroups(currentSpace, 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("setSharingProperties"+" :: othersToDelete: "+othersToDelete);
		}
		sharingTool.delStorageAvailableSpaceForOthers(currentSpace, othersToDelete, modifiedSpaceSharing.getServer().getId());
		
		//log
		if (log.isDebugEnabled()) {
			log.debug("setSharingProperties"+" :: othersToUpdate: "+othersToUpdate);
		}
		sharingTool.updateReadAndWriteAndShareSpaceOthers(currentSpace, othersToUpdate);
		
		
		
		
		/**
		 * INHERITANCE ... PUBLIC
		 */
		
		
		// add or remove the inheritance
		//sharingTool.setInheritance(currentSpace, modifiedSpaceSharing.getTargetsOfSharing().useInheritedPrivileges());
		
		// add or remove the inheritance
		//sharingTool.setPublic(currentSpace, modifiedSpaceSharing.getTargetsOfSharing().isPublicDirectory(), modifiedSpaceSharing);
		
		
		/**
		 * LABEL
		 */
		
		// we update the label for each element in the database
		this.sharingTool.updateXmlServerAvailableSpace(modifiedSpaceSharing);
		
		
		
		/**
		 * INIT
		 */
		
		// set the properties
		this.currentSpaceSharing = null;

		// check the privileges of the current user
		initPrivilegesOfTheCurrentViewer();
	}


	
	
	
	

	/**
	 * Generate the XML String for this mod
	 * @param runtimeData the runtime data channel object
	 * @return the XML String for this mod
	 * @throws ChannelException
	 */
	private StringBuffer deletePrivileges(ChannelRuntimeData runtimeData, ChannelStaticData staticData, ContentHandler out) throws ChannelException, PortalException {
		String cancel = runtimeData.getParameter("Cancel");
		
		// click on "YES"
		if (cancel == null) {
			this.sharingTool.deleteAllPrivileges(currentSpace, this.currentSpaceSharing.getServer().getId(), this.currentSpaceSharing.getKey());
			this.currentSpaceSharing = null;

			// check the privileges of the current user
			initPrivilegesOfTheCurrentViewer();
			
			return renderXmlWithInformation("2017");
		}
		
		// click on "NO"
		else {
			stylesheet = new StringBuffer("shareFolder");
			return renderXmlShareDirectory(runtimeData, staticData, out);	
		}				
	}
	
	
	
	
	
	
}
