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


import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.esupportail.portal.channels.CStockage.channelAction.AbstractChannelAction;
import org.esupportail.portal.channels.CStockage.channelAction.BufferAction;
import org.esupportail.portal.channels.CStockage.channelAction.classic.sharing.SharedSpaceProperties;
import org.esupportail.portal.channels.CStockage.exception.ApplicationException;
import org.esupportail.portal.channels.CStockage.exception.BadConnexionParameters;
import org.esupportail.portal.channels.CStockage.exception.PropertiesException;
import org.esupportail.portal.channels.CStockage.exception.ServerException;
import org.esupportail.portal.channels.CStockage.exception.ChannelException;
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.UserForPersonalization;
import org.jasig.portal.security.IPerson;

/**
 * Id: Space.java,v 1.0 9 juil. 2004<br/>
 * Copyright (c) 2004 Esup Portail (www.esup-portail.org)<br/>
 * Classes: Space<br/>
 * Original Author: Yohan Colmant<br/>
 * This represents a file space on the server<br/>
 */
public class Space {


	/**
	 * Logger object
	 */
	protected static final Log log = LogFactory.getLog(Space.class);
	
	
	/**
	 * The server object for this space
	 */
	private Server server;
	
	
	
	/**
	 * The space key
	 */
	private String key;
	
	/**
	 * The label of this space
	 */
	private String label;

	/**
	 * The path in the initial configuration file
	 */
	private String initialPathFromTheConfigurationFile;

	/**
	 * The regexp used to apply on the path
	 */
	private String pathRegexp;

	/**
	 * The separator used when the regexp is in few parts
	 */
	private String pathRegexpSeparator;

	/**
	 * The currentPath used
	 */
	private Vector currentPath = new Vector();
	
	/**
	 * The channel action type
	 */
	private String actionType;
	
	
	
	/**
	 * The class name used to manage the actions
	 */
	private String channelActionClass;		

	

	/**
	 * The namespace used for the metadata
	 */
	private String metadataNamespace;
	
	
	
	
	/**
	 * If the administrator allow users to share documents
	 */
	private String sharing;
	
	/**
	 * The attribute used to access the server
	 */
	private ServerAccess access;
	
	/**
	 * To manage the actions in funtion of the access class
	 */
	private AbstractChannelAction channelAction;
	
	
	
	
	/**
	 * The authorization list for this space
	 */
	private ArrayList authorizations = new ArrayList();
	
	
	
	
	
	/**
	 * If this space is a personnal one
	 */
	private boolean personnalSpace = false;
	
	
	/**
	 * The target for the sharing: the user key or the group key
	 */
	private SharedSpaceProperties currentViewer;
	

	/**
	 * The sharing directory properties of the current space
	 */
	private DirectorySharingProperties targetsOfSharing;
	
	/**
	 * The owner of the space
	 */
	private UserForPersonalization owner;
	

	/**
	 * The group for the acl security
	 */
	private String aclSecurity;
	
	
	
	
	

	/**
	 * @return Returns the aclSecurity.
	 */
	public String getAclSecurity() {
		
		if (aclSecurity==null) {
			if (log.isDebugEnabled()) {
				log.debug("getAclSecurity"+" :: getAclSecurity is null");
			}
		}
		return aclSecurity;
	}
	/**
	 * @param aclSecurity The aclSecurity to set.
	 */
	public void setAclSecurity(String aclSecurity) {
		this.aclSecurity = aclSecurity;
	}
	
	
	
	/**
	 * @return Returns the currentViewer.
	 */
	public SharedSpaceProperties getCurrentViewer() {
		return currentViewer;
	}
	/**
	 * @param currentViewer The targetOfsharing to set.
	 */
	public void setCurrentViewer(SharedSpaceProperties currentViewer) {
		this.currentViewer = currentViewer;
	}
	
	
	
	
	
