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

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.CStockage.channelAction.BufferAction;
import org.esupportail.portal.channels.CStockage.channelAction.injac.DirectoryProperties;
import org.esupportail.portal.channels.CStockage.channelAction.injac.ChannelAction;
import org.esupportail.portal.channels.CStockage.channelAction.injac.DefaultRenderXml;
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.channelAction.injac.metadata.parse.ParseRequiredMetaData;
import org.esupportail.portal.channels.CStockage.channelAction.injac.metadata.parse.RequiredMetaData;
import org.esupportail.portal.channels.CStockage.config.ChannelConfiguration;
import org.esupportail.portal.channels.CStockage.config.Space;
import org.esupportail.portal.channels.CStockage.exception.CancelException;
import org.esupportail.portal.channels.CStockage.exception.CopyException;
import org.esupportail.portal.channels.CStockage.exception.InjacDocumentException;
import org.esupportail.portal.channels.CStockage.exception.MetadataException;
import org.esupportail.portal.channels.CStockage.exception.NoneSelectedResourceException;
import org.esupportail.portal.channels.CStockage.exception.NotAuthorizedModifyMetadataException;
import org.esupportail.portal.channels.CStockage.exception.ServerException;
import org.esupportail.portal.channels.CStockage.exception.TooMuchSelectedException;
import org.esupportail.portal.channels.CStockage.exception.ChannelException;
import org.esupportail.portal.channels.CStockage.provider.access.ServerAccess;
import org.jasig.portal.ChannelRuntimeData;

/**
 * Id: MetadataManagerAction.java,v 1.0 27 oct. 2004
 * Copyright (c) 2004 Esup Portail (www.esup-portail.org)
 * Classes: MetadataManagerAction
 * Original Author: Yohan Colmant
 * Actions of the metadata management
 */
public class MetadataManagerAction {



	/**
	 * Logger object
	 */
	protected static final Log log = LogFactory.getLog(MetadataManagerAction.class);
	
	
	
	/**
	 * If we are editing a new document
	 */
	public final static String EDIT_NEW_DOC = "edit-new-doc";
	
	/**
	 * If we are re-editing an existing document
	 */
	public final static String EDIT_OLD_DOC = "edit-old-doc";
	
	/**
	 * If we are only setting metadata
	 */
	public final static String SET_METADATA = "set-metadata";
	
	
	

	/**
	 * If we are publishing a new document from another space
	 */
	public final static String PUBLISH_PERSONNAL_DOC = "publish-personnal-doc";
	
	/**
	 * If we are publishing a document wich have still been edited before
	 */
	public final static String PUBLISH_EDITED_DOC = "publish-edited-doc";
	
	

	/**
	 * If we are rejecting a document wich have still been edited before
	 */
	public final static String REJECT_DOC = "reject-doc";
	
	
	

