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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.esupportail.portal.channels.CAnnuaire.CAnnuaireServantFactory;
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.injac.acl.InjacAclManager;
import org.esupportail.portal.channels.CStockage.channelAction.injac.actions.DocumentEditionAction;
import org.esupportail.portal.channels.CStockage.channelAction.injac.actions.DocumentPublicationAction;
import org.esupportail.portal.channels.CStockage.channelAction.injac.actions.DocumentRejectAction;
import org.esupportail.portal.channels.CStockage.channelAction.injac.actions.DocumentUnpublicationAction;
import org.esupportail.portal.channels.CStockage.channelAction.injac.actions.MetadataManagerAction;
import org.esupportail.portal.channels.CStockage.channelAction.injac.config.MetadataFileProfile;
import org.esupportail.portal.channels.CStockage.channelAction.injac.config.RenderingType;
import org.esupportail.portal.channels.CStockage.channelAction.injac.metadata.InjacSpaceManagementProperties;
import org.esupportail.portal.channels.CStockage.channelAction.injac.metadata.MetaDataConstants;
import org.esupportail.portal.channels.CStockage.channelAction.injac.metadata.MetaDataManager;
import org.esupportail.portal.channels.CStockage.config.ChannelConfiguration;
import org.esupportail.portal.channels.CStockage.config.Space;
import org.esupportail.portal.channels.CStockage.exception.ApplicationException;
import org.esupportail.portal.channels.CStockage.exception.BadConnexionParameters;
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.DeleteException;
import org.esupportail.portal.channels.CStockage.exception.NoneSelectedResourceException;
import org.esupportail.portal.channels.CStockage.exception.NotAuthorizedAccessPublishedDocumentException;
import org.esupportail.portal.channels.CStockage.exception.NotAuthorizedDeleteException;
import org.esupportail.portal.channels.CStockage.exception.NotAuthorizedException;
import org.esupportail.portal.channels.CStockage.exception.NotAuthorizedNewDirException;
import org.esupportail.portal.channels.CStockage.exception.NotAuthorizedRenameException;
import org.esupportail.portal.channels.CStockage.exception.NotExistsResourceException;
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.provider.ResourceControl;
import org.esupportail.portal.channels.CStockage.provider.access.ServerAccess;
import org.esupportail.portal.channels.CStockage.userManagement.Group;
import org.esupportail.portal.channels.CStockage.userManagement.User;
import org.jasig.portal.ChannelRuntimeData;
import org.jasig.portal.ChannelStaticData;
import org.jasig.portal.IServant;
import org.jasig.portal.PortalException;
import org.jasig.portal.channels.groupsmanager.CGroupsManagerServantFactory;
import org.jasig.portal.groups.EntityGroupImpl;
import org.jasig.portal.groups.GroupsException;
import org.jasig.portal.utils.XSLT;
import org.xml.sax.ContentHandler;

/**
 * Id: ChannelAction.java,v 1.0 27 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 an injac space context
 */
public class ChannelAction extends AbstractChannelAction {

	

	/**
	 * Logger object
	 */
	protected static final Log log = LogFactory.getLog(ChannelAction.class);
	
	
	
	/**
	 * Object use to manage an injac space properties
	 */
	private InjacSpaceManagementProperties smp;
	 
	/**
	 * The servant channel used for groups and users selection
	 */
	private IServant slave;
	
	

	/**
	 * Object used to know the properties of the current directory
	 */
	private DirectoryProperties directoryProperties;
	
	

	/**
	 * The metadata we have to set
	 */
	private ArrayList metadataToSet = new ArrayList();
	
	
	

	/**
	 * The stylesheet used
	 */
	private StringBuffer stylesheet;
	
	
	
	/**
	 * Default constructor
	 * 
	 */
	public ChannelAction() {		
	
	}
	
	/**
	 * Init the object used to manage the actions of the channel
	 * @param currentSpace the current space used
	 * @param spaces all the spaces used
	 * @param config the config class
	 * @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(Space currentSpace, ArrayList spaces, ChannelConfiguration config, BufferAction buffer, String userPortalLogin, Vector userGroups) throws ChannelException {
		super.init(currentSpace, spaces, config, buffer, userPortalLogin, userGroups);
		//setCurrentDirectoryProperties();		
	}
	
	
	
	/**
	 * Set the properties of the currentDirectory
	 * @throws ServerException
	 */
	private void setCurrentDirectoryProperties() throws ServerException {
		setCurrentDirectoryProperties(null);
	}
	
	
	
	/**
	 * Set the properties of the currentDirectory
	 * @param injacType the type of the directory
	 * @throws ServerException
	 */
	private void setCurrentDirectoryProperties(String injacType) throws ServerException {
		String currentDirPath = this.currentSpace.getPath();
		
		String localInjacType = injacType;
		if (localInjacType==null)
			localInjacType = MetaDataManager.getDirectoryType(currentSpace, currentDirPath);
		
		if (localInjacType!=null && localInjacType.equals(MetaDataConstants.INJAC_TYPE_SPACE)) {
			boolean userIsWriter = isUserWriterInSpace(currentDirPath, currentSpace, this.userPortalLogin, this.userGroups);
			boolean userIsEditor = isUserEditorInSpace(currentDirPath, currentSpace, this.userPortalLogin, this.userGroups);
			boolean userIsManager = isUserManagerInSpace(currentDirPath, currentSpace, this.userPortalLogin, this.userGroups);
			
			if (this.directoryProperties == null) {
				this.directoryProperties = new DirectoryProperties(localInjacType, userIsWriter, userIsEditor, userIsManager);
			}
			else {
				this.directoryProperties.setType(localInjacType);
				this.directoryProperties.setUserIsWriter(userIsWriter);
				this.directoryProperties.setUserIsEditor(userIsEditor);
				this.directoryProperties.setUserIsManager(userIsManager);
			}
		}
		
		else {
			
			if (this.directoryProperties == null) {
				this.directoryProperties = new DirectoryProperties(injacType, false, false, false);
			}
			else {
				this.directoryProperties.setType(injacType);
				this.directoryProperties.setUserIsWriter(false);
				this.directoryProperties.setUserIsEditor(false);
				this.directoryProperties.setUserIsManager(false);				
			}
		}
	}
	
	
	