	/**
	 * @return Returns the owner.
	 */
	public UserForPersonalization getOwner() {
		return owner;
	}
	/**
	 * @param owner The owner to set.
	 */
	public void setOwner(UserForPersonalization owner) {
		this.owner = owner;
	}
	
	
	/**
	 * Init the privileges of the current user. If he can read, write, write-acl ??
	 *
	 */
	public void initCurrentUserPrivileges() {
		
		String currentPath = getCurrentPath();
		//System.out.print("passe par initCurrentUserPrivileges: "+currentPath+" ");
		/*System.out.print("1: "+getCurrentViewer());
		System.out.print("2: "+getCurrentViewer().getUser());
		System.out.print("3: "+getCurrentViewer().getUser().getPersonalization());*/
		boolean[] userPrivileges = getServerAccessObject().checkPrivileges(currentPath);
		//System.out.println(userPrivileges[0]+" "+userPrivileges[1]+" "+userPrivileges[2]);
		if (userPrivileges[0])
			getCurrentViewer().getUser().getPersonalization().setReading(1);
		if (userPrivileges[1])
			getCurrentViewer().getUser().getPersonalization().setWriting(1);
		if (userPrivileges[2])
		getCurrentViewer().getUser().getPersonalization().setSharing(1);
	}
	
	
	/**
	 * @return Returns the targetsOfSharing.
	 */
	public DirectorySharingProperties getTargetsOfSharing() {
		return targetsOfSharing;
	}
	/**
	 * @param targetsOfSharing The targetsOfSharing to set.
	 */
	public void setTargetsOfSharing(DirectorySharingProperties targetsOfSharing) {
		this.targetsOfSharing = targetsOfSharing;
	}
	
	
	
	/**
	 * @return Returns the server.
	 */
	public Server getServer() {
		return server;
	}
	/**
	 * @param server The server to set.
	 */
	public void setServer(Server server) {
		this.server = server;
	}
	


	
	/**
	 * @return Returns the metadataNamespace.
	 */
	public String getMetadataNamespace() {
		return metadataNamespace;
	}
	/**
	 * @param metadataNamespace The metadataNamespace to set.
	 */
	public void setMetadataNamespace(String metadataNamespace) {
		this.metadataNamespace = metadataNamespace;
	}
	
	
	
	/**
	 * @return Returns the manageAcl.
	 */
	/*public boolean managesAcl() throws PropertiesException {		
		return server.managesAcl();
	}*/
	
	/**
	 * @param manageAcl The manageAcl to set.
	 */
	/*public void setManageAcl(String manageAcl) {
		if (manageAcl.equals("true"))
			this.manageAcl = true;
		else this.manageAcl = false;
	}*/
	
	
	/**
	 * return the authorization list
	 * @return the authorization list
	 */
	public ArrayList getAuthorization() {			
		return authorizations;
	}

	/**
	 * add a new authorization to the list
	 * @param authorization the authorization to add
	 */
	public void setAuthorization(AuthorizationSpaceParameter authorization) {		
		// add this authorization
		authorizations.add(authorization);
	}
	
	

	
	
	/**
	 * @return Returns the cifsDisablePlainTextPassword.
	 */
	public String getCifsDisablePlainTextPassword() {
		return server.getCifsDisablePlainTextPassword();
	}
	
	/**
	 * @return Returns the cifsDomain.
	 */
	public String getCifsDomain() {
		return server.getCifsDomain();
	}
	
	/**
	 * @return Returns the cifsResolveOrder.
	 */
	public String getCifsResolveOrder() {
		return server.getCifsResolveOrder();
	}
	/**
	 * @return Returns the cifsEncoding.
	 */
	public String getCifsUseUnicode() {
		return server.getCifsUseUnicode();
	}
	/**
	 * @return Returns the cifsEncoding.
	 */
	public String getCifsEncoding() {
		return server.getCifsEncoding();
	}
	/**
	 * @return Returns the actionType.
	 */
	public String getActionType() {
		return actionType;
	}
	/**
	 * @param actionType The actionType to set.
	 */
	public void setActionType(String actionType) {
		this.actionType = actionType;
	}
	/**
	 * @return Returns the serverType.
	 */
	public String getServerType() {
		return server.getServerType();
	}
	
