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.InputStream;
019
020import org.apache.avalon.framework.component.Component;
021import org.apache.avalon.framework.configuration.Configurable;
022import org.apache.avalon.framework.configuration.Configuration;
023import org.apache.avalon.framework.configuration.ConfigurationException;
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.avalon.framework.service.Serviceable;
027import org.apache.excalibur.source.Source;
028import org.apache.excalibur.source.SourceResolver;
029
030import org.ametys.runtime.i18n.I18nizableText;
031import org.ametys.runtime.plugin.component.AbstractLogEnabled;
032import org.ametys.runtime.plugin.component.PluginAware;
033
034import com.opensymphony.workflow.loader.WorkflowDescriptor;
035import com.opensymphony.workflow.loader.WorkflowLoader;
036
037/**
038 * Object to describe a workflow.
039 */
040public class WorkflowDefinition extends AbstractLogEnabled implements Component, Serviceable, Configurable, PluginAware
041{
042    /** The source resolver */
043    protected SourceResolver _srcResolver;
044    
045    private String _location;
046    private I18nizableText _label;
047    private WorkflowDescriptor _descriptor;
048    private String _id;
049    private String _pluginName;
050    
051    public void service(ServiceManager manager) throws ServiceException
052    {
053        _srcResolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
054    }
055    
056    public void configure(Configuration configuration) throws ConfigurationException
057    {
058        _location = configuration.getChild("file").getValue();
059        
060        String defaultCatalog = "plugin." + _pluginName;
061        I18nizableText defaultValue = new I18nizableText(defaultCatalog, "WORKFLOW_" + _id.replace("-", "_").toUpperCase());
062        _label = I18nizableText.parseI18nizableText(configuration.getChild("label"), defaultCatalog, defaultValue);
063        // Lazy loaded
064        _descriptor = null;
065    }
066    
067    public void setPluginInfo(String pluginName, String featureName, String id)
068    {
069        _id = id;
070        _pluginName = pluginName;
071    }
072    
073    /**
074     * Get the workflow label.
075     * @return The workflow label, default is plugin.[pluginName]:WORKFLOW_[workflowNameUpperCased]
076     */
077    public I18nizableText getLabel()
078    {
079        return _label;
080    }
081    
082    /**
083     * Get the location of the workflow file.
084     * @return the location of the workflow file
085     */
086    public String getLocation()
087    {
088        return _location;
089    }
090    
091    /**
092     * Get or load the workflow descriptor.
093     * @param validate if the descriptor has to be valid
094     * @return the workflow descriptor
095     * @throws Exception if an error occurs
096     */
097    public WorkflowDescriptor getDescriptor(boolean validate) throws Exception
098    {
099        if (_descriptor == null)
100        {
101            getLogger().debug("Loading '{}' for the workflow '{}'.", _location, _id);
102            
103            Source source = null;
104            
105            try
106            {
107                source = _srcResolver.resolveURI(_location);
108                try (InputStream is = source.getInputStream())
109                {
110                    _descriptor = WorkflowLoader.load(is, validate);
111                }
112            }
113            finally
114            {
115                if (source != null)
116                {
117                    _srcResolver.release(source);
118                }
119            }
120            
121            _descriptor.setName(_id);
122        }
123        
124        return _descriptor;
125    }
126}