Package org.apache.lenya.workflow.impl

Source Code of org.apache.lenya.workflow.impl.WorkflowBuilder

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You 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.
*
*/

/* $Id: WorkflowBuilder.java 565260 2007-08-13 07:55:41Z nettings $  */

package org.apache.lenya.workflow.impl;

import java.io.File;

import org.apache.avalon.framework.container.ContainerUtil;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.lenya.workflow.Condition;
import org.apache.lenya.workflow.Workflow;
import org.apache.lenya.workflow.WorkflowException;
import org.apache.lenya.xml.DocumentHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
* Utility class to build a workflow schema from a file.
*/
public class WorkflowBuilder extends AbstractLogEnabled {

    protected static final String STATE_ELEMENT = "state";
    protected static final String TRANSITION_ELEMENT = "transition";
    protected static final String EVENT_ELEMENT = "event";
    protected static final String CONDITION_ELEMENT = "condition";
    //protected static final String ACTION_ELEMENT = "action";
    protected static final String ID_ATTRIBUTE = "id";
    protected static final String INITIAL_ATTRIBUTE = "initial";
    protected static final String SOURCE_ATTRIBUTE = "source";
    protected static final String DESTINATION_ATTRIBUTE = "destination";
    protected static final String CLASS_ATTRIBUTE = "class";
    protected static final String VARIABLE_ELEMENT = "variable";
    protected static final String ASSIGNMENT_ELEMENT = "assign";
    protected static final String VARIABLE_ATTRIBUTE = "variable";
    protected static final String VALUE_ATTRIBUTE = "value";
    protected static final String NAME_ATTRIBUTE = "name";
    protected static final String SYNCHRONIZED_ATTRIBUTE = "synchronized";

    private ConditionFactory conditionFactory = null;

    /**
     * Ctor.
     * @param logger The logger to use.
     */
    public WorkflowBuilder(Logger logger) {
        ContainerUtil.enableLogging(this, logger);
    }

    /**
     * Builds a workflow schema from a file.
     * @param name The workflow name.
     * @param file The file.
     * @return A workflow schema implementation.
     * @throws WorkflowException if the file does not represent a valid workflow
     *             schema.
     */
    public WorkflowImpl buildWorkflow(String name, File file) throws WorkflowException {
        WorkflowImpl workflow;

        try {
            Document document = DocumentHelper.readDocument(file);
            workflow = buildWorkflow(name, document);
        } catch (Exception e) {
            throw new WorkflowException(e);
        }

        return workflow;
    }

    /**
     * Builds a workflow object from an XML document.
     * @param name The workflow name.
     * @param document The XML document.
     * @return A workflow implementation.
     * @throws WorkflowException when something went wrong.
     */
    protected WorkflowImpl buildWorkflow(String name, Document document) throws WorkflowException {

        Element root = document.getDocumentElement();
        String initialState = null;

        // load states
        NodeList stateElements = root.getElementsByTagNameNS(Workflow.NAMESPACE, STATE_ELEMENT);

        for (int i = 0; i < stateElements.getLength(); i++) {
            Element element = (Element) stateElements.item(i);
            String state = buildState(element);

            if (isInitialStateElement(element)) {
                initialState = state;
            }
        }

        WorkflowImpl workflow = new WorkflowImpl(name, initialState);

        // load variables
        NodeList variableElements = root.getElementsByTagNameNS(Workflow.NAMESPACE,
                VARIABLE_ELEMENT);

        for (int i = 0; i < variableElements.getLength(); i++) {
            Element element = (Element) variableElements.item(i);
            BooleanVariableImpl variable = buildVariable(element);
            workflow.addVariable(variable);
        }

        // load events
        NodeList eventElements = root.getElementsByTagNameNS(Workflow.NAMESPACE, EVENT_ELEMENT);

        for (int i = 0; i < eventElements.getLength(); i++) {
            String event = buildEvent((Element) eventElements.item(i));
            workflow.addEvent(event);
        }

        // load transitions
        NodeList transitionElements = root.getElementsByTagNameNS(Workflow.NAMESPACE,
                TRANSITION_ELEMENT);

        for (int i = 0; i < transitionElements.getLength(); i++) {
            TransitionImpl transition = buildTransition((Element) transitionElements.item(i));
            workflow.addTransition(transition);
        }

        return workflow;
    }

    /**
     * Checks if a state element contains the initial state.
     * @param element An XML element.
     * @return A boolean value.
     */
    protected boolean isInitialStateElement(Element element) {
        String initialAttribute = element.getAttribute(INITIAL_ATTRIBUTE);

        return (initialAttribute != null)
                && (initialAttribute.equals("yes") || initialAttribute.equals("true"));
    }