	/**
	 * @return Returns the aclUportalGroup.
	 */
	public String getAclUportalGroup() {
		return server.getAclUportalGroup();
	}
	/**
	 * @return Returns the aclUserPrefix.
	 */
	public String getAclUserPrefix() {
		return server.getAclUserPrefix();
	}
	/**
	 * @return Returns the aclGroupPrefix.
	 */
	public String getAclGroupPrefix() {
		return server.getAclGroupPrefix();
	}
	
	/**
	 * @return Returns the aclNamespace.
	 */
	public String getAclNamespace() {
		return server.getAclNamespace();
	}
	
	
	
	
	/**
	 * @return Returns the personnalSpace.
	 */
	public boolean isPersonnalSpace() {
		return personnalSpace;
	}
	/**
	 * @param personnalSpace The personnalSpace to set.
	 */
	public void setPersonnalSpace(boolean personnalSpace) {
		this.personnalSpace = personnalSpace;
	}
	
	/**
	 * If the selected authentication is CAS
	 * @return trus is cas is selected
	 */
	public boolean isCasAuthentication() throws PropertiesException {
		return server.isCasAuthentication();
	}
	/**
	 * If the selected authentication is TRUSTED
	 * @return true if trusted is selected
	 */
	public boolean isTrustedAuthentication() throws PropertiesException {
		return server.isTrustedAuthentication();
	}
	/**
	 * If the selected authentication is ASKED
	 * @return true if asked is selected
	 */
	public boolean isAskedAuthentication() throws PropertiesException {
		return server.isAskedAuthentication();
	}
	

	/**
	 * @return Returns the login.
	 */
	public String getLogin() {
		return server.getLogin();
	}
	/**
	 * @param login The login to set.
	 */
	public void setLogin(String login) {
		server.setLogin(login);
	}
	
	
	/**
	 * @return Returns the loginIsFromConfigurationFile.
	 */
	public boolean isLoginIsFromConfigurationFile() {
		return server.isLoginIsFromConfigurationFile();
	}
	
	/**
	 * @return Returns the initialLoginFromTheConfigurationFile.
	 */
	public String getInitialLoginFromTheConfigurationFile() {
		return server.getInitialLoginFromTheConfigurationFile();
	}
	
	
	/**
	 * @return Returns the password.
	 */
	public String getPassword() throws PropertiesException {
		return server.getPassword();
	}
	/**
	 * @param password The trustedPassword to set.
	 */
	public void setPassword(String password) {
		server.setPassword(password);
	}
	/**
	 * @return Returns the url.
	 */
	public String getUrl() throws PropertiesException {
		return server.getUrl();
	}
	
	/**
	 * @return Returns the authenticationMode.
	 */
	public String getAuthenticationMode() {
		return server.getAuthenticationMode();
	}
	
	/**
	 * @return Returns the serverAccessClass.
	 */
	/*public String getServerAccessClass() {
		return serverAccessClass;
	}*/
	/**
	 * @param serverAccessClass The serverAccessClass to set.
	 */
	public void setServerAccessClass(String serverAccessClass) {
		server.setServerAccessClass(serverAccessClass);
	}
	
	

	/**
	 * @return Returns the accessClass.
	 */
	public String getChannelActionClass() {
		return channelActionClass;
	}
	/**
	 * @param channelActionClass The channelActionClass to set.
	 */
	public void setChannelActionClass(String channelActionClass) {
		this.channelActionClass = channelActionClass;
	}
	
	
	
	/**
	 * @return Returns the key.
	 */
	public String getKey() {
		return key;
	}
	
	/**
	 * @param key The key to set.
	 */
	public void setKey(String key) {
		this.key = key;
	}
	
	/**
	 * @return Returns the label.
	 */
	public String getLabel() {
		return label;
	}
	
	/**
	 * @param label The label to set.
	 */
	public void setLabel(String label) {
		this.label = label;
	}
	
	
	
	
	