	/**
	 * Check if the current user is manager in the specified space
	 * @param spacePath the space access path
	 * @param currentSpace the current space used
	 * @param userPortalLogin the uportal access login
	 * @param userGroups the groups of the user
	 * @return true if manager, false else
	 * @throws ServerException
	 */
	public static boolean isUserManagerInSpace(String spacePath, Space currentSpace, String userPortalLogin, Vector userGroups) throws ServerException {		
		String injacType = MetaDataManager.getDirectoryType(currentSpace, spacePath);
		if (injacType!=null && injacType.equals(MetaDataConstants.INJAC_TYPE_SPACE)) {
			boolean isManager = InjacSpaceManagementProperties.isUserManager(userPortalLogin, userGroups, currentSpace, spacePath);
			//System.out.println("Manager sur "+spacePath+": "+isManager);
			return isManager;
		}
		else return false;		
	}
	
	
	/**
	 * Check if the current user is writer in the specified space
	 * @param spacePath the space access path
	 * @param currentSpace the current space used
	 * @param userPortalLogin the uportal access login
	 * @param userGroups the groups of the user
	 * @return true if writer, false else
	 * @throws ServerException
	 */
	public static boolean isUserWriterInSpace(String spacePath, Space currentSpace, String userPortalLogin, Vector userGroups) throws ServerException {		
		String injacType = MetaDataManager.getDirectoryType(currentSpace, spacePath);
		if (injacType!=null && injacType.equals(MetaDataConstants.INJAC_TYPE_SPACE)) {
			boolean isWriter = InjacSpaceManagementProperties.isUserWriter(userPortalLogin, userGroups, currentSpace, spacePath);
			//System.out.println("Writer sur espace "+spacePath+": "+isWriter);
			return isWriter;
		}
		else return false;		
	}
	
	

	
	/**
	 * Check if the current user is editor in the specified space
	 * @param spacePath the space access path
	 * @param currentSpace the current space used
	 * @param userPortalLogin the uportal access login
	 * @param userGroups the groups of the user
	 * @return true if editor, false else
	 * @throws ServerException
	 */
	public static boolean isUserEditorInSpace(String spacePath, Space currentSpace, String userPortalLogin, Vector userGroups) throws ServerException {		
		String injacType = MetaDataManager.getDirectoryType(currentSpace, spacePath);
		if (injacType!=null && injacType.equals(MetaDataConstants.INJAC_TYPE_SPACE)) {
			boolean isEditor = InjacSpaceManagementProperties.isUserEditor(userPortalLogin, userGroups, currentSpace, spacePath);
			//System.out.println("Editor sur "+spacePath+": "+isEditor);
			return isEditor;
		}
		else return false;		
	}
	
	
	/**
	 * Check if the current user is the owner of the specified document
	 * @param documentPath the document access path
	 * @param currentSpace the current space used
	 * @param userPortalLogin the uportal access login
	 * @return true if author, false else
	 * @throws ServerException
	 */
	public static boolean isUserDocumentOwner(String documentPath, Space currentSpace, String userPortalLogin) throws ServerException {		
		
		String owner = MetaDataManager.getDocumentOwner(currentSpace, documentPath);
		
		boolean isOwner = owner.equals(userPortalLogin);			
		if (isOwner)
			return true;
		else return false;		
		
	}
	
	
	
	
	
	
	
	
	/**
	 * Manage the actions when refreshing the channel
	 * @param staticData the static data channel object
	 * @param runtimeData the runtime data channel object
	 * @param out a sax document handler
	 * @param xslt the xslt motor object
	 * @param setStaticDataException the excpetion throwed in the setStaticData method
	 * @throws PortalException
	 */
	public void checkCalledAction(ChannelStaticData staticData, ChannelRuntimeData runtimeData, ContentHandler out, XSLT xslt, ChannelException setStaticDataException) throws PortalException {		
		
		//System.out.println("\n\n\n\n");
		
		// set the mod
		// in the channel, there are 2 action menus. 
		// those menus have the same name modeDav. 
		// To differentiate the menu that we have selected, we check the value of the both. 
		// the menu with a not null value is the one we have selected.  
		String currentMode = null;
		String[] mod=runtimeData.getParameterValues("modeDav");
		//System.out.print("modeDav= ");
		if (mod != null){
			for (int i = 0; i<mod.length;i++){
				if (!mod[i].equals("")) {
					currentMode = mod[i];
				}
				//System.out.print(mod[i]);
				//System.out.println();
			}
		}
		//else System.out.println();
		

		// log
		if (log.isDebugEnabled()){
			log.debug("checkCalledAction"+" :: currentMode = "+currentMode);
		}
		
		
		// check if servant is active or not
		if (slave!=null) {
			slave.setRuntimeData(runtimeData);
			if (!slave.isFinished()) {								
				slave.renderXML(out);
				return;
			}
			else {								
				currentMode = InjacConstants.VALID_SERVANT_RESULTS;
			}
		}
		
		// the string we will return
		StringBuffer xml = new StringBuffer();
		xml.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");		
		xml.append("<ROOT>");
		
		
		// the stylesheet we are going to use
		stylesheet = new StringBuffer();

		// Xml string generated by the diferents methods
		StringBuffer xmlTemp = new StringBuffer();
		
		
		try {

			// if password set
			try {				
				if (currentMode!=null && currentMode.equals(Constants.PASSWORD_MODE)) {
					String login = runtimeData.getParameter("login");
					String password = runtimeData.getParameter("password");
					this.currentSpace.setLogin(login);
					this.currentSpace.setPassword(password);
					this.currentSpace.getServerAccessObject().init(this.currentSpace);
					currentMode = Constants.SHOW_CURRENT_DIR_MODE;
				}
			}
			catch(MalformedURLException e) {							
				if (log.isDebugEnabled()){
					log.debug("checkCalledAction"+" :: "+e);
				}
				throw new PropertiesException();
			}		
			
			
			// if none staticdata exception
			if (setStaticDataException==null) {
				
				// if it the asked authentication, and none password still set
				if (this.currentSpace.isAskedAuthentication() && this.currentSpace.getPassword()==null) {
					throw new BadConnexionParameters();
				}
				
				// else, connect to the server
				else {
					try {					
						this.currentSpace.getServerAccessObject().connect();
						
						// if the current directory properties has not been still initialized
						if (this.directoryProperties == null) {
							setCurrentDirectoryProperties();
						}
					}
					catch(BadConnexionParameters e) {
						throw e;
					}
					catch(Exception e) {
						setStaticDataException= new ServerException();
					}
				}
			}
			
			
			// check the setStaticDataException
			if (setStaticDataException!=null) {

				// log
				if (log.isDebugEnabled()){
					log.debug("checkCalledAction"+" :: setStaticDataException = "+setStaticDataException);
				}
				
				throw setStaticDataException;
			}
			
			
			// set the default mod
			if (currentMode == null) {			
				currentMode = Constants.SHOW_CURRENT_DIR_MODE;
			}

			//////////////////////////////////////////////////////
			// D I R E C T O R Y
			//Display the current directory
			if (currentMode.equals(Constants.SHOW_CURRENT_DIR_MODE)) {				
				xmlTemp = renderXmlShowCurrentDir(runtimeData);			
				stylesheet = new StringBuffer("CStockage");
			}
			//Go to the parent directory
			else if (currentMode.equals(Constants.DIRECTORY_BACK)) {	
				directoryBack();
				xmlTemp = renderXmlShowCurrentDir(runtimeData);			
				stylesheet = new StringBuffer("CStockage");
			}
			//prepare create
			else if (currentMode.equals(Constants.SET_NAME_FOR_CREATE_DIR_MODE)) {		
				stylesheet = new StringBuffer("setNewDirectory");						
			}
			//Real create
			else if (currentMode.equals(Constants.CREATE_DIR_MODE)) {		
				stylesheet = new StringBuffer("CStockage");
				createDir(runtimeData);		
				xmlTemp = DefaultRenderXml.getXml(spaces, currentSpace, null, "2004", config, userPortalLogin, userGroups, directoryProperties);
			}
			
			//////////////////////////////////////////////////////
			// S P A C E
			//prepare create
			else if (currentMode.equals(InjacConstants.SET_NAME_FOR_CREATE_SPACE_MODE)) {		
				stylesheet = new StringBuffer("setNewSpace");						
			}
			//Real create
			else if (currentMode.equals(InjacConstants.CREATE_SPACE_MODE)) {		
				stylesheet = new StringBuffer("CStockage");
				//createSpace(runtimeData);		
				xmlTemp = createSpace(runtimeData, staticData, out);//InjacRenderXml.getXml(spaces, currentSpace, null, "2004", config);
			}

			//admin
			else if (currentMode.equals(InjacConstants.ADMIN_SPACE_MODE)) {		
				stylesheet = new StringBuffer("adminSpace");
				xmlTemp = renderXmlAdminSpace(runtimeData, staticData, out);
				if (xmlTemp == null)
					return;
			}
			
			// valid the servant results
			else if (currentMode.equals(InjacConstants.VALID_SERVANT_RESULTS)) {		
				stylesheet = new StringBuffer("adminSpace");
				xmlTemp = renderXmlAdminSpaceValidServantResults(runtimeData, staticData);				
			}
			

			//////////////////////////////////////////////////////
			// D O C U M E N T   M E T A D A T A
			// metadata
			else if (currentMode.equals(InjacConstants.SET_METADATA_ON_DOCUMENT_MODE)) {		
				stylesheet = new StringBuffer("documentMetaData");
				xmlTemp = MetadataManagerAction.renderXmlMetadataManager(runtimeData, stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties, buffer);
			}
			

			//////////////////////////////////////////////////////  
			//S U B M I T   D O C U M E N T
			
			// ask if we want to submit
			else if (currentMode.equals(InjacConstants.CONFIRM_SUBMIT_MODE)) {			
				stylesheet = new StringBuffer("confirmSubmit");												
				xmlTemp = DocumentEditionAction.renderXmlConfirmSubmit(runtimeData, buffer, stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties);
			}
			
			//Real submit
			else if (currentMode.equals(InjacConstants.SUBMIT_MODE)) {
				stylesheet = new StringBuffer("CStockage");				
				xmlTemp = DocumentEditionAction.submit(runtimeData, stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties, buffer);
			}
			

			//////////////////////////////////////////////////////  
			//P U B L I S H   D O C U M E N T
			
			// ask if we want to publish
			else if (currentMode.equals(InjacConstants.CONFIRM_PUBLISH_MODE)) {			
				stylesheet = new StringBuffer("confirmPublish");												
				xmlTemp = DocumentPublicationAction.renderXmlConfirmPublish(runtimeData, buffer, stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties);
			}
			
			//Real publish
			else if (currentMode.equals(InjacConstants.PUBLISH_MODE)) {
				stylesheet = new StringBuffer("CStockage");				
				xmlTemp = DocumentPublicationAction.publish(runtimeData, stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties, buffer);
			}
			

			//////////////////////////////////////////////////////  
			//U N P U B L I S H   D O C U M E N T
			
			// ask if we want to unpublish
			else if (currentMode.equals(InjacConstants.CONFIRM_UNPUBLISH_MODE)) {			
				stylesheet = new StringBuffer("confirmUnpublish");												
				xmlTemp = DocumentUnpublicationAction.renderXmlConfirmUnpublish(runtimeData, buffer, stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties);
			}
			
			//Real unpublish
			else if (currentMode.equals(InjacConstants.UNPUBLISH_MODE)) {
				stylesheet = new StringBuffer("CStockage");				
				xmlTemp = DocumentUnpublicationAction.unpublish(runtimeData, stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties);
			}
			

			//////////////////////////////////////////////////////  
			//R E J E C T   D O C U M E N T
			
			// ask if we want to reject
			else if (currentMode.equals(InjacConstants.CONFIRM_REJECT_MODE)) {			
				stylesheet = new StringBuffer("confirmReject");												
				xmlTemp = DocumentRejectAction.renderXmlConfirmReject(runtimeData, buffer, stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties);
			}
			
			//Real reject
			else if (currentMode.equals(InjacConstants.REJECT_MODE)) {
				stylesheet = new StringBuffer("CStockage");				
				xmlTemp = DocumentRejectAction.reject(runtimeData, stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties, buffer);
			}
			
			//////////////////////////////////////////////////////
			//D E L E T E
			//confirm
			else if (currentMode.equals(Constants.CONFIRM_DELETE_MODE)) {									
				stylesheet = new StringBuffer("confirmDelete");
				xmlTemp = renderXmlConfirmDelete(runtimeData);
			}
			
			//Real delete
			else if (currentMode.equals(Constants.DELETE_MODE)) {										
				delete(runtimeData);
				stylesheet = new StringBuffer("CStockage");			
				xmlTemp = DefaultRenderXml.getXml(spaces, currentSpace, null, "2002", config, userPortalLogin, userGroups, directoryProperties);
			}

			//////////////////////////////////////////////////////  
			//C O P Y
			//set clipboard
			else if (currentMode.equals(Constants.SET_CLIPBOARD_FOR_COPY_MODE)) {			
				stylesheet = new StringBuffer("CStockage");				
				setClipboard(Constants.COPY_MODE, runtimeData);
				xmlTemp = DefaultRenderXml.getXml(spaces, currentSpace, null, "2007", config, userPortalLogin, userGroups, directoryProperties);
			}
			
			// ask if we paste really
			else if (currentMode.equals(Constants.CONFIRM_PASTE_MODE)) {			
				stylesheet = new StringBuffer("confirmPaste");								
				xmlTemp = renderXmlConfirmPaste();
			}
			
			//Real paste
			else if (currentMode.equals(Constants.PASTE_MODE)) {
				stylesheet = new StringBuffer("CStockage");
				xmlTemp = paste(runtimeData);						
			}

			//////////////////////////////////////////////////////
			//M O V E
			//set clipboard
			else if (currentMode.equals(Constants.SET_CLIPBOARD_FOR_MOVE_MODE)) {			
				stylesheet = new StringBuffer("CStockage");
				setClipboard(Constants.MOVE_MODE, runtimeData);
				xmlTemp = DefaultRenderXml.getXml(spaces, currentSpace, null, "2007", config, userPortalLogin, userGroups, directoryProperties);
			}			

			//////////////////////////////////////////////////////
			//R E N A M E
			//prepare
			else if (currentMode.equals(Constants.SET_NAME_FOR_RENAME_MODE)) {
				stylesheet = new StringBuffer("setRename");
				xmlTemp = renderXmlSetNameForRename(runtimeData);		
			}
			//Real rename
			else if (currentMode.equals(Constants.RENAME_MODE)) {				
				rename(runtimeData);
				stylesheet = new StringBuffer("CStockage");	
				xmlTemp = DefaultRenderXml.getXml(spaces, currentSpace, null, "2003", config, userPortalLogin, userGroups, directoryProperties);
			} 
			 
			xml.append(xmlTemp);			
				
		}		
		catch(BadConnexionParameters e) {
			stylesheet = new StringBuffer("CStockage");
			xml.append(DefaultRenderXml.getXmlForPasswordSetting(spaces, currentSpace, e, config));
			// log
			if (log.isDebugEnabled()){
				log.debug("checkCalledAction"+" :: "+e);
			}
		}
		catch(ChannelException e) {			
			stylesheet = new StringBuffer("CStockage");
			xml.append(DefaultRenderXml.getXml(spaces, currentSpace, e, null, config, userPortalLogin, userGroups, directoryProperties));
			// log
			if (log.isDebugEnabled()){
				log.debug("checkCalledAction"+" :: "+e);
			}
		}
		
		try {
			// discconnect from the dav
			this.currentSpace.getServerAccessObject().disconnect();
		}
		catch (Exception e) {
			// log
			if (log.isDebugEnabled()){
				log.debug("checkCalledAction"+" :: "+e);
			}
		}
				
		
		// set the stylesheet and the parameters

		//specify the stylesheet selector		
		xslt.setXSL("CStockage.ssl", stylesheet.toString(), runtimeData.getBrowserInfo());
		
		
		//url to the channel
		xslt.setStylesheetParameter("baseActionURL",runtimeData.getBaseActionURL());		
		xslt.setStylesheetParameter("mediaPath",runtimeData.getBaseMediaURL(this));
		
		//url to the download worker
		xslt.setStylesheetParameter( "downloadURL",runtimeData.getBaseWorkerURL( org.jasig.portal.UPFileSpec.FILE_DOWNLOAD_WORKER,true).replaceAll("%2F","/"));				
		
		
		// the parameter to know if there is a resource in the clipboard
		if (buffer.getClipboard() != null)
			xslt.setStylesheetParameter("isClipboardEmpty","false");			      
		
		// the parameter used in the copy/move mode. tell if the mode is copy or move
		String clipboardParameter = buffer.getClipboardParameter();
		if (clipboardParameter != null) {
			xslt.setStylesheetParameter("clipboardParameter",clipboardParameter);			

		}
		
		// the final balise
		xml.append("</ROOT>");
		
		//pass the result XML to the styling engine.
		String s = xml.toString();		
		xslt.setXML(s);		

		// set the output Handler for the output.
		xslt.setTarget(out);
	
		// do the deed
		xslt.transform();	
	}
	
	
	
	
	
	
	
	
	
	
	

	
	/**
	 * Generate the XML String for this mod
	 * @param runtimeData the runtime data channel object
	 * @return le XML pour ce mode
	 * @throws NotExistsResourceException
	 * @throws ApplicationException
	 * @throws NotAuthorizedException
	 * @throws ServerException
	 * @throws NotAuthorizedAccessPublishedDocumentException
	 */
	private StringBuffer renderXmlShowCurrentDir(ChannelRuntimeData runtimeData) throws NotExistsResourceException, ApplicationException, NotAuthorizedException, ServerException, NotAuthorizedAccessPublishedDocumentException {	
		
		//When we enter in a sub directory ...
		String targetDirectory = runtimeData.getParameter("targetDirectory");
		if (targetDirectory != null) {

			// log
			if (log.isDebugEnabled()){
				log.debug("renderXmlShowCurrentDir"+" :: targetDirectory = "+targetDirectory);
			}
			
			String currentPath = this.currentSpace.getPath();
			ServerAccess access = this.currentSpace.getServerAccessObject();
			
			if (!access.exists(targetDirectory, currentPath)) {
				NotExistsResourceException e = new NotExistsResourceException();
				// log
				if (log.isDebugEnabled()){
					log.debug("renderXmlShowCurrentDir"+" ::  "+e);
				}
				throw e;
			}
			
			// check if the target is a published document
			String fullPath = currentPath+targetDirectory;
			String directoryType = MetaDataManager.getDirectoryType(currentSpace, fullPath);
			if (directoryType!=null && directoryType.equals(MetaDataConstants.INJAC_TYPE_DOCUMENT)) {
				
				// if we are the document owner
				boolean owner = isUserDocumentOwner(fullPath, currentSpace, userPortalLogin);				
				if (owner) {					
					String documentState = MetaDataManager.getDocumentState(currentSpace, fullPath);					
					// the document if published
					if (documentState.equals(MetaDataConstants.DOCUMENT_PUBLISHED_STATE)) {
						NotAuthorizedAccessPublishedDocumentException e = new NotAuthorizedAccessPublishedDocumentException();
						// log
						if (log.isDebugEnabled()){
							log.debug("renderXmlShowCurrentDir"+" ::  "+e);
						}
						throw e;					
					}					
				}
				
				// we are not the document owner
				else {
					
					// we are editor in the space
					boolean editor = directoryProperties.isUserEditor();					
					if (editor) {						
						String documentState = MetaDataManager.getDocumentState(currentSpace, fullPath);						
						// the document if published
						if (documentState.equals(MetaDataConstants.DOCUMENT_PUBLISHED_STATE)) {
							NotAuthorizedAccessPublishedDocumentException e = new NotAuthorizedAccessPublishedDocumentException();
							// log
							if (log.isDebugEnabled()){
								log.debug("renderXmlShowCurrentDir"+" ::  "+e);
							}
							throw e;					
						}						
					}
					
					// we are not editor, not owner
					else {
						NotAuthorizedException e = new NotAuthorizedException();
						// log
						if (log.isDebugEnabled()){
							log.debug("renderXmlShowCurrentDir"+" ::  "+e);
						}
						throw e;
					}
					
					
				}
				
				// if we are not the document owner
				/*if (!isUserDocumentOwner(fullPath, access, userPortalLogin)) {					
					NotAuthorizedException e = new NotAuthorizedException();
					LogService.log(LogService.ERROR, "CStockage::InjacChannelAction::renderXmlShowCurrentDir : "+ e);
					throw e;
				}
				
				// we are the document owner
				else {
					String documentState = MetaDataManager.getDocumentState(access, fullPath);
					
					// the document if published
					if (documentState.equals(MetaDataConstants.DOCUMENT_PUBLISHED_STATE)) {
						NotAuthorizedAccessPublishedDocumentException e = new NotAuthorizedAccessPublishedDocumentException();
						LogService.log(LogService.ERROR, "CStockage::InjacChannelAction::renderXmlShowCurrentDir : "+ e);
						throw e;					
					}
				
				}*/
			}			

			// we add it to path
			currentSpace.addPathElement(targetDirectory);
			
			// init the properties of this directory
			setCurrentDirectoryProperties(directoryType);
			
			
			return DefaultRenderXml.getXml(spaces, currentSpace, null , null, config, userPortalLogin, userGroups, directoryProperties);
		}
		else {
			//... by naviguation tool
			String dir = runtimeData.getParameter("link");
			if (dir != null) {
				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
				setCurrentDirectoryProperties();
				
				return DefaultRenderXml.getXml(spaces, currentSpace, null , null, config, userPortalLogin, userGroups, directoryProperties);
			}
		}
					
		// all others cases
		return DefaultRenderXml.getXml(spaces, currentSpace, null , null, config, userPortalLogin, userGroups, directoryProperties);
	}
	
	
	/**
	 * Go to the parent directory
	 * @throws ServerException
	 */
	private void directoryBack() throws ServerException {
		// log
		if (log.isDebugEnabled()){
			log.debug("directoryBack");
		}
		
		if (currentSpace.getPathSize()>1) {			
			currentSpace.removePathElement(currentSpace.getPathSize()-1);			

			// init the properties of this directory
			setCurrentDirectoryProperties();
		}
	}
	
	
	
	
	
	
	
	
	

