org.springmodules.workflow.osworkflow.configuration.ConfigurationBean.java Source code

Java tutorial

Introduction

Here is the source code for org.springmodules.workflow.osworkflow.configuration.ConfigurationBean.java

Source

/*
 * Copyright 2002-2005 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springmodules.workflow.osworkflow.configuration;

import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.FatalBeanException;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.util.Assert;
import org.xml.sax.SAXException;

import com.opensymphony.workflow.FactoryException;
import com.opensymphony.workflow.InvalidWorkflowDescriptorException;
import com.opensymphony.workflow.StoreException;
import com.opensymphony.workflow.config.DefaultConfiguration;
import com.opensymphony.workflow.loader.WorkflowDescriptor;
import com.opensymphony.workflow.loader.WorkflowLoader;
import com.opensymphony.workflow.spi.WorkflowStore;
import com.opensymphony.workflow.spi.memory.MemoryWorkflowStore;

/**
 * Supports Spring-style configuration of OSWorkflow resources. <p/> Workflow
 * descriptor resources are configured through the
 * <code>workflowLocations</code> property. This property accepts a
 * <code>Properties</code> instance and treats the key of each entry as the
 * workflow name and the value as the resource path. All standard Spring
 * resource paths are supported including <code>classpath:</code> style
 * resources. <p/> By default <code>MemoryWorkflowStore</code> is used as the
 * persistence class. However it is possible to use an already configured
 * <code>WorkflowStore</code> by calling #setWorkflowStore. <p/>
 * 
 * @author Rob Harrop
 */
public class ConfigurationBean extends DefaultConfiguration implements ResourceLoaderAware {
    /**
     * <code>Log</code> instance for this class.
     */
    private static final Log logger = LogFactory.getLog(ConfigurationBean.class);

    /**
     * Spring <code>ResourceLoader</code> used to load workflow
     * <code>Resource</code>s.
     * 
     */
    protected ResourceLoader resourceLoader = new DefaultResourceLoader();

    /**
     * Stores any arguments that are to be passed to
     */
    private Map persistenceArgs = new HashMap();

    /**
     * Stores loaded workflows
     */
    private Map workflows = new HashMap();

    /**
     * Indicates whether this instance is initialized or not
     */
    private boolean initialized;

    /**
     * User defined store - can be null.
     */
    private WorkflowStore workflowStore;

    /**
     * Creates a new <code>ConfigurationBean</code> with
     * <code>MemoryWorkflowStore</code> as the persistence class.
     */
    public ConfigurationBean() {
        setPersistence(MemoryWorkflowStore.class.getName());
    }

    /**
     * Gets the <code>Map</code> of arguments to be passed to the persistence
     * object
     */
    public Map getPersistenceArgs() {
        return this.persistenceArgs;
    }

    /**
     * Sets the arguments to be passed to the persistence object.
     */
    public void setPersistenceArgs(Map persistenceArgs) {
        Assert.notEmpty(persistenceArgs, "persistenceArgs cannot be null or empty");
        this.persistenceArgs = persistenceArgs;
    }

    /**
     * Sets the locations of the workflow definition files as a
     * <code>Properties</code> instance. The key of each entry corresponds to
     * the logical name for the workflow definition and the value of each entry
     * is the location of the definition file. <p/> Locations are specified as
     * Spring-style resource paths and classpath: resources are fully supported.
     */
    public void setWorkflowLocations(Properties workflowLocations) {
        Assert.notNull(workflowLocations, "workflowLocations cannot be null");

        Enumeration workflowNames = workflowLocations.propertyNames();
        while (workflowNames.hasMoreElements()) {
            String name = (String) workflowNames.nextElement();
            String resourceLocation = workflowLocations.getProperty(name);

            if (logger.isInfoEnabled()) {
                logger.info("Loading workflow [" + name + "] from [" + resourceLocation + "].");
            }

            workflows.put(name, loadWorkflowDescriptor(resourceLocation, name));
        }

        this.initialized = true;
    }

    /**
     * Gets a <code>WorkflowDescriptor</code> by name.
     */
    public WorkflowDescriptor getWorkflow(String name) throws FactoryException {
        WorkflowDescriptor wd = (WorkflowDescriptor) this.workflows.get(name);

        if (wd == null) {
            throw new FactoryException("Unknown workflow name [" + name + "].");
        }

        return wd;
    }

    /**
     * Gets the names of all configured workflows.
     */
    public String[] getWorkflowNames() throws FactoryException {
        Set names = this.workflows.keySet();
        return (String[]) names.toArray(new String[names.size()]);
    }

    /**
     * Indicates whether this instance has been initialized or not.
     */
    public boolean isInitialized() {
        return this.initialized;
    }

    /**
     * Unsupported operation.
     */
    public boolean removeWorkflow(String string) throws FactoryException {
        throw new UnsupportedOperationException("Operation removeWorkflow(String) not supported.");
    }

    /**
     * Loads a <code>WorkflowDescriptor</code> from the specified location
     * using the <code>WorkflowLoader</code> class.
     */
    protected WorkflowDescriptor loadWorkflowDescriptor(String resourceLocation, String name) {
        Resource resource = this.resourceLoader.getResource(resourceLocation);
        WorkflowDescriptor workflowDescriptor = null;
        try {
            workflowDescriptor = this.invokeLoader(resource);
        } catch (IOException ex) {
            throw new FatalBeanException("Unable to load workflow resource [" + resourceLocation + "].", ex);
        } catch (InvalidWorkflowDescriptorException ex) {
            throw new FatalBeanException(
                    "Descriptor for workflow [" + name + "] in [" + resourceLocation + "] is invalid.", ex);
        } catch (SAXException ex) {
            throw new FatalBeanException(
                    "XML in descriptorfor workflow [" + name + "] in [" + resourceLocation + "] is invalid.", ex);
        }
        return workflowDescriptor;
    }

    /**
     * Hook which allows subclasses to invoke the approapriate/available method
     * on the WorkflowLoader since between 2.7 and 2.8 the method signatures
     * changed.
     * 
     * @see com.opensymphony.workflow.loader.WorkflowLoader#load(java.io.InputStream)
     * 
     * @param resource resource to load
     * @throws WorkflowLoader.load exceptions
     * @return loaded workflow descriptor
     */
    protected WorkflowDescriptor invokeLoader(Resource resource)
            throws IOException, SAXException, InvalidWorkflowDescriptorException {
        // oswf 2.8 version
        // return WorkflowLoader.load(resource.getURL(), true);

        // the method exists in both 2.7 and 2.8(deprecated)
        return WorkflowLoader.load(resource.getInputStream());
    }

    /**
     * @see com.opensymphony.workflow.config.DefaultConfiguration#getWorkflowStore()
     */
    public WorkflowStore getWorkflowStore() throws StoreException {
        // default behavior
        if (workflowStore == null)
            return super.getWorkflowStore();
        return workflowStore;
    }

    /**
     * @param workflowStore The workflowStore to set.
     */
    public void setWorkflowStore(WorkflowStore workflowStore) {
        this.workflowStore = workflowStore;
    }

    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

}