	/**
	 * @return Returns the pathRegexp.
	 */
	public String getPathRegexp() {
		return pathRegexp;
	}
	/**
	 * @param pathRegexp The pathRegexp to set.
	 */
	public void setPathRegexp(String pathRegexp) {
		this.pathRegexp = pathRegexp;
	}
	/**
	 * @return Returns the pathRegexpSeparator.
	 */
	public String getPathRegexpSeparator() {
		return pathRegexpSeparator;
	}
	/**
	 * @param pathRegexpSeparator The pathRegexpSeparator to set.
	 */
	public void setPathRegexpSeparator(String pathRegexpSeparator) {
		this.pathRegexpSeparator = pathRegexpSeparator;
	}
	
	
	
	/**
	 * @param path The path to set.
	 */
	public void setPath(String path) {
		
		this.initialPathFromTheConfigurationFile = path;
		
		// set the vector
		currentPath = initPath(path);
	}

	
	
	/**
	 * @param path The path to set.
	 */
	private Vector initPath(String path) {
		
		// set the vector
		Vector currentPath = new Vector();		
		
		String initPath = new String(path);		
		if (initPath.startsWith("/"))
			initPath = initPath.substring(1, initPath.length());		
		if (initPath.endsWith("/"))
			initPath = initPath.substring(0, initPath.length()-1);
				
		// we add it to the currentPath
		currentPath.addElement(initPath);	
		
		return currentPath;
	}
	
	
	
	/**
	 * @return Returns the path.
	 */
	public String getCurrentPath() {	
		return getPath(currentPath);				
	}
	
	
	
	/**
	 * @return Returns the parent path until the space root
	 */
	public String getParentPathUntilSpaceRoot() {	
		int size = this.getPathSize();
		if (size == 1)
			return null;
		else
			return getParentPath(currentPath);				
	}
	
	/**
	 * @return Returns the space root path
	 */
	public String getSpaceRootPath() {	
		return (String)this.currentPath.elementAt(0);		
	}

	
	
	
	/**
	 * @return Returns the parent path.
	 */
	public String getParentPath() {	
		String path = getCurrentPath();
		String[] p = path.split("/");
		String s = "";
		
		// if we are at the root
		if (path.trim().equals("/")) {
			return null;
		}
		
		// if we are not at the root
		for (int i=0; i<p.length-1; i++) {
			s+=p[i]+"/";
		}
		
		return s;	
	}

	

	/**
	 * Get the path from an initial path, without first and last slashes
	 * @param path the path to transform
	 * @return the path without first and last slashes
	 */
	public static String getPathWithoutFirstAndLastSlash(String path) {
		String s = null;
		
		// if the path starts with "/"
		if (path.startsWith("/")) {
			s = path.substring(1);
		}
		else {
			s = path;
		}
		
		// if the path ends with "/"		
		if (s.endsWith("/")) {
			s = s.substring(0, s.length()-1);
		}
		
		return s;
	}
	
	
	
	/**
	 * @return Returns the path.
	 */
	public String getPath() {	
		return this.initialPathFromTheConfigurationFile;				
	}
	
	
	/**
	 * Return the path due to a current path vector
	 * @param currentPath
	 * @return the space current path
	 */
	private String getParentPath(Vector currentPath) {
		StringBuffer pathh = new StringBuffer("/"); 
		for (int i=0; i<currentPath.size()-1; i++) {
			String s = (String)currentPath.elementAt(i);
			if (!s.equals("")) {
				pathh.append(s);
				pathh.append("/");
			}			
		}
		
		return pathh.toString();	
	}
	
	/**
	 * Return the path due to a current path vector
	 * @param currentPath
	 * @return the space current path
	 */
	private String getPath(Vector currentPath) {
		StringBuffer pathh = new StringBuffer("/"); 
		for (int i=0; i<currentPath.size(); i++) {
			String s = (String)currentPath.elementAt(i);
			if (!s.equals("")) {
				pathh.append(s);
				pathh.append("/");
			}			
		}
		
		return pathh.toString();	
	}
	
	
	
	
	
