001/*
002 *  Copyright 2021 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.workflow.definition;
017
018import java.io.File;
019
020import org.apache.avalon.framework.configuration.ConfigurationException;
021import org.apache.avalon.framework.configuration.DefaultConfiguration;
022import org.apache.avalon.framework.service.ServiceException;
023import org.apache.avalon.framework.service.ServiceManager;
024
025import org.ametys.plugins.workflow.support.WorkflowHelper;
026import org.ametys.runtime.plugin.Feature;
027import org.ametys.runtime.plugin.Plugin;
028import org.ametys.runtime.plugin.component.AbstractThreadSafeComponentExtensionPoint;
029
030/**
031 * The {@link WorkflowDefinition} extension point to list all available workflows.
032 */
033public class WorkflowDefinitionExtensionPoint extends AbstractThreadSafeComponentExtensionPoint<WorkflowDefinition>
034{
035    /** The Avalon role */
036    public static final String ROLE = WorkflowDefinitionExtensionPoint.class.getName();
037    
038    /** The workflow helper */
039    protected WorkflowHelper _workflowHelper;
040    
041    @Override
042    public void service(ServiceManager manager) throws ServiceException
043    {
044        super.service(manager);
045        _workflowHelper = (WorkflowHelper) manager.lookup(WorkflowHelper.ROLE);
046    }
047    
048    @Override
049    public void initializeExtensions() throws Exception
050    {
051        /* Add custom workflow found in WEB-INF/param/workflows and ignore those which are already defined in the kernel */
052        
053        // List workflow files
054        File[] workflowFiles = _workflowHelper.getParamWorkflowDir().listFiles((file, name) -> name.endsWith(".xml"));
055
056        if (workflowFiles != null)
057        {
058            for (File workflowFile : workflowFiles)
059            {
060                String workflowId = _getWorkflowIdFromFilename(workflowFile.getName());
061                
062                // If the workflow definition is not already declared, add it to known extensions
063                if (!hasExtension(workflowId))
064                {
065                    _addNewExtension(workflowId);
066                }
067            }
068        }
069        
070    }
071    
072    private void _addNewExtension(String workflowId) throws ConfigurationException
073    {
074        DefaultConfiguration extensionConf = new DefaultConfiguration("extension");
075        extensionConf.setAttribute("class", AutomaticWorkflowDefinition.class.getName());
076        
077        // Set null to the configuration because the configuration is get into the method
078        addExtension(workflowId, Plugin.DEFAULT_NAME, Feature.DEFAULT_NAME, extensionConf);
079    }
080    
081    /**
082     * Add a workflow to the workflow definition extension point
083     * @param workflowId id of workflow
084     * @throws ConfigurationException exception while trying to configure workflow 
085     */
086    public void addOrUpdateExtension(String workflowId) throws ConfigurationException
087    {
088        if (!hasExtension(workflowId))
089        {
090            // If the workflow definition is not already declared, add it to known extensions
091            _addNewExtension(workflowId);
092        }
093        else
094        {
095            // Otherwise, force the workflow reloading
096            getExtension(workflowId).reset();
097        }
098    }
099    
100    /**
101     * Get the workflow ID from the workflow filename.
102     * @param filename The workflow filename
103     * @return the workflow ID
104     */
105    protected String _getWorkflowIdFromFilename(String filename)
106    {
107        return filename.substring(0, filename.lastIndexOf('.'));
108    }
109}