/*
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.Hashtable;
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.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.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.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) throws ChannelException {
		super.init(person, currentSpace, spaces, buffer, userPortalLogin, userGroups);
	}
	
	

	/**
	 * Set the sharing properties of the currentDirectory
	 * @throws ServerException
	 * @throws DataBaseException
	 * @throws PropertiesException
	 * @throws AclReadException
	 * @throws AclAccessException
	 * @throws AclWriteException
	 * @throws NotSupportedAclException
	 */
	private void setCurrentDirectorySharingProperties() throws ServerException, DataBaseException, PropertiesException, AclReadException, AclAccessException, AclWriteException, NotSupportedAclException {
		
		// 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;
		}
		
		// construct an empty object		
		this.currentSpace.setTargetsOfSharing(new DirectorySharingProperties(name));
		
		// get the targets
		Object[] res = this.sharingTool.getTargetsOfAvailableSpace(this.currentSpace, this.currentSpace.getUrl(), this.currentSpace.getCurrentPath());
		
		// the space object
		//this.currentSpace.getTargetsOfSharing().setSharedSpace((Space)res[0]);
		
		// the users
		Hashtable users = (Hashtable)res[1];		
		this.currentSpace.getTargetsOfSharing().setUsers(users);
		
		// the groups		
		Hashtable groups = (Hashtable)res[2];
		this.currentSpace.getTargetsOfSharing().setGroups(groups);
		
		// the temp shared space
		this.tempSharedSpace = (Space)res[0];//(Space)this.currentSpace.cloneWithServer();
		this.tempSharedSpace.setTargetsOfSharing((DirectorySharingProperties)this.currentSpace.getTargetsOfSharing().clone());
		
		//System.out.println("space: "+this.tempSharedSpace);
		// the label
		if (this.tempSharedSpace.getLabel() == null)
			this.tempSharedSpace.setLabel(this.currentSpace.getPathElementAt(this.currentSpace.getPathSize()-1));
		/*String label = ((Space)res[0]).getLabel();
		System.out.println("label trouve: "+label);
		if (label!=null) {
			this.tempSharedSpace.setLabel(label);
		}
		else {
			this.tempSharedSpace.setLabel(this.currentSpace.getPathElementAt(this.currentSpace.getPathSize()-1));
		}*/
		

		// the key
		/*if (this.currentSpace.getLabel() == null)
			this.currentSpace.setLabel(this.currentSpace.getPathElementAt(this.currentSpace.getPathSize()-1));*/
		/*String key = ((Space)res[0]).getKey();
		System.out.println("key trouve: "+key);
		if (key!=null) {
			this.tempSharedSpace.setKey(key);
		}*/
		
	}
	
	
	
	/**
	 * 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);				
		}
		
		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 PropertiesException {
		stylesheet = new StringBuffer("CStockage");
		return DefaultRenderXml.getXml(spaces, currentSpace, null, informationCode, this.sharingTool, this.buffer.getCurrentSortType());
	}
	
	
	

	/**
	 * 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) {
			if (this.currentSpace.isSharing()) {
				setCurrentDirectorySharingProperties();
			}
		}
	}
	
	
	

	
	/**
	 * Return the xml when we have a BadConnexionParameters exception
	 * @param e the throwed exception
	 * @return the xml when we have a BadConnexionParameters exception
	 */
	protected 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  {	
		//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
			if (this.currentSpace.isSharing())
				setCurrentDirectorySharingProperties();
			
			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
				if (this.currentSpace.isSharing())
					setCurrentDirectorySharingProperties();
				
				return DefaultRenderXml.getXml(spaces, currentSpace, null , null, this.sharingTool, this.buffer.getCurrentSortType());
			}
		}
		
		// 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
			if (this.currentSpace.isSharing())
				setCurrentDirectorySharingProperties();						
		}		
	}
	
	
	
 

	/**
	 * 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");
		String cancel = runtimeData.getParameter("Cancel");
		
		if (submit == null) {
			throw new CancelException();
		} 
		else {
			String information = null;
			String error = null;
				
			String path = currentSpace.getCurrentPath();
			int errorCode = 0;

			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");
		String cancel = runtimeData.getParameter("Cancel");
		
		if (submit == null) {
			buffer.setFileToRename(null);
			throw new CancelException();
		}
		else {
			String information = null;
			String error = null;
				
			// 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.isSharing()) {			
				// 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");
		String cancel = runtimeData.getParameter("Cancel");
		
		if (submit == null) {
			throw new CancelException();
		}
		
		deleteWithoutConfirm();					
	} 
	
	
	
	/**
	 * Delete resource(s) without confirmation
	 * @throws ChannelException
	 */
	private void deleteWithoutConfirm() throws ChannelException {		
		
		String information = null;
		String error = null;
			
		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.isSharing()) {		
				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");
		String cancel = runtimeData.getParameter("Cancel");
		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();
			}			
			
			String information = null;
			String error = null;
			
			// 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(), currentSpace.getCurrentPath());
		}
		catch (PasteDeletedResourceException e) {
			buffer.setClipboard(null);
			buffer.setClipboardParameter(null);
			buffer.setClipboardPath(null);
			buffer.setClipboardSpace(null);
			
			throw new PasteDeletedResourceException();
		}
		
		// 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 submit = runtimeData.getParameter("Submit");
		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, clipboardSpace, clipboardPath, currentSpace.getKey(), currentSpace.getCurrentPath());
				}
				else {
					
					// log
					if (log.isDebugEnabled()){
						log.debug("paste"+" :: move clipboardElement = "+clipboardElement);
					}
					
					this.currentSpace.getServerAccessObject().move(clipboardElement, clipboardSpace, clipboardPath, currentSpace.getKey(), currentSpace.getCurrentPath());
					
					if (clipboardSpace.isSharing()) {		
					
						// 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 tempSharedSpace;
	
	
	/**
	 * 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 {	
		
		// 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));
		}*/
		
		// 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 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();
			}		
	}
	
	
	
	
	/**
	 * When click on cancel
	 * @return the xml when we click on cancel
	 * @throws CancelException
	 */
	private StringBuffer renderXmlShareDirectoryCancel() throws CancelException {
		//this.tempSharedSpace = 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) {
		
		// the label
		String label = runtimeData.getParameter("label");
		tempSharedSpace.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
		Hashtable users = tempSharedSpace.getTargetsOfSharing().getUsers();
		Hashtable groups = tempSharedSpace.getTargetsOfSharing().getGroups();
		
		// for each user, we check if he has read and/or write rights
		Enumeration enum = users.elements();
		while (enum.hasMoreElements()) {
			UserForPersonalization u = (UserForPersonalization)enum.nextElement();
			String key = u.getKey();
			
			if (u.isModifiable()) {
				// 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.setReading(true);
				}
				else {
					u.setReading(false);
				}
			
				// 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.setWriting(true);
					u.setReading(true);
				}
				else {
					u.setWriting(false);
				}
			
				// 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.setWriting(true);
					u.setReading(true);
					u.setSharing(true);
				}
				else {
					u.setSharing(false);
				}
			}
		}

		// for each group, we check if he has read and/or write rights
		enum = groups.elements();
		while (enum.hasMoreElements()) {
			GroupForPersonalization g = (GroupForPersonalization)enum.nextElement();
			String key = g.getKey();
			
			if (g.isModifiable()) {
				// 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.setReading(true);
				}
				else {
					g.setReading(false);
				}
				
				// 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.setWriting(true);
					g.setReading(true);
				}
				else {
					g.setWriting(false);
				}
	
				// 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.setWriting(true);
					g.setReading(true);
					g.setSharing(true);
				}
				else {
					g.setSharing(false);
				}
			}
		}
	}
	
	
	
	
	/**
	 * 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.tempSharedSpace = 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.setReading(true);
					this.tempSharedSpace.getTargetsOfSharing().getUsers().put(user.getKey(), 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.setReading(true);
							this.tempSharedSpace.getTargetsOfSharing().getGroups().put(group.getKey(), 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
		Hashtable users = this.tempSharedSpace.getTargetsOfSharing().getUsers();
		for (int i=0; i<selection.length; i++) {
			users.remove(selection[i]);
		}
		
		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
		Hashtable groups = this.tempSharedSpace.getTargetsOfSharing().getGroups();
		for (int i=0; i<selection.length; i++) {
			groups.remove(selection[i]);
		}
		
		return renderXmlShareDirectoryGenerateXml();
	}
	
	
	
	
	/**
	 * Generate xml for the directory sharing
	 * @return the xml for the directory sharing
	 */
	private StringBuffer renderXmlShareDirectoryGenerateXml() {
		return tempSharedSpace.getTargetsOfSharing().getXml(tempSharedSpace.getLabel());		
	}
	
	
	
	/**
	 * Set the properties for the current directory
	 */	
	private void setSharingProperties() throws DataBaseException, PropertiesException, ServerException, AclAccessException, AclWriteException, AclReadException, NotSupportedAclException { // TODO

		
		// the new label
		String newLabel = this.tempSharedSpace.getLabel();
		
		// the properties before modifications
		Hashtable usersBefore = this.currentSpace.getTargetsOfSharing().getUsers();
		Hashtable groupsBefore = this.currentSpace.getTargetsOfSharing().getGroups();		
		
		// the properties after modifications
		Hashtable usersAfter = this.tempSharedSpace.getTargetsOfSharing().getUsers();
		Hashtable groupsAfter = this.tempSharedSpace.getTargetsOfSharing().getGroups();		
		
		// the shared space
		Space sharedSpace = tempSharedSpace;//this.tempSharingProperties.getSharedSpace();
		//System.out.println("server ID: "+sharedSpace.getServer().getId());
		
		// the users which has been added
		Enumeration enum = usersAfter.elements();
		Vector usersToAdd = new Vector();
		while(enum.hasMoreElements()) {
			UserForPersonalization u = (UserForPersonalization)enum.nextElement();
			String key = (String)u.getKey();
			
			if (!usersBefore.containsKey(key) && (u.isReading() || u.isWriting() || u.isSharing())) {
				usersToAdd.add(u);
			}
		}
		//sharingTool.addStorageAvailableSpaceUsers(currentSpace, sharedSpace, currentSpace.getUrl(), userPortalLogin, currentSpace.getCurrentPath(), usersToAdd);

		// the groups which has been added
		enum = groupsAfter.elements();
		Vector groupsToAdd = new Vector();
		while(enum.hasMoreElements()) {
			GroupForPersonalization g = (GroupForPersonalization)enum.nextElement();
			String key = (String)g.getKey();			
			
			if (!groupsBefore.containsKey(key) && (g.isReading() || g.isWriting() || g.isSharing())) {
				groupsToAdd.add(g);
			}			
		}
		sharingTool.addStorageAvailableSpace(currentSpace, sharedSpace, currentSpace.getUrl(), userPortalLogin, currentSpace.getCurrentPath(), usersToAdd, groupsToAdd);
		
		// the users which has been deleted, or still here
		enum = usersBefore.elements();
		Vector usersToDelete = new Vector();
		Vector usersToUpdate = new Vector();
		while(enum.hasMoreElements()) {
			UserForPersonalization userBefore = (UserForPersonalization)enum.nextElement();
			String keyBefore = (String)userBefore.getKey();		
			
			UserForPersonalization userAfter = (UserForPersonalization)usersAfter.get(keyBefore);
			
			// deleted
			if (userAfter==null) {
				usersToDelete.add(userBefore);
			}
			
			// still here
			else {			
				//System.out.print("user "+keyBefore+" est encore la, ");
				
				// check if the reading and writing attributes are equals
				if (userBefore.isReading()==userAfter.isReading() && userBefore.isWriting()==userAfter.isWriting() && userBefore.isSharing()==userAfter.isSharing()) {
					//System.out.println("read et write egaux");					
				}
				// not equals, we have to update
				else {
					//System.out.println("read et write PAS egaux");
					// if not read and not write, we delete
					if (!userAfter.isReading() && !userAfter.isWriting() && !userAfter.isSharing()) {
						usersToDelete.add(userBefore);
					}
					// we update
					else {
						usersToUpdate.add(userAfter);
					}
				}				
			}		
		}
		sharingTool.delStorageAvailableSpaceForUsers(currentSpace, usersToDelete, sharedSpace.getServer().getId());
		sharingTool.updateReadAndWriteAndShareSpaceUsers(currentSpace, usersToUpdate);

		// the groups which has been deleted, or still here
		enum = groupsBefore.elements();
		Vector groupsToDelete = new Vector();
		Vector groupsToUpdate = new Vector();
		while(enum.hasMoreElements()) {
			GroupForPersonalization groupBefore = (GroupForPersonalization)enum.nextElement();
			String keyBefore = (String)groupBefore.getKey();				
			
			GroupForPersonalization groupAfter = (GroupForPersonalization)groupsAfter.get(keyBefore);
			
			// deleted
			if (groupAfter==null) {
				groupsToDelete.add(groupBefore);
			}
			
			// still here
			else {				
				//System.out.print("group "+keyBefore+" est encore la, ");
				
				// check if the reading and writing attributes are equals
				if (groupBefore.isReading()==groupAfter.isReading() && groupBefore.isWriting()==groupAfter.isWriting() && groupBefore.isSharing()==groupAfter.isSharing()) {
					//System.out.println("read et write egaux");
				}
				// not equals, we have to update
				else {
					//System.out.println("read et write PAS egaux");
					// if not read and not write, we delete
					if (!groupAfter.isReading() && !groupAfter.isWriting() && !groupAfter.isSharing()) {
						groupsToDelete.add(groupBefore);
					}
					// we update
					else {
						groupsToUpdate.add(groupAfter);
					}
				}		
			}			
		}
		sharingTool.delStorageAvailableSpaceForGroups(currentSpace, groupsToDelete, sharedSpace.getServer().getId());
		sharingTool.updateReadAndWriteAndShareSpaceGroups(currentSpace, groupsToUpdate);
		
		
		// we update the label for each element in the database
		//String oldLabel = currentSpace.getLabel();
		//System.out.println("label : "+oldLabel+" --> "+newLabel);
		//if (!oldLabel.equals(newLabel)) {
			this.sharingTool.updateXmlServerAvailableSpace(sharedSpace);			
		//}
		
		
		//System.out.println("\n\n\n");
		
		
		// add properties for users
		//sharingTool.addStorageUsersSharing(currentSpace.getUrl(), currentSpace.getPath(), label, users, userPortalLogin, SpaceTool.getXmlFromSpace(currentSpace));		

		// add properties for groups
		//sharingTool.addStorageGroupsSharing(currentSpace.getUrl(), currentSpace.getPath(), label, groups, userPortalLogin, SpaceTool.getXmlFromSpace(currentSpace));
		
		
		
		
		// set the properties
		if (this.currentSpace.isSharing())
			setCurrentDirectorySharingProperties();
		//this.sharingTool.setCurrentDirectorySharingProperties(tempSharingProperties);
	}


	
	
	
	
	
	
	
	
	
	
	
}