	/**
	 * We check if the is a {...} form in the path. If yes, we replace by the real value
	 * @param person the connected person
	 */
	public void checkPath(IPerson person) {
		 
		String formLoginAttribute = "storageFormLogin";
		
		// if there are {} in the initial path, for each element between {}, we replace by the real value
		String path = "";
		String[] tab = initialPathFromTheConfigurationFile.split("\\{");
		for (int i=0; i<tab.length; i++) {
			String s = tab[i];
			int index = s.indexOf("}");
			
			// if there is a "}"
			if (index==-1) {
				path = path+s;
			}
			
			// there is no "}"
			else {
				String attributeName = s.substring(0, index);
				String endOfString = s.substring(index+1, s.length());
				
				// replace the attribute
				String value = "";
				if (attributeName.equals(formLoginAttribute)) {
					value = getLogin();
				}
				else {
					value = (String)person.getAttribute(attributeName);
				}
				
				// add the attribute value
				path = path+value;
				
				// add the end of the string
				path = path+endOfString;
			}
		}
		
		
		// we check if the path is a regular expression
		if (pathRegexp!=null) {
			
			String[] regexps = null;
			if (pathRegexpSeparator!=null) {
				regexps = pathRegexp.split(pathRegexpSeparator);
			}
			else {
				regexps = new String[1];
				regexps[0] = pathRegexp;
			}
			
			StringBuffer result = new StringBuffer();
			
 			for (int i = 0; i < regexps.length; i++) {
				
				Pattern p = Pattern.compile(regexps[i], Pattern.CASE_INSENSITIVE);
				Matcher m = p.matcher(path);
				
				result.append(m.replaceAll("$1"));				
			}
			
			path = result.toString();
			//pathRegexp = null;
			//pathRegexpSeparator = null;
		}
		
		
		// we fix the currentPath vector
		currentPath = initPath(path);		
		
		// log
		if (log.isDebugEnabled()) {
			log.debug("checkPath"+" :: currentPath = "+currentPath);
		}
 	}
	
	
	
	/**
	 * Delete the regexp
	 *
	 */
	public void clearRegexp() {
		pathRegexp = null;
		pathRegexpSeparator = null;
	}
	
	
	
	/**
	 * we look for a {...} form in the attribute. If yes, we replace it with the real value
	 * @param attributeName to check 
	 * @param person uPortal person object
	 */
	public void checkAttribute(String attributeName, IPerson person) {
		server.checkAttribute(attributeName, person);
	}
	
	
	
	/**
	 * Add a path element to the current directory
	 * @param pathElement
	 */
	public void addPathElement(String pathElement) {
		this.currentPath.add(pathElement);
	}
	
	/**
	 * Remove an element from the current path
	 * @param index
	 */
	public void removePathElement(int index) {
		this.currentPath.remove(index);
	}
	
