/*
 * Copyright (C) 2005-2010 Alfresco Software Limited.
 *
 * This file is part of Alfresco
 *
 * Alfresco is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Alfresco 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Alfresco. If not, see 
Run a server-side script against the target node(s).
 * 
 * @author gkspencer
 */
public class JavaScriptDesktopAction extends DesktopAction {
	// 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
	{		
		File scriptFile = new File(m_scriptPath);
		
		synchronized (this)
        {
            if (scriptFile.lastModified() != m_lastModified)
            {
                // Reload the script
                m_lastModified = scriptFile.lastModified();
                try
                {
                    loadScript(scriptFile);
                }
                catch (IOException ex)
                {
                    // Check if the script file has been changed
                    return new DesktopResponse(StsError, "Failed to reload script file, " + getScriptName());
                }
            }
        }
			
		// Access the script service
		final ScriptService scriptService = getServiceRegistry().getScriptService();
		
		if ( scriptService != null)
		{
	        // Create the objects to be passed to the script
			
            final Map