    /**
     * Builds a state from an XML element.
     * @param element An XML element.
     * @return A state.
     */
    protected String buildState(Element element) {
        return element.getAttribute(ID_ATTRIBUTE);
    }

    /**
     * Builds a transition from an XML element.
     * @param element An XML element.
     * @return A transition.
     * @throws WorkflowException when something went wrong.
     */
    protected TransitionImpl buildTransition(Element element) throws WorkflowException {

        if (getLogger().isDebugEnabled()) {
            getLogger().debug("Building transition");
        }

        String source = element.getAttribute(SOURCE_ATTRIBUTE);
        String destination = element.getAttribute(DESTINATION_ATTRIBUTE);

        TransitionImpl transition = new TransitionImpl(source, destination);
        ContainerUtil.enableLogging(transition, getLogger());

        // set event
        Element eventElement = (Element) element.getElementsByTagNameNS(Workflow.NAMESPACE,
                EVENT_ELEMENT).item(0);
        String event = eventElement.getAttribute(ID_ATTRIBUTE);
        transition.setEvent(event);

        if (getLogger().isDebugEnabled()) {
            getLogger().debug("    Event: [" + event + "]");
        }

        // load conditions
        NodeList conditionElements = element.getElementsByTagNameNS(Workflow.NAMESPACE,
                CONDITION_ELEMENT);

        for (int i = 0; i < conditionElements.getLength(); i++) {
            Condition condition = buildCondition((Element) conditionElements.item(i));
            transition.addCondition(condition);
        }

        // load assignments
        NodeList assignmentElements = element.getElementsByTagNameNS(Workflow.NAMESPACE,
                ASSIGNMENT_ELEMENT);

        for (int i = 0; i < assignmentElements.getLength(); i++) {
            BooleanVariableAssignmentImpl action = buildAssignment((Element) assignmentElements
                    .item(i));
            transition.addAction(action);
        }

        // load actions
        /*
         * NodeList actionElements = element
         * .getElementsByTagNameNS(Workflow.NAMESPACE, ACTION_ELEMENT);
         *
         * for (int i = 0; i < actionElements.getLength(); i++) { Action action =
         * buildAction((Element) actionElements.item(i));
         * transition.addAction(action); }
         */

        // set synchronization

        /* FIXME: this is not used in the default publication, and is not currently accepted by the workflow xml validation. what does it do? */
        if (element.hasAttribute(SYNCHRONIZED_ATTRIBUTE)) {
            Boolean isSynchronized = Boolean.valueOf(element.getAttribute(SYNCHRONIZED_ATTRIBUTE));
            transition.setSynchronized(isSynchronized.booleanValue());
        }

        return transition;
    }

    /**
     * Builds an event from an XML element.
     * @param element An XML element.
     * @return An event.
     */
    protected String buildEvent(Element element) {
        return element.getAttribute(ID_ATTRIBUTE);
    }


    /**
     * Builds a condition from an XML element.
     * @param element An XML element.
     * @return A condition.
     * @throws WorkflowException when something went wrong.
     */
    protected Condition buildCondition(Element element) throws WorkflowException {
        String className = element.getAttribute(CLASS_ATTRIBUTE);
        String expression = DocumentHelper.getSimpleElementText(element);
        if (this.conditionFactory == null) {
            this.conditionFactory = new ConditionFactory(getLogger());
        }
        Condition condition = this.conditionFactory.createCondition(className, expression);

        return condition;
    }

    /**
     * Builds a boolean variable from an XML element.
     * @param element An XML element.
     * @return A boolean variable.
     */
    protected BooleanVariableImpl buildVariable(Element element) {
        String name = element.getAttribute(NAME_ATTRIBUTE);
        String value = element.getAttribute(VALUE_ATTRIBUTE);

        return new BooleanVariableImpl(name, Boolean.getBoolean(value));
    }

    /**
     * Builds an assignment object from an XML element.
     * @param element An XML element.
     * @return An assignment object.
     * @throws WorkflowException when something went wrong.
     */
    protected BooleanVariableAssignmentImpl buildAssignment(Element element)
            throws WorkflowException {
        String variableName = element.getAttribute(VARIABLE_ATTRIBUTE);

        String valueString = element.getAttribute(VALUE_ATTRIBUTE);
        boolean value = Boolean.valueOf(valueString).booleanValue();

        return new BooleanVariableAssignmentImpl(variableName, value);
    }
}
TOP

Related Classes of org.apache.lenya.workflow.impl.WorkflowBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.