	/**
	 * Return the path size
	 * @return the size
	 */
	public int getPathSize() {
		return currentPath.size();
	}
	
	
	/**
	 * Check if we are at the root of the space
	 * @return true if we are at the root, else false
	 */
	public boolean isCurrentPathAtRoot() {
		return getPathSize()==1;
	}
	
		
	/**
	 * Return the current element path at the good index
	 * @param index the selected index
	 * @return a string
	 */
	public String getPathElementAt(int index) {
		if (index == 0)
			return this.label;
		else return (String)this.currentPath.elementAt(index);
	}
		
	
	/**
	 * Check if we are authorized to read this space
	 * @param access the object used to access the server
	 * @return true if authorized else false
	 */
	public boolean canRead(ServerAccess access) {
		try {
			if (access.canRead(this.getCurrentPath()))
				return true;
			else return false;
		}
		catch(ChannelException e) {
			return false;
		}
	}		
	
	
	/**
	 * Set the server access object for this space
	 * @return true if we can access this space, else false
	 * @throws ClassNotFoundException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws MalformedURLException
	 * @throws ApplicationException
	 * @throws PropertiesException
	 */
	public boolean setServerAccessObject() throws PropertiesException, ClassNotFoundException, InstantiationException, IllegalAccessException, MalformedURLException, ApplicationException{
		
		if (server.getServerAccessClass()==null) {
			log.error("setServerAccessObject :: "+getLabel()+" wrong server type for space "+getKey());
			return false;
		}
		
		// construct the object
		Class c = Class.forName(server.getServerAccessClass());
		access = (ServerAccess)c.newInstance();
		
		if (log.isDebugEnabled()) {
			log.debug("setServerAccessObject :: before access.init");
		}
		//System.out.println("avant init");
		access.init(this);
		if (log.isDebugEnabled()) {
			log.debug("setServerAccessObject :: after access.init");
		}
		//System.out.println("apres init");
		// add the current server hierarchy path
		//String serverCurrentHierPath = access.getServerCurrentHierPath();		
		//setPath(serverCurrentHierPath);
		
		
		// if the authentication is "asked", we don't try to connect
		if (isAskedAuthentication())
			return true;
		
		// try to connect
		try {
			//System.out.println("avant connect");
			if (log.isDebugEnabled()) {
				log.debug("setServerAccessObject :: before access.connect");
			}
			access.connect();			
			//System.out.println("apres connect");
			if (log.isDebugEnabled()) {
				log.debug("setServerAccessObject :: after access.connect");
			}
		}
		catch(ServerException e) {			
			//e.printStackTrace();
			// log
			if (log.isDebugEnabled()){
				log.debug("setServerAccessObject"+" :: "+getLabel()+" "+e);
			}
			
			return false;
		}
		catch(BadConnexionParameters e) {
			//e.printStackTrace();
			// log
			if (log.isDebugEnabled()){
				log.debug("setServerAccessObject"+" :: "+getLabel()+" "+e);
			}
			
			return false;
		}
		
		// if it is valid
		boolean valid = access.canRead(getCurrentPath());
		if (log.isDebugEnabled()) {
			log.debug("setServerAccessObject :: valid="+valid);
		}
		
		
		// disconnect
		try {
			access.disconnect();			
		}
		catch(ServerException e) {

			// log
			if (log.isDebugEnabled()){
				log.debug("setServerAccessObject"+" :: "+getLabel()+" "+e);
			}
			
		}
		
		return valid;
	}
	
	
	
	/**
	 * Return the object used to access the server
	 * @return the object used to access the server
	 */
	public ServerAccess getServerAccessObject() {
		return this.access;
	}
	
	
	
	/**
	 * init the server access object for this space
	 * @param person the uportal person object
	 * @throws MalformedURLException
	 * @throws PropertiesException
	 */
	public void initServerAccessObject(IPerson person) throws MalformedURLException, PropertiesException {
		server.initServerAccessObjectForEachSpace(person);
	}
	
	
	
	
	
	/**
	 * Set the object used to manage the actions of the channel
	 * @param person the uPortal person object
	 * @param spaces 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
	 * @return true if well done
	 * @throws ChannelException
	 */
	public boolean setChannelActionObject(IPerson person, ArrayList spaces, BufferAction buffer, String userPortalLogin, Vector userGroups)  {
		
		try {
			
			if (this.channelActionClass==null)
				this.channelActionClass = "org.esupportail.portal.channels.CStockage.channelAction.classic.ChannelAction";				
			
			Class classe = Class.forName(this.channelActionClass);
			Object obj = classe.newInstance();
			
			this.channelAction = (AbstractChannelAction)obj;
			
			if (log.isDebugEnabled()) {
				log.debug("setChannelActionObject"+" :: before this.channelAction.init");
			}
			this.channelAction.init(person, this, spaces, buffer, userPortalLogin, userGroups);
			if (log.isDebugEnabled()) {
				log.debug("setChannelActionObject"+" :: after this.channelAction.init");
			}
		}
		catch(ClassNotFoundException e) {
			log.error("setChannelActionObject"+" :: "+e);			
			return false;
		}
		catch(IllegalAccessException e) {
			log.error("setChannelActionObject"+" :: "+e);	
			return false;
		}
		catch(InstantiationException e) {
			log.error("setChannelActionObject"+" :: "+e);	
			return false;
		}
		return true;
	}
	
	
	