	/**
	 * Generate the XML String for this mod
	 * @param runtimeData the runtime data channel object
	 * @throws CancelException
	 * @throws ApplicationException
	 * @throws CreateDirectoryException
	 * @throws StillExistsException
	 * @throws BadFormatException
	 * @throws NotAuthorizedException
	 * @throws NotAuthorizedNewDirException
	 * @throws NotExistsResourceException
	 */
	private void createDir(ChannelRuntimeData runtimeData) throws CancelException, ApplicationException, CreateDirectoryException, StillExistsException, BadFormatException, NotAuthorizedException, NotAuthorizedNewDirException, NotExistsResourceException{
		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.getPath();
			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 String 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();
			//return WebdavRenderXml.getXml(spaces, currentSpace, new NoneSelectedResourceException(), null, config);
		}		
		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();
				//return WebdavRenderXml.getXml(spaces, currentSpace, new TooMuchSelectedException(), null, config);
			}
			else {			
				String fileToRename = files[0];

				// log
				if (log.isDebugEnabled()){
					log.debug("renderXmlSetNameForRename"+" :: fileToRename = "+fileToRename);
				}
				
				// check if we are able to rename this resource
				String currentPath = this.currentSpace.getPath();
				String fullPath = currentPath+fileToRename;
				String directoryType = MetaDataManager.getDirectoryType(currentSpace, fullPath);

				// if injac document
				if (directoryType!=null && directoryType.equals(MetaDataConstants.INJAC_TYPE_DOCUMENT)) {
					
					// if we are not the document owner
					if (!(isUserDocumentOwner(fullPath, currentSpace, userPortalLogin) || directoryProperties.isUserEditor()) ) {					
						NotAuthorizedDeleteException e = new NotAuthorizedDeleteException();

						// log
						if (log.isDebugEnabled()){
							log.debug("renderXmlSetNameForRename"+" :: "+e);
						}
						
						throw e;
					}
					
					else {
						String documentState = MetaDataManager.getDocumentState(currentSpace, fullPath);											
						
						// the document if published
						if (documentState!=null && documentState.equals(MetaDataConstants.DOCUMENT_PUBLISHED_STATE)) {
							NotAuthorizedAccessPublishedDocumentException e = new NotAuthorizedAccessPublishedDocumentException();

							// log
							if (log.isDebugEnabled()){
								log.debug("renderXmlSetNameForRename"+" :: "+e);
							}
							
							throw e;					
						}
					}
					
					
				}
				
				// if injac space
				else if (directoryType!=null && directoryType.equals(MetaDataConstants.INJAC_TYPE_SPACE)) {
					
					// if we are not the space manager
					if (!directoryProperties.isUserManager()) {									
						NotAuthorizedRenameException e = new NotAuthorizedRenameException();

						// log
						if (log.isDebugEnabled()){
							log.debug("renderXmlSetNameForRename"+" :: "+e);
						}
						
						throw e;
					}					
					
				}
				
				
				
				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;
			}					
		}
	}
	
	
	/**
	 * Generate the XML String for this mod
	 * @param runtimeData the runtime data channel object
	 * @throws ChannelException
	 */
	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.getPath();		
						
			String newName = runtimeData.getParameter("new_name");

			// log
			if (log.isDebugEnabled()){
				log.debug("rename"+" :: newName = "+newName);
			}
			
			this.currentSpace.getServerAccessObject().rename(buffer.getFileToRename(), newName, path);
			
			buffer.setFileToRename(null);						
		}
	}
		
	
	
	
	
	
	/**
	 * Generate the XML String for this mod
	 * @param runtimeData the runtime data channel object
	 * @return le XML pour ce mode
	 * @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 {
			
			//For each piece of the selection
			for (int j=0;j<filesToDelete.length;j++){
				String fileName = filesToDelete[j];								
				
				// check if we are able to rename this resource
				String currentPath = this.currentSpace.getPath();
				String fullPath = currentPath+fileName;
				String directoryType = MetaDataManager.getDirectoryType(currentSpace, fullPath);
				
				// if injac document
				if (directoryType!=null && directoryType.equals(MetaDataConstants.INJAC_TYPE_DOCUMENT)) {
					
					// if we are not the document owner
					if (!(isUserDocumentOwner(fullPath, currentSpace, userPortalLogin) || directoryProperties.isUserEditor()) ) {					
						NotAuthorizedDeleteException e = new NotAuthorizedDeleteException();

						// log
						if (log.isDebugEnabled()){
							log.debug("renderXmlConfirmDelete"+" :: "+e);
						}
						
						throw e;
					}
					
				}
				
				// if injac space
				else if (directoryType!=null && directoryType.equals(MetaDataConstants.INJAC_TYPE_SPACE)) {
					
					// if we are not the space manager
					if (!directoryProperties.isUserManager()) {									
						NotAuthorizedDeleteException e = new NotAuthorizedDeleteException();

						// log
						if (log.isDebugEnabled()){
							log.debug("renderXmlConfirmDelete"+" :: "+e);
						}
						
						throw e;
					}					
					
				}
				
				
				//String path = currentSpace.getPath();			
				
				//check if it is a directory or a file
				boolean isDirectory = this.currentSpace.getServerAccessObject().isDirectory(fileName, currentPath);																
				if (isDirectory) {	
					
					//check if non empty
					boolean empty = this.currentSpace.getServerAccessObject().isEmpty(fileName, currentPath);														
					
					fileName = fileName.replaceAll("&","&amp;");
					fileName = fileName.replaceAll("\"","&#148;");
					xml.append("<DIR name=\""+fileName+"\" empty=\""+empty+"\"/>");									
				}
				
				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
	 * @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();
		}
		
		String information = null;
		String error = null;
			
		String path = currentSpace.getPath();	
		
		String[] filesToDelete = buffer.getFilesToDelete();
		
		for (int i=0; i<filesToDelete.length; i++) {
			String file = (String)filesToDelete[i];

			// log
			if (log.isDebugEnabled()){
				log.debug("delete"+" :: file = "+file);
			}
			
			this.currentSpace.getServerAccessObject().delete(file, path);				
		}
			
		buffer.setFilesToDelete(null);								
	} 
	
	
	
	
	

	/************************
	 *   Copy/Move methods
	 ************************/
		
	
	
	/**
	 * Generate the XML String for this mod
	 * @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) {
			NoneSelectedResourceException e = new NoneSelectedResourceException();

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

			throw e;			
		}		
		else {
			
			// we check if we are authorized to copy all selected resources			
			String tempPath = currentSpace.getPath();
			for (int j=0;j<files.length;j++){
				String fileName = files[j];
				if (!this.currentSpace.getServerAccessObject().canRead(fileName, tempPath)) {
					// we erase the clipboard					
					buffer.setClipboard(null);
					buffer.setClipboardParameter(null);
					buffer.setClipboardPath(null);
					buffer.setClipboardSpace(null);
					
					// we throw an exception
					NotAuthorizedException e = new NotAuthorizedException();

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

					throw e;					
				}
			}
			
			// if none NotAuthorizedException throwed
			
			// files/directories to copy			
			buffer.setClipboard(new Vector());
			buffer.setClipboardPath(currentSpace.getPath());
			buffer.setClipboardSpace(this.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.getPath());
		}
		catch (PasteDeletedResourceException e) {
			buffer.setClipboard(null);
			buffer.setClipboardParameter(null);
			buffer.setClipboardPath(null);
			buffer.setClipboardSpace(null);
			
			// log
			if (log.isDebugEnabled()){
				log.debug("renderXmlConfirmPaste"+" :: "+e);
			}			
			
			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 = this.currentSpace.getServerAccessObject().isDirectory(fileName, buffer.getClipboardPath());								
						
			if (isDirectory) {	
					
				//check if non empty
				boolean empty = this.currentSpace.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 submit
		if (submit != 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.getPath());
				}
				else {

					// log
					if (log.isDebugEnabled()){
						log.debug("paste"+" :: move clipboardElement = "+clipboardElement);
					}

					this.currentSpace.getServerAccessObject().move(clipboardElement, clipboardSpace, clipboardPath, currentSpace.getKey(), currentSpace.getPath());
				}						
			}			
		}
		
		// if cancel
		else {
			CancelException e = new CancelException();

			// log
			if (log.isDebugEnabled()){
				log.debug("paste"+" :: CancelException");
			}
			
			throw e;			
		}				
		
		
		
		// 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", config, userPortalLogin, userGroups, directoryProperties);	
		}
		else {
			buffer.setClipboard(null);
			buffer.setClipboardParameter(null);
			buffer.setClipboardPath(null);
			buffer.setClipboardSpace(null);
			return DefaultRenderXml.getXml(spaces, currentSpace, null, "2006", config, userPortalLogin, userGroups, directoryProperties);	
		}
	}
	
	

	
	

	
	/************************
	 * Space admin methods
	 ************************/
	
	
	
	/**
	 * If we are creating a new Space
	 */
	private boolean creatingNewSpace = false;
	
	/**
	 * The name of the new space while creating
	 */
	private String creatingNewSpaceName = null;
	

	/**
	 * The vector used to add people when we use a servant channel
	 */
	private Vector userTypeForAdd;

	/**
	 * The name of user type for add: reader_group, ... ?
	 */
	private String userTypeForAddName;
	
	
	/**
	 * Return XML for the space administration mode 
	 * @param runtimeData
	 * @param staticData
	 * @param out
	 * @return XML for the space administration mode 
	 * @throws PortalException
	 * @throws ChannelException
	 */
	private StringBuffer renderXmlAdminSpace(ChannelRuntimeData runtimeData, ChannelStaticData staticData, ContentHandler out) throws PortalException, ChannelException {				
				
		try {
		
			// if change "public" or "not public"
			String pub = runtimeData.getParameter("change_public");
			
			if (pub!=null) {
				if (smp.isPublicReading())
					smp.setPublicReading(false);						
				else smp.setPublicReading(true);
			}
		
			// the SpaceManagementProperties object used here		
			if (smp == null) {
				
				smp = InjacSpaceManagementProperties.getProperties(config, currentSpace, currentSpace.getPath());
				
				if (creatingNewSpace==true) {
					if (this.currentSpace.getServerAccessObject().exists(creatingNewSpaceName, this.currentSpace.getPath())) {
						
						creatingNewSpaceName = null;
						smp = null;
						
						StillExistsException e = new StillExistsException();

						// log
						if (log.isDebugEnabled()){
							log.debug("renderXmlAdminSpace"+" :: "+e);
						}
						throw e;						
					}
					smp.setDescription("");
				}
			}
						
			// if we change the metadata file
			String metadataFile = runtimeData.getParameter("metadataFile");
			if (metadataFile!=null)
				return renderXmlAdminSpaceChangeMetadataFile(metadataFile);			
			
			// if we change the metadata file
			String renderingType = runtimeData.getParameter("renderingType");
			if (renderingType!=null)
				return renderXmlAdminSpaceChangeRenderType(renderingType);
				
			
			// if change the description
			String description = runtimeData.getParameter("description");
			if (description!=null) {
				smp.setDescription(description);
			}
					
			// if we click on "valid" or "cancel"
			String action = runtimeData.getParameter("action");
			
			if (action!=null) {
				if (action.equals("cancel"))
					return renderXmlAdminSpaceCancel();
				else if (action.equals("valid"))
					return renderXmlAdminSpaceValid(runtimeData);
				else return renderXmlAdminSpaceGenerateXml();
			}
		
			else {
			
				// if click on add
				String addButton = runtimeData.getParameter("add");
				if (addButton != null)
					return renderXmlAdminSpaceAdd(runtimeData, staticData, out);
			
				// if click on delete
				String deleteButton = runtimeData.getParameter("delete");
				if (deleteButton != null)
					return renderXmlAdminSpaceDelete(runtimeData);
			
				return renderXmlAdminSpaceGenerateXml();
			}
		}
		catch(ChannelException e) {			
			creatingNewSpaceName = null;
			smp = null;
			
			// log
			if (log.isDebugEnabled()){
				log.debug("renderXmlAdminSpace"+" :: "+e);
			}
			throw e;
		}
		catch(PortalException e) {			
			creatingNewSpaceName = null;
			smp = null;

			// log
			if (log.isDebugEnabled()){
				log.debug("renderXmlAdminSpace"+" :: "+e);
			}	
			throw e;
		}
	}
	
	
	
	
	/**
	 * When click on cancel
	 * @return the xml when we click on cancel
	 * @throws CancelException
	 */
	private StringBuffer renderXmlAdminSpaceCancel() throws CancelException {
		this.smp = null;
		this.creatingNewSpace = false;
		
		CancelException e = new CancelException();

		// log
		if (log.isDebugEnabled()){
			log.debug("renderXmlAdminSpaceCancel"+" :: "+e);
		}
		throw e;
	}
	
	
	
	/**
	 * When valid the properties
	 * @param runtimeData
	 * @return xml when we set the properties
	 * @throws ChannelException
	 */
	private StringBuffer renderXmlAdminSpaceValid(ChannelRuntimeData runtimeData) throws ChannelException {
		
		// to access the server
		ServerAccess access = this.currentSpace.getServerAccessObject();				
		
		// the resource path
		String path = this.currentSpace.getPath();
		
		// if we are creating a new Space
		if (creatingNewSpace) {
			// we create a directory and fix the metadata to it to know that it is a space			
			try {
				access.createDir(this.creatingNewSpaceName, path);				
				boolean wellDone = MetaDataManager.setDirectoryAsSpace(currentSpace, path+this.creatingNewSpaceName);				
				if (!wellDone) {
					access.delete(this.creatingNewSpaceName, path);
				}
			}
			catch(ServerException e) {
				this.smp = null;
				this.creatingNewSpace = false;

				// log
				if (log.isDebugEnabled()){
					log.debug("renderXmlAdminSpaceValid"+" :: "+e);
				}				
				throw new CreateDirectoryException();
			}
			catch(DeleteException e) {
				this.smp = null;
				this.creatingNewSpace = false;

				// log
				if (log.isDebugEnabled()){
					log.debug("renderXmlAdminSpaceValid"+" :: "+e);
				}
				throw new CreateDirectoryException();
			}
			catch(NotAuthorizedDeleteException e) {
				this.smp = null;
				this.creatingNewSpace = false;

				// log
				if (log.isDebugEnabled()){
					log.debug("renderXmlAdminSpaceValid"+" :: "+e);
				}
				throw new CreateDirectoryException();
			}
			
			path = this.currentSpace.getPath()+this.creatingNewSpaceName;			
		}			
		
		try {
			// set the metadata
			boolean wellDone = MetaDataManager.setMetadataOnSpace(currentSpace, path, smp);
		
			if (!wellDone) {
				this.smp = null;
				this.creatingNewSpace = false;
			
				ApplicationException e = new ApplicationException();

				// log
				if (log.isDebugEnabled()){
					log.debug("renderXmlAdminSpaceValid"+" :: "+e);
				}
				throw e;
			}
		
			// set the ACL
			InjacAclManager.setReadersAclOnSpace(this.currentSpace, path, smp);
							
			this.setCurrentDirectoryProperties();
			this.smp = null;
		
			// if space creation
			if (creatingNewSpace) {
				creatingNewSpace = false;
				stylesheet = new StringBuffer("CStockage");
				return DefaultRenderXml.getXml(spaces, currentSpace, null, "2009", config, userPortalLogin, userGroups, directoryProperties);
			}
		
			// if metadata modification
			else {
				this.creatingNewSpace = false;
				stylesheet = new StringBuffer("CStockage");
				return DefaultRenderXml.getXml(spaces, currentSpace, null, "2008", config, userPortalLogin, userGroups, directoryProperties);
			}
			
			
		}
		catch(ChannelException e) {
			this.smp = null;
			this.creatingNewSpace = false;

			// log
			if (log.isDebugEnabled()){
				log.debug("renderXmlAdminSpaceValid"+" :: "+e);
			}
			throw e;
		}
	}
	
	
	
	
	/**
	 * When we change the metadata file
	 * @param choice the metadata file choice
	 * @return the xml when changing metadata file
	 * @throws PropertiesException
	 */
	private StringBuffer renderXmlAdminSpaceChangeMetadataFile(String choice) throws PropertiesException {
		this.smp.setSelectedMetadataProfile(choice);
		return renderXmlAdminSpaceGenerateXml();
	}
	
	

	/**
	 * When we change the rendering type
	 * @param choice the rendering type choice
	 * @return the xml when changing render type
	 * @throws PropertiesException
	 */
	private StringBuffer renderXmlAdminSpaceChangeRenderType(String choice) throws PropertiesException {
		this.smp.setSelectedRenderingType(choice);
		return renderXmlAdminSpaceGenerateXml();
	}
	
	
	
	/**
	 * When we want to add a user or 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 renderXmlAdminSpaceAdd(ChannelRuntimeData runtimeData, ChannelStaticData staticData, ContentHandler out) throws PropertiesException, PortalException {		

		// the user type
		userTypeForAddName = runtimeData.getParameter("user_type");
		
		// check wich vector we have to use		
		if (userTypeForAddName.equals("reader_group"))
			userTypeForAdd = smp.getReaderGroups();
		else {
			if (userTypeForAddName.equals("reader_user"))
				userTypeForAdd = smp.getReaderUsers();
			else {
				if (userTypeForAddName.equals("writer_group"))
					userTypeForAdd = smp.getWriterGroups();
				else {
					if (userTypeForAddName.equals("writer_user"))
						userTypeForAdd = smp.getWriterUsers();
					else {
						if (userTypeForAddName.equals("editor_group"))
							userTypeForAdd = smp.getEditorGroups();
						else {
							if (userTypeForAddName.equals("editor_user"))
								userTypeForAdd = smp.getEditorUsers();
							else {
								if (userTypeForAddName.equals("manager_group"))
									userTypeForAdd = smp.getManagerGroups();
								else {
									if (userTypeForAddName.equals("manager_user"))
										userTypeForAdd = smp.getManagerUsers();									
								}
							}
						}
					}
				}
			}
		}
		 
		// check if we want to choice a group or a user
		if (userTypeForAddName.endsWith("group")) {		
			slave = CGroupsManagerServantFactory.getGroupsServantforSelection(staticData, null);
		}
		else {
			staticData.setParameter("returnServant", "multiple");
			slave = CAnnuaireServantFactory.getAnnuaireServant(staticData);
		}
		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 renderXmlAdminSpaceValidServantResults(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;
					
					User user = new User(pers, config);
				
					// if there still this user in the list
					if (!userTypeForAdd.contains(user)){
						userTypeForAdd.add(user);
					}
					
					// if user reader
					if (userTypeForAddName.equals("reader_user")) {
						
						if (smp.getDeletedReaderUsers().contains(user)) {
							smp.getDeletedReaderUsers().remove(user);
						}
						else smp.getAddedReaderUsers().add(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 {
							Group group = new Group(egi);
					
							// if there still this group in the list
							if (!userTypeForAdd.contains(group)){
								userTypeForAdd.add(group);
							}	

							// if group reader
							if (userTypeForAddName.equals("reader_group")) {
								
								if (smp.getDeletedReaderGroups().contains(group)) {
									smp.getDeletedReaderGroups().remove(group);
								}
								else smp.getAddedReaderGroups().add(group);
								
							}
						}
						catch(GroupsException e) {							
							log.error("renderXmlAdminSpaceValidServantResults"+" :: "+e);							
						}
					}
				}									
			}
		}
		
		slave = null;		
		staticData.setParameter("groupManagerFinished", "false");	
		return renderXmlAdminSpaceGenerateXml();
	}
	
	
	
	/**
	 * When we delete a user or a group
	 * @param runtimeData the runtime data object used in the channel
	 * @return the xml when we delete somebody
	 * @throws PropertiesException
	 */
	private StringBuffer renderXmlAdminSpaceDelete(ChannelRuntimeData runtimeData) throws PropertiesException {
		
		// the user type
		String userType = runtimeData.getParameter("user_type");
		
		// the selection
		String[] selection = null;		
		if (userType.endsWith("group"))
			selection = runtimeData.getParameterValues("groupsList");
		else selection = runtimeData.getParameterValues("usersList");
		
		// if none selected
		if (selection==null || selection.length==0)
			return renderXmlAdminSpaceGenerateXml();
		
		// check wich vector we have to use
		Vector vector = null;
		if (userType.equals("reader_group")) {
			vector = smp.getReaderGroups();			
		}
		else {
			if (userType.equals("reader_user")) {
				vector = smp.getReaderUsers();		
			}
			else {
				if (userType.equals("writer_group"))
					vector = smp.getWriterGroups();
				else {
					if (userType.equals("writer_user"))
						vector = smp.getWriterUsers();
					else {
						if (userType.equals("editor_group"))
							vector = smp.getEditorGroups();
						else {
							if (userType.equals("editor_user"))
								vector = smp.getEditorUsers();
							else {
								if (userType.equals("manager_group"))
									vector = smp.getManagerGroups();
								else {
									if (userType.equals("manager_user"))
										vector = smp.getManagerUsers();									
								}
							}
						}
					}
				}
			}
		}
		
		boolean canDelete = true;
		
		// can not delete all managers
		if (userType.equals("manager_group") || userType.equals("manager_user")) {
			Vector managerUsers = smp.getManagerUsers();
			Vector managerGroups = smp.getManagerGroups();
			int total = managerGroups.size()+managerUsers.size();
			
			if (total-selection.length <= 0)
				canDelete = false;
		}
		
		// delete
		if (canDelete) {
			for (int i=selection.length-1; i>=0; i--) {
				
				// the key
				String key = selection[i];
				
				// delete
				if (userType.endsWith("group")) {
					vector.remove(new Group(key, key));			
				}
				else {
					vector.remove(new User(key, key));
				}
				
				// if user reader
				if (userType.equals("reader_user")) {
					User u = new User(key, key);
					
					if (smp.getAddedReaderUsers().contains(u)) {
						smp.getAddedReaderUsers().remove(u);
					}
					else smp.getDeletedReaderUsers().add(u);
					
				}

				// if group reader
				if (userType.equals("reader_group")) {
					Group g = new Group(key, key);

					if (smp.getAddedReaderGroups().contains(g)) {
						smp.getAddedReaderGroups().remove(g);
					}
					else smp.getDeletedReaderGroups().add(g);
				}
				
			}
		}
		
		return renderXmlAdminSpaceGenerateXml();
	}
	
	
	
	/**
	 * Generate xml for the administration rendering
	 * @return the xml for the administration rendering
	 * @throws PropertiesException
	 */
	private StringBuffer renderXmlAdminSpaceGenerateXml() throws PropertiesException {

		// the xml generated
		String xml = "";		
		
		// the space name
		xml += "<space name=\"";
		for (int i=0; i<currentSpace.getPathSize(); i++) {			
			if (i!=0)
				xml += " > ";
			String n = currentSpace.getPathElementAt(i);			
			n = n.replaceAll("&","&amp;");
			n = n.replaceAll("\"","&#148;");			
			xml += (n);
		}
		
		if (this.creatingNewSpace) {
			xml += (" > ");
			String n = this.creatingNewSpaceName;
			n = n.replaceAll("&","&amp;");
			n = n.replaceAll("\"","&#148;");			
			xml += (n);
		}
		
		xml += ("\"/>");
		
		
		// generate the XML
		
		// description
		String description = smp.getDescription();
		xml += ("<description>");
		description = description.replaceAll("&","&amp;");
		description = description.replaceAll("\"","&#148;");
		xml += (description);
		xml += ("</description>");
		
		// metadata list
		ArrayList metadataProfiles = smp.getAvailableMetadataProfiles();
		String selectedProfile = smp.getSelectedMetadataProfile();
		xml += ("<metadata>");
		for (int i=0; i<metadataProfiles.size(); i++) {
			MetadataFileProfile mdp = (MetadataFileProfile)metadataProfiles.get(i);
			String label = mdp.getLabel();			
			if (selectedProfile.equals(mdp.getFileName()))
				xml += ("<md name=\""+mdp.getFileName()+"\" label=\""+label+"\" default=\"true\"   />");
			else xml += ("<md name=\""+mdp.getFileName()+"\" label=\""+label+"\" />");
		}		
		xml += ("</metadata>");
		
		// rendering type
		ArrayList renderingTypes = smp.getAvailableRenderingTypes();
		String selectedRenteringType = smp.getSelectedRenderingType();
		xml += ("<renderingType>");
		for (int i=0; i<renderingTypes.size(); i++) {
			RenderingType rt = (RenderingType)renderingTypes.get(i);
			if (selectedRenteringType.equals(rt.getUrl()))
				xml += ("<render name=\""+rt.getUrl()+"\" label=\""+rt.getLabel()+"\" default=\"true\"   />");
			else xml += ("<render name=\""+rt.getUrl()+"\" label=\""+rt.getLabel()+"\" />");
		}		
		xml += ("</renderingType>");
		
		// writers
		xml += ("<writer>");
		xml += ("<groups>");
		Vector writersGrp = smp.getWriterGroups();
		for (int i=0; i<writersGrp.size(); i++) {
			Group g = (Group)writersGrp.elementAt(i);
			xml += ("<group key=\""+g.getKey()+"\" name=\""+g.getDisplayName()+"\"/>");
		}
		xml += ("</groups>");
		xml += ("<users>");
		Vector writersUsr = smp.getWriterUsers();
		for (int i=0; i<writersUsr.size(); i++) {
			User u = (User)writersUsr.elementAt(i);
			xml += ("<user key=\""+u.getKey()+"\" name=\""+u.getDisplayName()+"\"/>");
		}
		xml += ("</users>");
		xml += ("</writer>");
		
		//editors
		xml += ("<editor>");
		xml += ("<groups>");
		Vector editorsGrp = smp.getEditorGroups();
		for (int i=0; i<editorsGrp.size(); i++) {
			Group g = (Group)editorsGrp.elementAt(i);
			xml += ("<group key=\""+g.getKey()+"\" name=\""+g.getDisplayName()+"\"/>");
		}
		xml += ("</groups>");
		xml += ("<users>");
		Vector editorsUsr = smp.getEditorUsers();
		for (int i=0; i<editorsUsr.size(); i++) {
			User u = (User)editorsUsr.elementAt(i);
			xml += ("<user key=\""+u.getKey()+"\" name=\""+u.getDisplayName()+"\"/>");
		}
		xml += ("</users>");
		xml += ("</editor>");
		
		//managers
		xml += ("<manager>");
		xml += ("<groups>");
		Vector managersGrp = smp.getManagerGroups();
		for (int i=0; i<managersGrp.size(); i++) {
			Group g = (Group)managersGrp.elementAt(i);
			xml += ("<group key=\""+g.getKey()+"\" name=\""+g.getDisplayName()+"\"/>");
		}
		xml += ("</groups>");
		xml += ("<users>");
		Vector managersUsr = smp.getManagerUsers();
		for (int i=0; i<managersUsr.size(); i++) {
			User u = (User)managersUsr.elementAt(i);
			xml += ("<user key=\""+u.getKey()+"\" name=\""+u.getDisplayName()+"\"/>");
		}		
		xml += ("</users>");
		xml += ("</manager>");
		
		
		// readers
		boolean pub = smp.isPublicReading();
		xml += ("<reader public=\""+pub+"\">");
		//if (!pub) {
			xml += ("<groups>");
			Vector readersGrp = smp.getReaderGroups();
			for (int i=0; i<readersGrp.size(); i++) {
				Group g = (Group)readersGrp.elementAt(i);
				xml += ("<group key=\""+g.getKey()+"\" name=\""+g.getDisplayName()+"\"/>");
			}
			xml += ("</groups>");
			xml += ("<users>");
			Vector readersUsr = smp.getReaderUsers();
			for (int i=0; i<readersUsr.size(); i++) {
				User u = (User)readersUsr.elementAt(i);
				xml += ("<user key=\""+u.getKey()+"\" name=\""+u.getDisplayName()+"\"/>");
			}			
			xml += "</users>";			
		//}
		xml += ("</reader>");
		
		
		
		
		StringBuffer sb = new StringBuffer(xml);
		
		return sb;
	}
	
	
	
	/**
	 * Generate the xml for the creating space mod
	 * @param runtimeData the runtime data channel object
	 * @param staticData the static data channel object
	 * @param out the object used for the rendering
	 * @return the xml for the creating space mod
	 * @throws ChannelException
	 * @throws PortalException
	 */	
	private StringBuffer createSpace(ChannelRuntimeData runtimeData, ChannelStaticData staticData, ContentHandler out) throws ChannelException, PortalException {
		String submit = runtimeData.getParameter("Submit_create");
		String cancel = runtimeData.getParameter("Cancel_create");
		
		if (submit == null) {
			CancelException e = new CancelException();

			// log
			if (log.isDebugEnabled()){
				log.debug("createSpace"+" :: "+e);
			}
			throw e;
		} 
		
		else {
			
			// we are creating a new space
			this.creatingNewSpace = true;
			
			// the new space name
			this.creatingNewSpaceName = runtimeData.getParameter("spaceName");
			
			// if name is well formed
			boolean wellFormed = ResourceControl.isWellFormed(creatingNewSpaceName);
        	if ( !wellFormed ) {
        		this.creatingNewSpace = false;

    			// log
    			if (log.isDebugEnabled()){
    				log.debug("createSpace"+" :: "+creatingNewSpaceName+" not well formed");
    			}
            	throw new BadFormatException();
        	}
			
        	stylesheet = new StringBuffer("adminSpace");
        	return renderXmlAdminSpace(runtimeData, staticData, out);
        	        	
		}
	}


	
	
	
	
}







