org.pentaho.platform.engine.services.actionsequence.SequenceDefinition.java Source code

Java tutorial

Introduction

Here is the source code for org.pentaho.platform.engine.services.actionsequence.SequenceDefinition.java

Source

/*!
 *
 * This program is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License, version 2 as published by the Free Software
 * Foundation.
 *
 * You should have received a copy of the GNU General Public License along with this
 * program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.html
 * or from the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * This program 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 General Public License for more details.
 *
 *
 * Copyright (c) 2002-2018 Hitachi Vantara. All rights reserved.
 *
 */

package org.pentaho.platform.engine.services.actionsequence;

import org.apache.commons.collections.map.ListOrderedMap;
import org.apache.commons.io.FilenameUtils;
import org.dom4j.Document;
import org.dom4j.Node;
import org.pentaho.commons.connection.memory.MemoryResultSet;
import org.pentaho.platform.api.engine.IActionParameter;
import org.pentaho.platform.api.engine.IActionSequence;
import org.pentaho.platform.api.engine.IActionSequenceResource;
import org.pentaho.platform.api.engine.IApplicationContext;
import org.pentaho.platform.api.engine.IConditionalExecution;
import org.pentaho.platform.api.engine.ILogger;
import org.pentaho.platform.api.engine.ISequenceDefinition;
import org.pentaho.platform.api.engine.ISolutionActionDefinition;
import org.pentaho.platform.api.repository2.unified.RepositoryFile;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import org.pentaho.platform.engine.services.messages.Messages;
import org.pentaho.platform.util.logging.Logger;
import org.pentaho.platform.util.xml.dom4j.XmlDom4JHelper;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class SequenceDefinition implements ISequenceDefinition {

    private static final boolean debug = PentahoSystem.debug;

    private int errorCode;

    private String xactionPath;

    private String version;

    private String title;

    private boolean isWebService;

    private String cacheLevel;

    private int loggingLevel;

    private String description;

    private String author;

    private String help;

    private String resultType;

    private String iconPath;

    private Map outputDefinitions;

    private Map inputDefinitions;

    private Map resourceDefinitions;

    IApplicationContext applicationContext;

    ISolutionActionDefinition[] actionDefinitions;

    public static IActionSequence ActionSequenceFactory(final Document document, final String solutionPath,
            final ILogger logger, final IApplicationContext applicationContext, final int loggingLevel) {

        // Check for a sequence document
        Node sequenceDefinitionNode = document.selectSingleNode("//action-sequence"); //$NON-NLS-1$
        if (sequenceDefinitionNode == null) {
            logger.error(Messages.getInstance()
                    .getErrorString("SequenceDefinition.ERROR_0002_NO_ACTION_SEQUENCE_NODE", "", solutionPath, "")); //$NON-NLS-1$
            return null;
        }

        ISequenceDefinition seqDef = new SequenceDefinition(sequenceDefinitionNode, solutionPath, logger,
                applicationContext);

        Node actionNode = sequenceDefinitionNode.selectSingleNode("actions"); //$NON-NLS-1$

        return (SequenceDefinition.getNextLoopGroup(seqDef, actionNode, solutionPath, logger, loggingLevel));
    }

    private static IActionSequence getNextLoopGroup(final ISequenceDefinition seqDef, final Node actionsNode,
            final String solutionPath, final ILogger logger, final int loggingLevel) {

        String loopParameterName = XmlDom4JHelper.getNodeText("@loop-on", actionsNode); //$NON-NLS-1$
        boolean loopUsingPeek = "true".equalsIgnoreCase(XmlDom4JHelper.getNodeText("@peek-only", actionsNode)); //$NON-NLS-1$ //$NON-NLS-2$

        Node actionDefinitionNode;
        ActionDefinition actionDefinition;

        List actionDefinitionList = new ArrayList();

        List nodeList = actionsNode.selectNodes("*"); //$NON-NLS-1$
        Iterator actionDefinitionNodes = nodeList.iterator();
        while (actionDefinitionNodes.hasNext()) {
            actionDefinitionNode = (Node) actionDefinitionNodes.next();
            if (actionDefinitionNode.getName().equals("actions")) { //$NON-NLS-1$
                actionDefinitionList.add(SequenceDefinition.getNextLoopGroup(seqDef, actionDefinitionNode,
                        solutionPath, logger, loggingLevel));
            } else if (actionDefinitionNode.getName().equals("action-definition")) { //$NON-NLS-1$
                actionDefinition = new ActionDefinition(actionDefinitionNode, logger);
                actionDefinition.setLoggingLevel(loggingLevel);
                actionDefinitionList.add(actionDefinition);
            }
        }
        // action sequences with 0 actions are valid, see: JIRA PLATFORM-837

        IConditionalExecution conditionalExecution = SequenceDefinition.parseConditionalExecution(actionsNode,
                logger, "condition"); //$NON-NLS-1$

        ActionSequence sequence = new ActionSequence(loopParameterName, seqDef, actionDefinitionList,
                loopUsingPeek);

        sequence.setConditionalExecution(conditionalExecution);
        return sequence;
    }

    private SequenceDefinition(final Node sequenceRootNode, final String solutionPath, final ILogger logger,
            final IApplicationContext applicationContext) {

        // initialize this object from the contents of the xml

        this.xactionPath = solutionPath;
        this.applicationContext = applicationContext;

        // get the descriptive entries
        version = XmlDom4JHelper.getNodeText("version", sequenceRootNode); //$NON-NLS-1$
        title = XmlDom4JHelper.getNodeText("title", sequenceRootNode); //$NON-NLS-1$

        isWebService = "true".equals(XmlDom4JHelper.getNodeText("web-service", sequenceRootNode)); //$NON-NLS-1$ //$NON-NLS-2$
        loggingLevel = Logger.getLogLevel(XmlDom4JHelper.getNodeText("logging-level", sequenceRootNode)); //$NON-NLS-1$

        description = XmlDom4JHelper.getNodeText("documentation/description", sequenceRootNode); //$NON-NLS-1$
        help = XmlDom4JHelper.getNodeText("documentation/help", sequenceRootNode); //$NON-NLS-1$
        author = XmlDom4JHelper.getNodeText("documentation/author", sequenceRootNode); //$NON-NLS-1$
        resultType = XmlDom4JHelper.getNodeText("documentation/result-type", sequenceRootNode); //$NON-NLS-1$
        iconPath = XmlDom4JHelper.getNodeText("documentation/icon", sequenceRootNode); //$NON-NLS-1$

        // get the input parameter definitions
        inputDefinitions = new ListOrderedMap();
        errorCode = SequenceDefinition.parseParameters(sequenceRootNode, logger, "inputs/*", inputDefinitions, null, //$NON-NLS-1$
                true);

        // get the ouput definitions
        outputDefinitions = new ListOrderedMap();
        errorCode = SequenceDefinition.parseParameters(sequenceRootNode, logger, "outputs/*", outputDefinitions, //$NON-NLS-1$
                null, false);
        if (errorCode != ISequenceDefinition.ACTION_SEQUENCE_DEFINITION_OK) {
            logger.info(Messages.getInstance().getString("SequenceDefinition.INFO_OUTPUT_PARAMETERS_NOT_DEFINED")); //$NON-NLS-1$      
        }
        // get the resource definitions
        errorCode = parseResourceDefinitions(sequenceRootNode, logger);
        if (errorCode != ISequenceDefinition.ACTION_SEQUENCE_DEFINITION_OK) {
            logger.info(
                    Messages.getInstance().getString("SequenceDefinition.INFO_RESOURCES_PARAMETERS_NOT_DEFINED")); //$NON-NLS-1$     
        }
    }

    public String getVersion() {
        return version;
    }

    public boolean isWebService() {
        return isWebService;
    }

    public String getCacheLevel() {
        return cacheLevel;
    }

    public int getErrorCode() {
        return errorCode;
    }

    static IConditionalExecution parseConditionalExecution(final Node actionRootNode, final ILogger logger,
            final String nodePath) {
        try {
            Node condition = actionRootNode.selectSingleNode(nodePath);
            if (condition == null) {
                return null;
            }
            String script = condition.getText();
            IConditionalExecution ce = PentahoSystem.get(IConditionalExecution.class, null);
            ce.setScript(script);
            return ce;
        } catch (Exception ex) {
            logger.error(Messages.getInstance().getErrorString("SequenceDefinition.ERROR_0005_PARSING_PARAMETERS"), //$NON-NLS-1$
                    ex);
        }
        return null;
    }

    static int parseParameters(final Node actionRootNode, final ILogger logger, final String nodePath,
            final Map parameterMap, final Map mapTo, final boolean inputVar) {
        try {
            List parameters = actionRootNode.selectNodes(nodePath);

            // TODO create objects to represent the types
            // TODO need source variable list
            Iterator parametersIterator = parameters.iterator();
            Node parameterNode;
            String parameterName;
            String parameterType;
            ActionParameter parameter;
            List variableNodes;
            List variables;
            Node variableNode;
            Iterator variablesIterator;
            String variableSource;
            String variableName;
            int variableIdx;
            Object defaultValue = null;

            while (parametersIterator.hasNext()) {
                parameterNode = (Node) parametersIterator.next();
                parameterName = parameterNode.getName();
                parameterType = XmlDom4JHelper.getNodeText("@type", parameterNode); //$NON-NLS-1$

                if (mapTo != null) {
                    mapTo.put(parameterName, XmlDom4JHelper.getNodeText("@mapping", parameterNode, parameterName)); //$NON-NLS-1$
                }

                defaultValue = SequenceDefinition.getDefaultValue(parameterNode);
                // get the list of sources for this parameter
                variableNodes = parameterNode.selectNodes((inputVar) ? "sources/*" : "destinations/*"); //$NON-NLS-1$ //$NON-NLS-2$
                variablesIterator = variableNodes.iterator();
                variableIdx = 1;
                variables = new ArrayList();
                while (variablesIterator.hasNext()) {
                    variableNode = (Node) variablesIterator.next();
                    // try to resolve the parameter value for this
                    try {
                        variableSource = variableNode.getName();
                        variableName = variableNode.getText();
                        ActionParameterSource variable = new ActionParameterSource(variableSource, variableName);
                        if (SequenceDefinition.debug) {
                            logger.debug(Messages.getInstance().getString(
                                    "SequenceDefinition.DEBUG_ADDING_SOURCE_FOR_PARAMETER", variableSource, //$NON-NLS-1$
                                    parameterName));
                        }

                        variables.add(variable);
                    } catch (Exception e) {
                        logger.error(Messages.getInstance().getErrorString(
                                "SequenceDefinition.ERROR_0004_VARIABLE_SOURCE_NOT_VALID", //$NON-NLS-1$
                                Integer.toString(variableIdx), parameterName), e);
                    }
                    variableIdx++;
                }
                if (defaultValue != null) {
                    if (SequenceDefinition.debug) {
                        logger.debug(
                                Messages.getInstance().getString("SequenceDefinition.DEBUG_USING_DEFAULT_VALUE", //$NON-NLS-1$
                                        defaultValue.toString(), parameterName));
                    }
                }
                boolean isOutputParameter = Boolean
                        .parseBoolean(XmlDom4JHelper.getNodeText("@is-output-parameter", parameterNode, "true")); //$NON-NLS-1$ //$NON-NLS-2$
                parameter = new ActionParameter(parameterName, parameterType, null, variables, defaultValue);
                parameter.setOutputParameter(isOutputParameter);
                parameterMap.put(parameterName, parameter);
            }
            return ISequenceDefinition.ACTION_SEQUENCE_DEFINITION_OK;
        } catch (Exception e) {
            logger.error(Messages.getInstance().getErrorString("SequenceDefinition.ERROR_0005_PARSING_PARAMETERS"), //$NON-NLS-1$
                    e);
        }

        return ISequenceDefinition.ACTION_SEQUENCE_DEFINITION_INVALID_ACTION_DOC;
    }

    private int parseResourceDefinitions(final Node actionRootNode, final ILogger logger) {

        resourceDefinitions = new ListOrderedMap();

        try {
            List resources = actionRootNode.selectNodes("resources/*"); //$NON-NLS-1$

            // TODO create objects to represent the types
            // TODO need source variable list
            Iterator resourcesIterator = resources.iterator();

            Node resourceNode;
            String resourceName;
            String resourceTypeName;
            String resourceMimeType;
            int resourceType;
            ActionSequenceResource resource;
            Node typeNode, mimeNode;
            while (resourcesIterator.hasNext()) {
                resourceNode = (Node) resourcesIterator.next();
                typeNode = resourceNode.selectSingleNode("./*"); //$NON-NLS-1$
                if (typeNode != null) {
                    resourceName = resourceNode.getName();
                    resourceTypeName = typeNode.getName();
                    resourceType = ActionSequenceResource.getResourceType(resourceTypeName);
                    String resourceLocation = XmlDom4JHelper.getNodeText("location", typeNode); //$NON-NLS-1$
                    if ((resourceType == IActionSequenceResource.SOLUTION_FILE_RESOURCE)
                            || (resourceType == IActionSequenceResource.FILE_RESOURCE)) {
                        if (resourceLocation == null) {
                            logger.error(Messages.getInstance().getErrorString(
                                    "SequenceDefinition.ERROR_0008_RESOURCE_NO_LOCATION", resourceName)); //$NON-NLS-1$
                            continue;
                        }
                    } else if (resourceType == IActionSequenceResource.STRING) {
                        resourceLocation = XmlDom4JHelper.getNodeText("string", resourceNode); //$NON-NLS-1$
                    } else if (resourceType == IActionSequenceResource.XML) {
                        //resourceLocation = XmlHelper.getNodeText("xml", resourceNode); //$NON-NLS-1$
                        Node xmlNode = typeNode.selectSingleNode("./location/*"); //$NON-NLS-1$
                        // Danger, we have now lost the character encoding of the XML in this node
                        // see BISERVER-895
                        resourceLocation = (xmlNode == null) ? "" : xmlNode.asXML(); //$NON-NLS-1$
                    }
                    mimeNode = typeNode.selectSingleNode("mime-type"); //$NON-NLS-1$
                    if (mimeNode != null) {
                        resourceMimeType = mimeNode.getText();
                        if ((resourceType == IActionSequenceResource.SOLUTION_FILE_RESOURCE)
                                || (resourceType == IActionSequenceResource.FILE_RESOURCE)) {
                            resourceLocation = FilenameUtils.separatorsToUnix(resourceLocation);
                            if (!resourceLocation.startsWith("/")) { //$NON-NLS-1$
                                String parentDir = FilenameUtils.getFullPathNoEndSeparator(xactionPath);
                                if (parentDir.length() == 0) {
                                    parentDir = RepositoryFile.SEPARATOR;
                                }
                                resourceLocation = FilenameUtils
                                        .separatorsToUnix(FilenameUtils.concat(parentDir, resourceLocation));
                            }
                        }
                        resource = new ActionSequenceResource(resourceName, resourceType, resourceMimeType,
                                resourceLocation);
                        resourceDefinitions.put(resourceName, resource);
                    } else {
                        logger.error(Messages.getInstance().getErrorString(
                                "SequenceDefinition.ERROR_0007_RESOURCE_NO_MIME_TYPE", resourceName)); //$NON-NLS-1$
                    }
                }
                // input = new ActionParameter( resourceName, resourceType, null
                // );
                // resourceDefinitions.put( inputName, input );
            }
            return ISequenceDefinition.ACTION_SEQUENCE_DEFINITION_OK;
        } catch (Exception e) {
            logger.error(Messages.getInstance().getErrorString("SequenceDefinition.ERROR_0006_PARSING_RESOURCE"), //$NON-NLS-1$
                    e);
        }
        return ISequenceDefinition.ACTION_SEQUENCE_DEFINITION_INVALID_ACTION_DOC;

    }

    /**
     * sbarkdull: method appears to never be used anywhere
     * 
     * @param actionRootNode
     * @param logger
     * @param nodePath
     * @param mapTo
     * @return
     */
    static int parseActionResourceDefinitions(final Node actionRootNode, final ILogger logger,
            final String nodePath, final Map mapTo) {

        try {
            List resources = actionRootNode.selectNodes(nodePath);

            // TODO create objects to represent the types
            // TODO need source variable list
            Iterator resourcesIterator = resources.iterator();

            Node resourceNode;
            String resourceName;
            while (resourcesIterator.hasNext()) {
                resourceNode = (Node) resourcesIterator.next();
                resourceName = resourceNode.getName();
                if (mapTo != null) {
                    mapTo.put(resourceName, XmlDom4JHelper.getNodeText("@mapping", resourceNode, resourceName)); //$NON-NLS-1$
                }
            }
            return ISequenceDefinition.ACTION_SEQUENCE_DEFINITION_OK;
        } catch (Exception e) {
            logger.error(Messages.getInstance().getErrorString("SequenceDefinition.ERROR_0006_PARSING_RESOURCE"), //$NON-NLS-1$
                    e);
        }
        return ISequenceDefinition.ACTION_SEQUENCE_DEFINITION_INVALID_ACTION_DOC;

    }

    private static Object getDefaultValue(final Node parameterNode) {
        Node rootNode = parameterNode.selectSingleNode("default-value"); //$NON-NLS-1$
        if (rootNode == null) {
            return (null);
        }

        String dataType = XmlDom4JHelper.getNodeText("@type", rootNode); //$NON-NLS-1$
        if (dataType == null) {
            dataType = XmlDom4JHelper.getNodeText("@type", parameterNode); //$NON-NLS-1$
        }

        if ("string-list".equals(dataType)) { //$NON-NLS-1$
            List nodes = rootNode.selectNodes("list-item"); //$NON-NLS-1$
            if (nodes == null) {
                return (null);
            }

            ArrayList rtnList = new ArrayList();
            for (Iterator it = nodes.iterator(); it.hasNext();) {
                rtnList.add(((Node) it.next()).getText());
            }
            return (rtnList);
        } else if ("property-map-list".equals(dataType)) { //$NON-NLS-1$
            List nodes = rootNode.selectNodes("property-map"); //$NON-NLS-1$
            if (nodes == null) {
                return (null);
            }

            ArrayList rtnList = new ArrayList();
            for (Iterator it = nodes.iterator(); it.hasNext();) {
                Node mapNode = (Node) it.next();
                rtnList.add(SequenceDefinition.getMapFromNode(mapNode));
            }
            return (rtnList);
        } else if ("property-map".equals(dataType)) { //$NON-NLS-1$
            return (SequenceDefinition.getMapFromNode(rootNode.selectSingleNode("property-map"))); //$NON-NLS-1$
        } else if ("long".equals(dataType)) { //$NON-NLS-1$
            try {
                return (new Long(rootNode.getText()));
            } catch (Exception e) {
                //ignore
            }
            return (null);
        } else if ("result-set".equals(dataType)) { //$NON-NLS-1$

            return (MemoryResultSet.createFromActionSequenceInputsNode(parameterNode));
        } else { // Assume String
            return (rootNode.getText());
        }

    }

    private static Map getMapFromNode(final Node mapNode) {
        Map rtnMap = new ListOrderedMap();

        if (mapNode != null) {
            List nodes = mapNode.selectNodes("entry"); //$NON-NLS-1$
            if (nodes != null) {
                for (Iterator it = nodes.iterator(); it.hasNext();) {
                    Node entryNode = (Node) it.next();
                    rtnMap.put(XmlDom4JHelper.getNodeText("@key", entryNode), entryNode.getText()); //$NON-NLS-1$
                }
            }
        }
        return (rtnMap);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.pentaho.newcode.IActionDefinition#getParamDefs()
     */
    public Map getInputDefinitions() {
        return inputDefinitions;
    }

    public Map getInputDefinitionsForParameterProvider(final String parameterProviderName) {
        Map rtnMap = new ListOrderedMap();

        Map paramList = getInputDefinitions();
        for (Iterator it = paramList.values().iterator(); it.hasNext();) {
            IActionParameter actionParameter = (IActionParameter) it.next();
            List vars = actionParameter.getVariables();
            for (int i = 0; i < vars.size(); i++) {
                ActionParameterSource source = (ActionParameterSource) (vars.get(i));
                if (source.getSourceName().equals(parameterProviderName)) {
                    rtnMap.put(source.getValue(), actionParameter);
                }
            }
        }
        return (rtnMap);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.pentaho.newcode.IActionDefinition#getOutputDefs()
     */
    public Map getOutputDefinitions() {
        return outputDefinitions;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.pentaho.newcode.IActionDefinition#getResourceDefs()
     */
    public Map getResourceDefinitions() {
        return resourceDefinitions;
    }

    public String getSequenceName() {
        return FilenameUtils.getName(xactionPath);
    }

    public String getAuthor() {
        return author;
    }

    public String getDescription() {
        return description;
    }

    public String getResultType() {
        return resultType;
    }

    public String getHelp() {
        return help;
    }

    public String getTitle() {
        return title;
    }

    public String getSolutionName() {
        return "";
    }

    public String getSolutionPath() {
        return xactionPath;
    }

    public int getLoggingLevel() {
        return (loggingLevel);
    }

    public String getIcon() {
        return iconPath;
    }

}