	/**
	 * Get the channel action object
	 * @return the channel action object
	 */
	public AbstractChannelAction getChannelActionObject() {
		return this.channelAction;
	}
	
	
	
	

	/**
	 * @return Returns the nfsGidNumber.
	 */
	public String getNfsGidNumber() {
		return server.getNfsGidNumber();
	}
	
	/**
	 * @return Returns the nfsUidNumber.
	 */
	public String getNfsUidNumber() {
		return server.getNfsUidNumber();
	}
	
	
	/**
	 * @return check if the space allow the personalization
	 */
	public boolean managesAcl() throws PropertiesException {		

		// check if the server allows personalization
		if (server.managesAcl() && getAclSecurity()!=null && !getAclSecurity().trim().equals("")) {
			return true;
		}
		else return false;
	}
	
	
	
	/**
	 * @return Returns the sharing.
	 */
	/*public boolean isSharing() throws PropertiesException {
		if (ChannelConfiguration.getInstance().isSpacesPersonalization()) {
			if (!personnalSpace) {
				
				// check if there are each aclxxx attribute and if type is webdav
				if (allowSharing !=null && allowSharing.equals("true")) {
					
					if (managesAcl()) {
						return true;
					}
					else return false;
					
				}
				else return false;
			}
			else {
				return currentViewer.isSharing();
			}
		}
		else {
			return false;
		}
	}*/
	public boolean allowsSharing() throws PropertiesException {
		
		// check if we have allowSharing="true"
		if (sharing !=null && sharing.equals("true")) {
			
			// check if the server allows personalization
			if (server.allowsPersonalization() && getAclSecurity()!=null && !getAclSecurity().trim().equals("")) {
				
				// check if the current user can write ACLs
				if (currentViewer!=null) {
					if (currentViewer.getUser().getPersonalization().getSharing()==1) {
						return true;
					}
				}
			}
		}
		return false;
	}
	
	public String getSharing() throws PropertiesException {
		if (sharing==null)
			return ""+false;
		else return sharing;
	}
	

	/**
	 * @param sharing The allowsSharing to set.
	 */
	public void setSharing(String sharing) {
		this.sharing = sharing;
	}
	/**
	 * @return Returns the enableSharing.
	 */
	/*public String getEnableSharing() {
		return enableSharing;
	}*/
	
	
	
	
	/**
	 * Return a String representation of this space
	 */
	public String toString() {
		return 
		"key: "+key+"\n"+
		"label: "+label+"\n"+
		"path: "+getCurrentPath()+"\n";
	}
	
	
	
	
	/**
	 * Compare this to another object
	 * @param o object to compare
	 */
	public boolean equals(Object o) {
		
		Space s = (Space)o;
		/*
		boolean thisIsPersonal = this.isPersonnalSpace();
		boolean sIsPersonal = s.isPersonnalSpace();
		
		if(thisIsPersonal && sIsPersonal) {
			return this.getIdInDatabase().equals(s.getIdInDatabase());
		}
		else {		
			return this.key.equals(((Space)o).getKey());
		}*/
		if (this.key == null) {
			if (s.key==null) {
				return true;
			}
			else {
				return false;
			}
		}
		else {
			if (s.key==null) {
				return false;
			}
			else {
				return this.key.equals(s.getKey());
			}
		}
		
	}
	
	
	
	
	
