/* * Copyright (C) 2005-2007 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * As a special exception to the terms and conditions of version 2.0 of * the GPL, you may redistribute this Program in connection with Free/Libre * and Open Source Software ("FLOSS") applications as described in Alfresco's * FLOSS exception. You should have recieved a copy of the text describing * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ package org.alfresco.filesys.repo.desk; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; import org.alfresco.config.ConfigElement; import org.alfresco.filesys.alfresco.AlfrescoContext; import org.alfresco.filesys.alfresco.AlfrescoDiskDriver; import org.alfresco.filesys.alfresco.DesktopAction; import org.alfresco.filesys.alfresco.DesktopActionException; import org.alfresco.filesys.alfresco.DesktopParams; import org.alfresco.filesys.alfresco.DesktopResponse; import org.alfresco.jlan.server.filesys.DiskSharedDevice; import org.alfresco.scripts.ScriptException; import org.alfresco.service.cmr.repository.ScriptService; import org.alfresco.util.ResourceFinder; import org.springframework.core.io.Resource; /** * Javascript Desktop Action Class * *
Run a server-side script against the target node(s).
 * 
 * @author gkspencer
 */
public class JavaScriptDesktopAction extends DesktopAction {
	// Script service
	
	private ScriptService m_scriptService;
	
	// Script name
	
	private String m_scriptName;
	
	// Script file details
	
	private String m_scriptPath;
	private long m_lastModified;
	
	// Script string
	
	private String m_script;
	
	/**
	 * Class constructor
	 */
	public JavaScriptDesktopAction()
	{
		super( 0, 0);
	}
	/**
	 * Return the confirmation string to be displayed by the client
	 * 
	 * @return String
	 */
	@Override
	public String getConfirmationString()
	{
		return "Run Javascript action";
	}
    /**
     * Perform standard desktop action initialization
     * 
     * @param global ConfigElement
     * @param config ConfigElement
     * @param fileSys DiskSharedDevice
     * @exception DesktopActionException
     */
    @Override
    public void standardInitialize(ConfigElement global, ConfigElement config, DiskSharedDevice fileSys)
        throws DesktopActionException
    {
		// Perform standard initialization
		super.standardInitialize(global, config, fileSys);
		
		// Get the script file name and check that it exists
		
		ConfigElement elem = config.getChild("script");
		if ( elem != null && elem.getValue().length() > 0)
		{
			// Set the script name
			setScriptName(elem.getValue());
		}
		else
			throw new DesktopActionException("Script name not specified");
		
		// check if the desktop action attributes have been specified
		
		elem = config.getChild("attributes");
		if ( elem != null)
		{
			// Check if the attribute string is empty
			
			if ( elem.getValue().length() == 0)
				throw new DesktopActionException("Empty desktop action attributes");
			
			// Parse the attribute string
			setAttributeList(elem.getValue());
		}
		
		// Check if the desktop action pre-processing options have been specified
		
		elem = config.getChild("preprocess");
		if ( elem != null)
		{
		    setPreprocess(elem.getValue());
		}
	}
	@Override
    public void initializeAction(AlfrescoDiskDriver filesysDriver, AlfrescoContext filesysContext)
            throws DesktopActionException
    {
        // Perform standard initialization
	    super.initializeAction(filesysDriver, filesysContext);
        
        // Get the script file name and check that it exists
        
        if ( m_scriptName == null || m_scriptName.length() == 0)
        {
            throw new DesktopActionException("Script name not specified");
        }
        // Check if the script exists on the classpath
        Resource resource = new ResourceFinder().getResource(m_scriptName);
        if (!resource.exists())
        {
            throw new DesktopActionException("Failed to find script on classpath, " + getScriptName());
        }
        // Check that the script file exists
        File scriptFile;
        try
        {
            scriptFile = resource.getFile();
            if (scriptFile.exists() == false)
                throw new DesktopActionException("Script file not found, " + m_scriptName);
        }
        catch (IOException e)
        {
            throw new DesktopActionException("Unable to resolve script as a file, " + resource.getDescription());
        }
        
        m_scriptPath = scriptFile.getAbsolutePath();
        m_lastModified =scriptFile.lastModified();
        
        // Load the script
        try
        {
            loadScript( scriptFile);
        }
        catch ( IOException ex)
        {
            throw new DesktopActionException( "Failed to load script, " + ex.getMessage());
        }
    }
    /**
	 * Run the desktop action
	 * 
	 * @param params DesktopParams
	 * @return DesktopResponse 
	 */
	@Override
	public DesktopResponse runAction(DesktopParams params)
		throws DesktopActionException
	{
		// Check if the script file has been changed
		
		DesktopResponse response = new DesktopResponse(StsSuccess);
		
		File scriptFile = new File(m_scriptPath);
		if ( scriptFile.lastModified() != m_lastModified)
		{
			// Reload the script
			m_lastModified = scriptFile.lastModified();
			
			try
			{
				loadScript( scriptFile);
			}
			catch ( IOException ex)
			{
				response.setStatus(StsError, "Failed to reload script file, " + getScriptName());
				return response;
			}
		}
			
		// Start a transaction
		
		params.getDriver().beginWriteTransaction( params.getSession());
		// Access the script service
		
		if ( getScriptService() != null)
		{
			// Create the objects to be passed to the script
			
            Map