	/**
	 * Generate the xml for the metadata management
	 * @param runtimeData the channel runtime data
	 * @param stylesheet the stylesheet used
	 * @param config the channel configuration file access object
	 * @param spaces the spaces list
	 * @param metadataToSet the metadata list to set
	 * @param userPortalLogin the user portal login
	 * @param userGroups the user portal groups
	 * @param currentSpace the current space
	 * @param directoryProperties the current directory properties
	 * @param buffer the buffer used for the clipboard
	 * @return the xml generation
	 * @throws ChannelException
	 */	
	public static StringBuffer renderXmlMetadataManager(ChannelRuntimeData runtimeData, StringBuffer stylesheet, ChannelConfiguration config, ArrayList spaces, ArrayList metadataToSet, String userPortalLogin, Vector userGroups, Space currentSpace, DirectoryProperties directoryProperties, BufferAction buffer) throws ChannelException{
		
		try {
			
			// the document in edition properties
			String documentName = runtimeData.getParameter("documentName");
			String documentPath = runtimeData.getParameter("documentPath");
			String actionType = runtimeData.getParameter("actionType");	


			// if it is the first call
			if (metadataToSet.isEmpty()) {
			
				// if no known document
				if (documentName==null) {
				
					// get the resource choosen
					String[] files = runtimeData.getParameterValues("listeFic");

					if (files == null) {
						NoneSelectedResourceException e = new NoneSelectedResourceException();

						// log
						if (log.isDebugEnabled()){
							log.debug("renderXmlMetadataManager"+" :: NoneSelectedResourceException ");
						}
						
						throw e;
					} 
					else {
						// if there is more than one file
						if (files.length > 1) {
							TooMuchSelectedException e = new TooMuchSelectedException();

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

					// the resource
					documentName = files[0];
					documentPath = currentSpace.getPath();
					actionType = SET_METADATA;
					String fullDocumentPath = documentPath + documentName;										
				}
				
				// set the metadata to set
				setMetadataToSet(runtimeData, metadataToSet, userPortalLogin, currentSpace, directoryProperties, documentName, documentPath, actionType);
			}

		
			
			// if click on ok
			String submit = runtimeData.getParameter("Submit_MD");
			if (submit != null) {
				return submitMetadataManager(runtimeData, stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties, documentName, documentPath, actionType, buffer);
			}

			// if click on cancel
			String cancel = runtimeData.getParameter("Cancel_MD");
			if (cancel != null) {
				metadataToSet.clear();
				CancelException e = new CancelException();

				// log
				if (log.isDebugEnabled()){
					log.debug("renderXmlMetadataManager"+" :: CancelException ");
				}
				
				throw e;
			}
			
			
			
			// generate the xml with the metadata list
			stylesheet.delete(0, stylesheet.length());
			stylesheet.append("documentMetaData");
			return generateXmlForMetadataSettings(metadataToSet, userPortalLogin, currentSpace, documentName, documentPath, actionType);	
		}
		catch(ChannelException e) {			
			metadataToSet.clear();			

			// log
			if (log.isDebugEnabled()){
				log.debug("renderXmlMetadataManager"+" :: ChannelException "+e);
			}
			
			throw e;
		}
		
	}
	
	
	
	
	/**
	 * Generate the xml and submit the metadata
	 * @param runtimeData the channel runtime data
	 * @param stylesheet the stylesheet used
	 * @param config the channel configuration file access object
	 * @param spaces the spaces list
	 * @param metadataToSet the metadata list to set
	 * @param userPortalLogin the user portal login
	 * @param userGroups the user portal groups
	 * @param currentSpace the current space
	 * @param directoryProperties the current directory properties
	 * @param documentName the name of the document we want to set metadata
	 * @param documentPath the path of the document we want to set metadata
	 * @param actionType the action type. For example EDIT_NEW_DOC, ....
	 * @param buffer the buffer used for the clipboard
	 * @return the xml generation
	 * @throws ChannelException
	 */	
	private static StringBuffer submitMetadataManager(ChannelRuntimeData runtimeData, StringBuffer stylesheet, ChannelConfiguration config, ArrayList spaces, ArrayList metadataToSet, String userPortalLogin, Vector userGroups, Space currentSpace, DirectoryProperties directoryProperties, String documentName, String documentPath, String actionType, BufferAction buffer) throws ChannelException {

		// we get each metadata
		for (int i = 0; i < metadataToSet.size(); i++) {
			RequiredMetaData metadata = (RequiredMetaData) metadataToSet.get(i);

			String metadataName = metadata.getName();
			String value = runtimeData.getParameter(metadataName);

			metadata.setValue(value);
		}

		// we check if all required metadata have been set
		boolean valid = true;
		for (int i = 0; valid && i < metadataToSet.size(); i++) {

			RequiredMetaData metadata = (RequiredMetaData) metadataToSet.get(i);
			if (!metadata.isValid() && metadata.isModifiable())
				valid = false;

		}

		// if set is ok
		if (valid) {

			String documentFullPath = currentSpace.getPath()+documentName;
			
			// if we are editing a document into the edition space
			if (actionType.equals(EDIT_NEW_DOC)) {
				
				ServerAccess access = currentSpace.getServerAccessObject();								

				// if the document is a file
				if (!buffer.getClipboardSpace().getServerAccessObject().isDirectory(documentName, documentPath)) {
						
					// we create a directory with the same name as the document
					String newDirectoryName = documentName;
					String newDirectoryPath = currentSpace.getPath();
					String newDirectoryFullPath = newDirectoryPath+newDirectoryName;
					
					boolean wellDone = true; 
					
					try {
						wellDone = access.createDir(newDirectoryName, newDirectoryPath);							
						
						// we put the document into the directory
						wellDone = wellDone && access.copy(newDirectoryName, buffer.getClipboardSpace(), documentPath, currentSpace.getKey(), newDirectoryFullPath+"/");							
						
						// we set the current user as the owner
						wellDone = wellDone && MetaDataManager.setUserAsDocumentOwner(currentSpace, newDirectoryFullPath, userPortalLogin);
					}
					catch(ChannelException e) {
						wellDone = false;
					}
					
					// we set metadata on document
					if (!wellDone) {
						access.delete(newDirectoryName, newDirectoryPath);
						CopyException e = new CopyException();

						// log
						if (log.isDebugEnabled()){
							log.debug("submitMetadataManager"+" :: CopyException "+e);
						}
						
						throw e;
					}
					else {														
						return editDocument(stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties, newDirectoryFullPath);
					}
				}
				
				// the document is a directory
				else {
										
					// we paste the document
					boolean wellDone = access.copy(documentName, buffer.getClipboardSpace(), documentPath, currentSpace.getKey(), currentSpace.getPath());
					
					// we set the current user as the owner
					wellDone = wellDone && MetaDataManager.setUserAsDocumentOwner(currentSpace, documentFullPath, userPortalLogin);
					
					// we set metadata on document
					if (!wellDone) {
						access.delete(documentName, documentPath);
						CopyException e = new CopyException();

						// log
						if (log.isDebugEnabled()){
							log.debug("submitMetadataManager"+" :: CopyException "+e);
						}
						
						throw e;
					}
					else {														
						return editDocument(stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties, documentFullPath);
					}
					
				}
				
			}


			// if we are changing metadata on an existing document
			else if (actionType.equals(SET_METADATA)) {
					return setMetadataOnDocument(stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties, documentFullPath);
			}
				
			// if we are editing an old document
			else if (actionType.equals(EDIT_OLD_DOC)) {					
				return editDocument(stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties, documentFullPath);
			}			
			

			// it'a a publication of an edited document
			else if (actionType.equals(PUBLISH_EDITED_DOC)) {					
				return publishDocument(stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties, documentFullPath);
			}
			

			// it'a a publication of a new document (we don't edit it)
			else if (actionType.equals(PUBLISH_PERSONNAL_DOC)) {
				ServerAccess access = currentSpace.getServerAccessObject();								

				// if the document is a file
				if (!buffer.getClipboardSpace().getServerAccessObject().isDirectory(documentName, documentPath)) {
						
					// we create a directory with the same name as the document
					String newDirectoryName = documentName;
					String newDirectoryPath = currentSpace.getPath();
					String newDirectoryFullPath = newDirectoryPath+newDirectoryName;
					
					boolean wellDone = access.createDir(newDirectoryName, newDirectoryPath);							
					
					// we put the document into the directory
					wellDone = wellDone && access.copy(newDirectoryName, buffer.getClipboardSpace(), documentPath, currentSpace.getKey(), newDirectoryFullPath+"/");							
					
					// we set the current user as the owner
					wellDone = wellDone && MetaDataManager.setUserAsDocumentOwner(currentSpace, newDirectoryFullPath, userPortalLogin);
					
					// we set metadata on document
					if (!wellDone) {
						CopyException e = new CopyException();

						// log
						if (log.isDebugEnabled()){
							log.debug("submitMetadataManager"+" :: CopyException "+e);
						}
						
						throw e;
					}
					else {														
						return publishDocument(stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties, newDirectoryFullPath);
					}
				}
				
				// the document is a directory
				else {
										
					// we paste the document
					boolean wellDone = access.copy(documentName, buffer.getClipboardSpace(), documentPath, currentSpace.getKey(), currentSpace.getPath());
					
					// we set the current user as the owner
					wellDone = wellDone && MetaDataManager.setUserAsDocumentOwner(currentSpace, documentFullPath, userPortalLogin);
					
					// we set metadata on document
					if (!wellDone) {
						CopyException e = new CopyException();

						// log
						if (log.isDebugEnabled()){
							log.debug("submitMetadataManager"+" :: CopyException "+e);
						}
						
						throw e;
					}
					else {														
						return publishDocument(stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties, documentFullPath);
					}
					
				}
				
			}
			

			// it'a a rejection of an edited document
			else if (actionType.equals(REJECT_DOC)) {				
				return rejectDocument(stylesheet, config, spaces, metadataToSet, userPortalLogin, userGroups, currentSpace, directoryProperties, documentFullPath);
			}
			
			
		}
		
		// generate the xml with the metadata list
		stylesheet.delete(0, stylesheet.length());
		stylesheet.append("documentMetaData");
		return generateXmlForMetadataSettings(metadataToSet, userPortalLogin, currentSpace, documentName, documentPath, actionType);	
	}
	
	
	
	
	
	/**
	 * Set the metadata list we want to set
	 * @param runtimeData the channel runtime data
	 * @param metadataToSet the metadata list to set
	 * @param userPortalLogin the user portal login
	 * @param currentSpace the current space
	 * @param directoryProperties the current directory properties
	 * @param documentName the name of the document we want to set metadata
	 * @param documentPath the path of the document we want to set metadata
	 * @param actionType the action type. For example EDIT_NEW_DOC, .... 
	 * @throws ChannelException
	 */	
	private static void setMetadataToSet(ChannelRuntimeData runtimeData, ArrayList metadataToSet, String userPortalLogin, Space currentSpace, DirectoryProperties directoryProperties, String documentName, String documentPath, String actionType) throws ChannelException {

		// to know the metadata to set
		ServerAccess access = currentSpace.getServerAccessObject();
		String spacePath = currentSpace.getPath();

		// get the metadata we have to set
		String xmlMetadataToSet = MetaDataManager.getMetadataSpaceProfile(currentSpace, spacePath);
		//System.out.println("metadata: "+metadataToSet);
		ParseRequiredMetaData parse = new ParseRequiredMetaData(xmlMetadataToSet);

		//boolean writerInSpace = directoryProperties.isUserWriter();
		boolean editorInSpace = directoryProperties.isUserEditor();
		
		// the document full path
		String fullDocumentPath = documentPath+documentName;		
	
		//boolean userIsOwnerOfDocument = directoryProperties.isUserWriter();//ChannelAction.isUserDocumentOwner(fullDocumentPath, access, userPortalLogin);
		boolean writer = false;
		if (actionType.equals(EDIT_NEW_DOC) || actionType.equals(PUBLISH_PERSONNAL_DOC)) {
			writer = directoryProperties.isUserWriter();
		}
		else {
			writer = ChannelAction.isUserDocumentOwner(fullDocumentPath, currentSpace, userPortalLogin);
		}
		
		// if writer in space and on document
		if (writer) {

			// if writer and editor
			if (editorInSpace) {
				metadataToSet.clear();
				ArrayList parseResult = parse.getMetadataListEditionAndPublication();
				for (int i=0; i<parseResult.size(); i++) {
					RequiredMetaData md = (RequiredMetaData)parseResult.get(i);										
					metadataToSet.add(md);
				}
			}

			// if only writer
			else {
				metadataToSet.clear();
				ArrayList parseResult = parse.getMetadataListEdition();
				for (int i=0; i<parseResult.size(); i++) {
					metadataToSet.add(parseResult.get(i));
				}
			}
		}

		else { 
			
			// if only editor
			if (editorInSpace) {
				metadataToSet.clear();
				ArrayList parseResult = parse.getMetadataListPublication();
				for (int i=0; i<parseResult.size(); i++) {
					metadataToSet.add(parseResult.get(i));
				}
			} 
			else {
				NotAuthorizedModifyMetadataException e = new NotAuthorizedModifyMetadataException();

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

		// if we are not editing a document, but changing metadata on an existing document
		if (actionType.equals(SET_METADATA)) {
			
			// check if this resource is an injac document			
			String type = MetaDataManager.getDirectoryType(currentSpace, fullDocumentPath);
			if (!type.equals(MetaDataConstants.INJAC_TYPE_DOCUMENT)) {				
				InjacDocumentException e = new InjacDocumentException();

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

			// if we are only writer on space, we check if we can access this document
			if (writer && !editorInSpace) {

				if (!writer) {
					
					NotAuthorizedModifyMetadataException e = new NotAuthorizedModifyMetadataException();

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

			}

			// if document state is published, we add the publication dates. if rejected, we add the reject cause
			String documentState = MetaDataManager.getDocumentState(currentSpace, fullDocumentPath);
			if (documentState.equals(MetaDataConstants.DOCUMENT_PUBLISHED_STATE) || documentState.equals(MetaDataConstants.DOCUMENT_EXPIRED_STATE)) {
				RequiredMetaData dateBegin = RequiredMetaData.getNewPublicationDateBeginMetatada();				
				RequiredMetaData dateEnd = RequiredMetaData.getNewPublicationDateEndMetatada();
				
				if (editorInSpace) {
					dateBegin.setModifiable(true);
					dateEnd.setModifiable(true);
				}
				else {
					dateBegin.setModifiable(false);
					dateEnd.setModifiable(false);
				}
				
				metadataToSet.add(dateBegin);
				metadataToSet.add(dateEnd);				
			}
			else if (documentState.equals(MetaDataConstants.DOCUMENT_REFUSED_STATE)) {
				RequiredMetaData reject = RequiredMetaData.getNewRejectCauseMetatada();
				
				if (editorInSpace) {
					reject.setModifiable(true);
					reject.setRequiredData(true);
				}
				else {
					reject.setModifiable(false);					
				}
				
				metadataToSet.add(reject);	
			}
			
			// we check if the document still has metadata set
			for (int i = 0; i < metadataToSet.size(); i++) {

				RequiredMetaData metadata = (RequiredMetaData) metadataToSet.get(i);								
				
				String metadataName = metadata.getName();
				String metadataValue = access.getProperty(currentSpace.getMetadataNamespace(), fullDocumentPath, metadataName);

				if (metadataValue==null)
					metadataValue="";												
				
				// if not modifiable and empty, we remove
				if (!metadata.isModifiable() && metadataValue.equals("")) {
					metadataToSet.remove(i);
					i--;					
				}
				else {				
					metadata.setValue(metadataValue);
				}
								
			}
		}
		
		
		// it'a an edition of an old document
		else if (actionType.equals(EDIT_OLD_DOC)) {									
			
			// we check if the document still has metadata set
			for (int i = 0; i < metadataToSet.size(); i++) {

				RequiredMetaData metadata = (RequiredMetaData) metadataToSet.get(i);
				
				String metadataName = metadata.getName();
				String metadataValue = access.getProperty(currentSpace.getMetadataNamespace(), fullDocumentPath, metadataName);
				
				// if not empty, we set the value
				if (metadataValue != null && !metadataValue.trim().equals("")) {
					metadata.setValue(metadataValue);
				}
				
				// if not modifiable, we remove this MD from the list 
				else if (!metadata.isModifiable()) {
					metadataToSet.remove(i);
					i--;					
				}				

			}
			
		}
		

		// it'a an edition of a new document
		else if (actionType.equals(EDIT_NEW_DOC)) {						
			
			// we set empty the values for the non modifiable metadata
			for (int i = 0; i < metadataToSet.size(); i++) {

				RequiredMetaData metadata = (RequiredMetaData) metadataToSet.get(i);
				
				// if not modifiable, we remove it from the list
				if (!metadata.isModifiable()) {
					metadataToSet.remove(i);
					i--;					
				}				

			}
			
		}
		
		
		

		// it'a a publication of an edited document
		else if (actionType.equals(PUBLISH_EDITED_DOC)) {				
			
			// we add the publication date MD 
			RequiredMetaData dateBegin = RequiredMetaData.getNewPublicationDateBeginMetatada();				
			RequiredMetaData dateEnd = RequiredMetaData.getNewPublicationDateEndMetatada();
			dateBegin.setModifiable(true);
			dateEnd.setModifiable(true);	
			metadataToSet.add(dateBegin);
			metadataToSet.add(dateEnd);	
			
			// we check if the document still has metadata set
			for (int i = 0; i < metadataToSet.size(); i++) {

				RequiredMetaData metadata = (RequiredMetaData) metadataToSet.get(i);
				
				String metadataName = metadata.getName();
				String metadataValue = access.getProperty(currentSpace.getMetadataNamespace(), fullDocumentPath, metadataName);
				
				// if not empty, we set the value
				if (metadataValue != null && !metadataValue.trim().equals("")) {
					metadata.setValue(metadataValue);
				}
				
				// if not modifiable, we remove this MD from the list 
				else if (!metadata.isModifiable()) {
					metadataToSet.remove(i);
					i--;					
				}
				
			}
			
		}
		

		// it'a a publication of a new document (we don't edit it)
		else if (actionType.equals(PUBLISH_PERSONNAL_DOC)) {							

			// we add the publication date MD 
			RequiredMetaData dateBegin = RequiredMetaData.getNewPublicationDateBeginMetatada();				
			RequiredMetaData dateEnd = RequiredMetaData.getNewPublicationDateEndMetatada();
			dateBegin.setModifiable(true);
			dateEnd.setModifiable(true);
			metadataToSet.add(dateBegin);
			metadataToSet.add(dateEnd);	
			
			// we set empty the values for the non modifiable metadata
			for (int i = 0; i < metadataToSet.size(); i++) {

				RequiredMetaData metadata = (RequiredMetaData) metadataToSet.get(i);
				
				// if not modifiable, we remove it from the list
				if (!metadata.isModifiable()) {
					metadataToSet.remove(i);
					i--;					
				}				
				
			}
			
		}
		
		


		// it'a a rejection of a document
		else if (actionType.equals(REJECT_DOC)) {							

			// we add the reject cause MD 
			RequiredMetaData reject = RequiredMetaData.getNewRejectCauseMetatada();
			reject.setModifiable(true);
			reject.setRequiredData(true);
			metadataToSet.add(reject);	
			
			// we check if the document still has metadata set
			for (int i = 0; i < metadataToSet.size(); i++) {

				RequiredMetaData metadata = (RequiredMetaData) metadataToSet.get(i);
				
				String metadataName = metadata.getName();
				String metadataValue = access.getProperty(currentSpace.getMetadataNamespace(), fullDocumentPath, metadataName);
				
				// if not empty, we set the value
				if (metadataValue != null && !metadataValue.trim().equals("")) {
					metadata.setValue(metadataValue);
				}
				
				// if not modifiable, we remove this MD from the list 
				else if (!metadata.isModifiable()) {
					metadataToSet.remove(i);
					i--;					
				}
				
			}
			
		}
		
		
	}
	
	
	
	
	/**
	 * Generate the xml for the metadata setting
	 * @param metadataToSet the metadata list to set
	 * @param userPortalLogin the user portal login
	 * @param currentSpace the current space
	 * @param documentName the name of the document we want to set metadata
	 * @param documentPath the path of the document we want to set metadata
	 * @param actionType the action type. For example EDIT_NEW_DOC, ....
	 * @return the xml generation
	 */	
	private static StringBuffer generateXmlForMetadataSettings(ArrayList metadataToSet, String userPortalLogin, Space currentSpace, String documentName, String documentPath, String actionType) {	
		StringBuffer xml = new StringBuffer();
		
		String documentName2 = documentName.replaceAll("&","&amp;");
		documentName2 = documentName2.replaceAll("\"","&#148;");
		String documentPath2 = documentPath.replaceAll("&","&amp;");
		documentPath2 = documentPath2.replaceAll("\"","&#148;");
		
		xml.append("<metas documentName=\""+documentName2+"\" documentPath=\""+documentPath2+"\" actionType=\""+actionType+"\" >");
		
		for (int i=0; i<metadataToSet.size(); i++) {
			
			try {
			
				StringBuffer xmlTemp = new StringBuffer();
			
				RequiredMetaData metadata = (RequiredMetaData)metadataToSet.get(i);
			
				// if modifiable
				if (metadata.isModifiable()) {				
				
					// the metadata
					xmlTemp.append("<meta ");
					
					// 	the attributes
					String name = metadata.getName();
					String label = metadata.getLabel();
					String input = metadata.getInput();					
					
					if (name == null || name.trim().equals("") || label == null || label.trim().equals("") || input == null || input.trim().equals("")) {
						Exception e = new Exception();

						// log
						if (log.isDebugEnabled()){
							log.debug("generateXmlForMetadataSettings"+" :: Exception "+e);
						}
						
						throw e;					
					}
					
					xmlTemp.append("name=\""+name+"\" ");
					xmlTemp.append("label=\""+label+"\" ");
					xmlTemp.append("required=\""+metadata.isRequired()+"\" ");
					xmlTemp.append("default-value=\""+metadata.getValue()+"\" ");
					xmlTemp.append("comment=\""+metadata.getComment()+"\" ");
					
					xmlTemp.append("modifiable=\"true\" ");
					
					xmlTemp.append("input=\""+input+"\" ");
					
					if (metadata.isValid())
						xmlTemp.append("good-format=\"true\" ");
					
					xmlTemp.append(">");
			
					// test input type
					if (input.equals(RequiredMetaData.INPUT_SELECT)) {
						
						String [] choiceListArray = metadata.getChoiceList();
						for (int j=0; j<choiceListArray.length; j++) {
							xmlTemp.append("<choice value=\""+choiceListArray[j]+"\" />");
						}
						
					}			
					
					// 	close
					xmlTemp.append("</meta>");	
					
					xml.append(xmlTemp);
				
				}
				
				// not modifiable
				else {
					

					// the metadata
					xmlTemp.append("<meta ");
					
					// 	the attributes
					String name = metadata.getName();
					String label = metadata.getLabel();
					String input = metadata.getInput();					
					
					if (name == null || name.trim().equals("") || label == null || label.trim().equals("") || input == null || input.trim().equals("")) {
						Exception e = new Exception();

						// log
						if (log.isDebugEnabled()){
							log.debug("generateXmlForMetadataSettings"+" :: Exception "+e);
						}
						
						throw e;					
					}
					
					// test input type
					if (input.equals(RequiredMetaData.INPUT_SELECT)) {						
						input = RequiredMetaData.INPUT_TEXT;						
					}
					
					xmlTemp.append("name=\""+name+"\" ");
					xmlTemp.append("label=\""+label+"\" ");
					xmlTemp.append("required=\""+metadata.isRequired()+"\" ");
					xmlTemp.append("default-value=\""+metadata.getValue()+"\" ");
					xmlTemp.append("comment=\""+metadata.getComment()+"\" ");
					
					xmlTemp.append("modifiable=\"false\" ");
					
					xmlTemp.append("input=\""+input+"\" ");
					
					xmlTemp.append("good-format=\"true\" ");
					
					xmlTemp.append(">");
			
								
					
					// 	close
					xmlTemp.append("</meta>");	
					
					xml.append(xmlTemp);
									
				}
				
				
			}
			catch(Exception e) {
				metadataToSet.remove(i);
				i--;
			}
						
		}
		
		xml.append("</metas>");
		
		return xml;
		
	}
	
	
	
	
	
	
	/**
	 * Set the metadata on document and return the xml for the next action
	 * @param stylesheet the stylesheet used
	 * @param config the channel configuration file access object
	 * @param spaces the spaces list
	 * @param metadataToSet the metadata list to set
	 * @param userPortalLogin the user portal login
	 * @param userGroups the user portal groups
	 * @param currentSpace the current space
	 * @param directoryProperties the current directory properties
	 * @param documentFullPath the full path of the document we want to set metadata
	 * @return the xml generation
	 * @throws ServerException
	 * @throws MetadataException
	 */	
	private static StringBuffer setMetadataOnDocument(StringBuffer stylesheet, ChannelConfiguration config, ArrayList spaces, ArrayList metadataToSet, String userPortalLogin, Vector userGroups, Space currentSpace, DirectoryProperties directoryProperties, String documentFullPath) throws ServerException, MetadataException {
		
		ServerAccess access = currentSpace.getServerAccessObject();
		
		// set the metadata on the document
		boolean wellDone = MetaDataManager.setMetadataOnDocument(currentSpace, documentFullPath, metadataToSet);
		
		if (!wellDone) {
			metadataToSet.clear();			
			MetadataException e = new MetadataException();

			// log
			if (log.isDebugEnabled()){
				log.debug("setMetadataOnDocument"+" :: MetadataException "+e);
			}
			
			throw e;
		}
		
		// return
		metadataToSet.clear();		
		stylesheet.delete(0, stylesheet.length());
		stylesheet.append("CStockage");
		return DefaultRenderXml.getXml(spaces, currentSpace, null, "2008", config, userPortalLogin, userGroups, directoryProperties);
	}
	
	
	
	

	/**
	 * Edit the document and return the xml for the next action
	 * @param stylesheet the stylesheet used
	 * @param config the channel configuration file access object
	 * @param spaces the spaces list
	 * @param metadataToSet the metadata list to set
	 * @param userPortalLogin the user portal login
	 * @param userGroups the user portal groups
	 * @param currentSpace the current space
	 * @param directoryProperties the current directory properties
	 * @param documentFullPath the full path of the document we want to set metadata
	 * @return the xml generation
	 * @throws ServerException
	 * @throws MetadataException
	 */
	private static StringBuffer editDocument(StringBuffer stylesheet, ChannelConfiguration config, ArrayList spaces, ArrayList metadataToSet, String userPortalLogin, Vector userGroups, Space currentSpace, DirectoryProperties directoryProperties, String documentFullPath) throws ServerException, MetadataException {
		
		ServerAccess access = currentSpace.getServerAccessObject();
		
		// set the metadata on the document
		boolean wellDone = MetaDataManager.setMetadataOnDocument(currentSpace, documentFullPath, metadataToSet);		
		wellDone = wellDone && MetaDataManager.setDirectoryAsWaitingDocument(currentSpace, documentFullPath);
		
		if (!wellDone) {
			metadataToSet.clear();		
			MetadataException e = new MetadataException();

			// log
			if (log.isDebugEnabled()){
				log.debug("editDocument"+" :: MetadataException "+e);
			}
			
			throw e;
		}
		
		// return
		metadataToSet.clear();
		stylesheet.delete(0, stylesheet.length());
		stylesheet.append("CStockage");
		return DefaultRenderXml.getXml(spaces, currentSpace, null, "2010", config, userPortalLogin, userGroups, directoryProperties);
	}
	

	

	/**
	 * Publish the document and return the xml for the next action
	 * @param stylesheet the stylesheet used
	 * @param config the channel configuration file access object
	 * @param spaces the spaces list
	 * @param metadataToSet the metadata list to set
	 * @param userPortalLogin the user portal login
	 * @param userGroups the user portal groups
	 * @param currentSpace the current space
	 * @param directoryProperties the current directory properties
	 * @param documentFullPath the full path of the document we want to set metadata
	 * @return the xml generation
	 * @throws ServerException
	 * @throws MetadataException
	 */
	private static StringBuffer publishDocument(StringBuffer stylesheet, ChannelConfiguration config, ArrayList spaces, ArrayList metadataToSet, String userPortalLogin, Vector userGroups, Space currentSpace, DirectoryProperties directoryProperties, String documentFullPath) throws ServerException, MetadataException { 
		
		ServerAccess access = currentSpace.getServerAccessObject();
		
		// set the metadata on the document
		boolean wellDone = MetaDataManager.setMetadataOnDocument(currentSpace, documentFullPath, metadataToSet);		
		wellDone = wellDone && MetaDataManager.setDirectoryAsPublishedDocument(currentSpace, documentFullPath);
		wellDone = wellDone && access.setProperty(currentSpace.getMetadataNamespace(), documentFullPath, MetaDataConstants.REJECT_CAUSE, "");
		
		if (!wellDone) {
			metadataToSet.clear();		
			MetadataException e = new MetadataException();

			// log
			if (log.isDebugEnabled()){
				log.debug("publishDocument"+" :: MetadataException "+e);
			}
			
			throw e;
		}
		
		// return
		metadataToSet.clear();
		stylesheet.delete(0, stylesheet.length());
		stylesheet.append("CStockage");
		return DefaultRenderXml.getXml(spaces, currentSpace, null, "2011", config, userPortalLogin, userGroups, directoryProperties);
	}
	
	
	

	
	/**
	 * Reject the document and return the xml for the next action
	 * @param stylesheet the stylesheet used
	 * @param config the channel configuration file access object
	 * @param spaces the spaces list
	 * @param metadataToSet the metadata list to set
	 * @param userPortalLogin the user portal login
	 * @param userGroups the user portal groups
	 * @param currentSpace the current space
	 * @param directoryProperties the current directory properties
	 * @param documentFullPath the full path of the document we want to set metadata
	 * @return the xml generation
	 * @throws ServerException
	 * @throws MetadataException
	 */
	private static StringBuffer rejectDocument(StringBuffer stylesheet, ChannelConfiguration config, ArrayList spaces, ArrayList metadataToSet, String userPortalLogin, Vector userGroups, Space currentSpace, DirectoryProperties directoryProperties, String documentFullPath) throws ServerException, MetadataException { 
		
		ServerAccess access = currentSpace.getServerAccessObject();
		
		// set the metadata on the document
		boolean wellDone = MetaDataManager.setMetadataOnDocument(currentSpace, documentFullPath, metadataToSet);		
		wellDone = wellDone && MetaDataManager.setDirectoryAsRejectedDocument(currentSpace, documentFullPath);
		wellDone = wellDone && access.setProperty(currentSpace.getMetadataNamespace(), documentFullPath, MetaDataConstants.PUBLICATION_DATE_BEGIN, "");
		wellDone = wellDone && access.setProperty(currentSpace.getMetadataNamespace(), documentFullPath, MetaDataConstants.PUBLICATION_DATE_END, "");
		
		if (!wellDone) {
			metadataToSet.clear();		
			MetadataException e = new MetadataException();

			// log
			if (log.isDebugEnabled()){
				log.debug("rejectDocument"+" :: MetadataException "+e);
			}
			
			throw e;
		}
		
		// return
		metadataToSet.clear();
		stylesheet.delete(0, stylesheet.length());
		stylesheet.append("CStockage");
		return DefaultRenderXml.getXml(spaces, currentSpace, null, "2012", config, userPortalLogin, userGroups, directoryProperties);
	}
	
	
	
}