	/**
	 * Clone this object
	 * @return a clone of this object
	 */
	public Object cloneWithoutServer() {
		Space clone = new Space();

		if (this.getOwner()!=null)
			clone.setOwner((UserForPersonalization)this.getOwner().clone());
		
		clone.key = this.key;
		clone.label = this.label;
	
		clone.actionType = this.actionType;
		clone.channelActionClass = this.channelActionClass;
		
		clone.sharing = this.sharing;
		clone.aclSecurity = this.aclSecurity;
		
		clone.initialPathFromTheConfigurationFile = this.initialPathFromTheConfigurationFile;
		clone.pathRegexp = this.pathRegexp;
		clone.pathRegexpSeparator = this.pathRegexpSeparator;
		
		clone.currentPath = (Vector)this.currentPath.clone();
		
		clone.metadataNamespace = this.metadataNamespace;
		
		clone.authorizations = new ArrayList();
		for (int i=0; i<this.authorizations.size(); i++) {
			clone.authorizations.add(((AuthorizationSpaceParameter)this.authorizations.get(i)).clone());
		}
		
		clone.personnalSpace = this.personnalSpace;
		if (this.currentViewer!=null)
			clone.currentViewer = (SharedSpaceProperties)this.currentViewer.clone();
		
		if (this.targetsOfSharing != null)
			clone.targetsOfSharing = (DirectorySharingProperties)this.targetsOfSharing.clone();
		
		return clone;
	}
	

	
	/**
	 * Clone this object
	 * @return a clone of this object
	 */
	public Object clone() {
		Server originalServer = this.getServer();
		ArrayList originalSpaces = originalServer.getSpaces();
		
		int originalIndexOfThisInServer = -1;
		for (int i=0; originalIndexOfThisInServer==-1 && i<originalSpaces.size(); i++) {
			if (this==(Space)originalSpaces.get(i)) {
				originalIndexOfThisInServer = i;
			}
		}
		
		if (originalIndexOfThisInServer != -1) {
			Server clonedServer = (Server)originalServer.clone();
			Space clonedSpace = (Space)clonedServer.getSpaces().get(originalIndexOfThisInServer);
			
			return clonedSpace;
		}
		else {
			Server clonedServer = (Server)originalServer.clone();
			Space clonedSpace = (Space)cloneWithoutServer();
			clonedSpace.setServer(clonedServer);
			
			return clonedSpace;
		}
	}
	
	
	
	
	/**
	 * Get the xml in the configuration file style
	 * @return the xml in the configuration file style
	 */
	public StringBuffer getLocalXml() {
		

		StringBuffer xmlSpace = new StringBuffer();		
		xmlSpace.append("<SPACE");
	
		// key
		if (key!=null && !key.trim().equals("")) {
			xmlSpace.append(" key=\""+key+"\"\n");
		}
		
		// label
		if (label!=null && !label.trim().equals("")) {
			xmlSpace.append(" label=\""+label+"\"\n");
		}
		
		// path
		String path = getCurrentPath();
		if (path!=null && !path.trim().equals(""))
			xmlSpace.append(" path=\""+path+"\"\n");

		// pathRegexp
		if (pathRegexp!=null && !pathRegexp.trim().equals(""))
			xmlSpace.append(" pathRegexp=\""+pathRegexp+"\"\n");

		// pathRegexpSeparator
		if (pathRegexpSeparator!=null && !pathRegexpSeparator.trim().equals(""))
			xmlSpace.append(" pathRegexpSeparator=\""+pathRegexpSeparator+"\"\n");

		// actionType
		if (actionType!=null && !actionType.trim().equals(""))
			xmlSpace.append(" actionType=\""+actionType+"\"\n");

		// sharing
		if (sharing!=null && !sharing.trim().equals(""))
			xmlSpace.append(" sharing=\""+sharing+"\"\n");

		// aclSecurityGroup
		String aclSecurity = this.getAclSecurity();
		if (aclSecurity!=null && !aclSecurity.trim().equals(""))
			xmlSpace.append(" aclSecurity=\""+aclSecurity+"\"\n");
		
		xmlSpace.append("/>\n");	
		
		return xmlSpace;
		
	}
	
	
	

	/**
	 * Get the xml in the configuration file style
	 * @return the xml in the configuration file style
	 */
	public String getXml() {
		
		StringBuffer xmlSpace = new StringBuffer();		
		
		xmlSpace.append(this.server.getLocalXmlBegin());
		
		xmlSpace.append(this.getLocalXml());
		
		xmlSpace.append(this.server.getLocalXmlEnd());
			
		return xmlSpace.toString();
		
	}
}
