org.pepstock.jem.jbpm.XmlParser.java Source code

Java tutorial

Introduction

Here is the source code for org.pepstock.jem.jbpm.XmlParser.java

Source

/**
JEM, the BEE - Job Entry Manager, the Batch Execution Environment
Copyright (C) 2012-2015   Andrea "Stock" Stocchero
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
    
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.
    
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.pepstock.jem.jbpm;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.lang.StringUtils;
import org.pepstock.jem.jbpm.xml.DataInput;
import org.pepstock.jem.jbpm.xml.DataInputAssociation;
import org.pepstock.jem.jbpm.xml.IoSpecification;
import org.pepstock.jem.jbpm.xml.TaskDescription;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * Is a XML parser, to extract all needed JEM nodes for creating all JEM structures (data description, data sets, data sources, locks).<br>
 * It scans all tasks tagged as TASK, with taskName="Jem"
 * 
 * @author Andrea "Stock" Stocchero
 * @version 2.2
 */
public final class XmlParser {

    private static final String PROCESS_ELEMENT = "process";

    private static final String TASK_ELEMENT = "task";

    private static final String IO_SPECIFICATION_ELEMENT = "ioSpecification";

    private static final String DATA_INPUT_ELEMENT = "dataInput";

    private static final String DATA_INPUT_ASSOCIATION_ELEMENT = "dataInputAssociation";

    private static final String TARGET_REF_ELEMENT = "targetRef";

    private static final String ASSIGNMENT_ELEMENT = "assignment";

    private static final String FROM_ELEMENT = "from";

    private static final String TO_ELEMENT = "to";

    private static final String ID_ATTRIBUTE = "id";

    private static final String NAME_ATTRIBUTE = "name";

    private static final String TASK_NAME_ATTRIBUTE = "taskName";

    /**
     * To avoid any instantiation
     */
    private XmlParser() {

    }

    /**
     * Loads all task defined as workitem based on JEM, to load all info about data description, data sources and locks.
     * @param jclFile BPMN file to parse
     * @return list of all tasks of JCL
     * @throws ParserConfigurationException if any exception occurs parsing XML
     * @throws SAXException if any exception occurs parsing XML
     * @throws IOException if any exception occurs reading file
     */
    public static final List<TaskDescription> getTaskDescription(String jclFile)
            throws ParserConfigurationException, SAXException, IOException {
        // creates an input soure
        InputSource source = new InputSource(new FileInputStream(jclFile));

        // DOM document and parsing
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setIgnoringComments(false);
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(source);

        // scan XML to read comment
        NodeList firstLevel = doc.getDocumentElement().getChildNodes();
        for (int i = 0; i < firstLevel.getLength(); i++) {
            Node node = firstLevel.item(i);
            // gets tag name 
            String tagName = getElementName(node);
            // if is a process, starts scanning nodes
            if (tagName != null && PROCESS_ELEMENT.equalsIgnoreCase(tagName)) {
                Element element = (Element) node;
                if (element.hasChildNodes()) {
                    // scans children only if the element has got children
                    return getTasks(element.getChildNodes());
                }
            }
        }
        return Collections.emptyList();
    }

    /**
     * Scans all children of PROCESS element, all BPMN tasks
     * @param list list of task, children of process
     * @return collection of tasks
     */
    private static List<TaskDescription> getTasks(NodeList list) {
        // creates list of tasks to return
        List<TaskDescription> result = new ArrayList<TaskDescription>();
        // scans all nodes
        for (int i = 0; i < list.getLength(); i++) {
            Node node = list.item(i);
            // gets tagname
            String tagName = getElementName(node);
            // checks if is TASK element
            if (tagName != null && TASK_ELEMENT.equalsIgnoreCase(tagName)) {
                Element element = (Element) node;
                boolean isJemWorkItem = false;
                // scans attributes to check if is a JEM node
                for (int k = 0; k < element.getAttributes().getLength(); k++) {
                    // gets attribute and value
                    String attrName = element.getAttributes().item(k).getNodeName();
                    String value = element.getAttributes().item(k).getTextContent();
                    // checks if the task is a JEM task.
                    // chekcs if there is a namespace also
                    if (value != null && (attrName.endsWith(":" + TASK_NAME_ATTRIBUTE)
                            || attrName.equalsIgnoreCase(TASK_NAME_ATTRIBUTE))) {
                        isJemWorkItem = value.equalsIgnoreCase(JBpmKeys.JBPM_JEM_WORKITEM_NAME);
                    }
                }
                // if it has found JEM task, loads information to task
                if (isJemWorkItem && element.hasChildNodes()) {
                    // loads data
                    TaskDescription task = new TaskDescription();
                    task.setId(element.getAttribute(ID_ATTRIBUTE));
                    task.setName(element.getAttribute(NAME_ATTRIBUTE));
                    // gets IOSPECIFICATION, where all IO information are written
                    task.setIoSpecification(getIoSpecification(element.getChildNodes()));
                    result.add(task);
                }
            }
        }
        return result;
    }

    /**
     * Scans all IOSPECIFICATION information. In this area you can find all parameters for the task.
     * JEM uses this parameters to set data description, data source and locks
     * 
     * @param list list of nodes to scan
     * @return IoSpecification instance
     */
    private static IoSpecification getIoSpecification(NodeList list) {
        // creates instance to return 
        IoSpecification ioSpecification = new IoSpecification();
        // scans all nodes
        for (int i = 0; i < list.getLength(); i++) {
            Node node = list.item(i);
            // gets tagname
            String tagName = getElementName(node);
            if (tagName != null) {
                // if is IO SPECIFICATION, then load all DATA INPUT
                if (IO_SPECIFICATION_ELEMENT.equalsIgnoreCase(tagName)) {
                    Element element = (Element) node;
                    if (element.hasChildNodes()) {
                        // loads data input
                        loadDataInput(element.getChildNodes(), ioSpecification);
                    }
                } else if (DATA_INPUT_ASSOCIATION_ELEMENT.equalsIgnoreCase(tagName)) {
                    // if is DATA_INOUT _ASSOCIATION, scan for all assignments
                    Element element = (Element) node;
                    if (element.hasChildNodes()) {
                        // scans children loading assignments
                        DataInputAssociation result = getDataInputAssociation(element.getChildNodes());
                        // checks if target_ref and value of assignment is the same
                        if (result.isValid()) {
                            // adds assignment
                            ioSpecification.getAssociations().put(result.getTargetRef(), result);
                        }
                    }
                }
            }
        }
        return ioSpecification;
    }

    /**
     * Loads all data input elements
     * @param list list of node's children 
     * @param ioSpecification container of data inputs
     */
    private static void loadDataInput(NodeList list, IoSpecification ioSpecification) {
        // scans all nodes
        for (int i = 0; i < list.getLength(); i++) {
            Node node = list.item(i);
            // gets tag name
            String tagName = getElementName(node);
            // checks if data input element
            if (tagName != null && DATA_INPUT_ELEMENT.equalsIgnoreCase(tagName)) {
                Element element = (Element) node;
                // gets ID and name
                String id = element.getAttribute(ID_ATTRIBUTE);
                String name = element.getAttribute(NAME_ATTRIBUTE);
                // checks if is a data description, data source and locks
                if (name != null && name.startsWith(JBpmKeys.JBPM_DATA_DESCRIPTION_PREFIX)
                        || name.startsWith(JBpmKeys.JBPM_DATA_SOURCE_PREFIX)
                        || name.equalsIgnoreCase(JBpmKeys.JBPM_LOCK_KEY)) {
                    // loads the bean 
                    DataInput input = new DataInput();
                    input.setId(id);
                    input.setName(name);
                    ioSpecification.getDataInputs().add(input);
                }
            }
        }
    }

    /**
     * Loads all data assignment 
     * @param list list of node's children
     * @return data input association entity
     */
    private static DataInputAssociation getDataInputAssociation(NodeList list) {
        // creates the result 
        DataInputAssociation result = new DataInputAssociation();
        // scans nodes
        for (int i = 0; i < list.getLength(); i++) {
            Node node = list.item(i);
            // gets tagname
            String tagName = getElementName(node);
            if (tagName != null) {
                Element element = (Element) node;
                // extracts the TARGET REF data
                if (TARGET_REF_ELEMENT.equalsIgnoreCase(tagName)) {
                    result.setTargetRef(element.getTextContent());
                }
                // gets assignment information
                if (ASSIGNMENT_ELEMENT.equalsIgnoreCase(tagName)) {
                    // scans all children of ASSIGNMENT
                    NodeList fromTo = element.getChildNodes();
                    for (int k = 0; k < fromTo.getLength(); k++) {
                        Node fromToNode = fromTo.item(k);
                        // gets tag name
                        String subTagName = getElementName(fromToNode);
                        if (subTagName != null) {
                            Element elfromTo = (Element) fromToNode;
                            // loads FROM and TO
                            if (FROM_ELEMENT.equalsIgnoreCase(subTagName)) {
                                result.setAssignmentFrom(elfromTo.getTextContent());
                            } else if (TO_ELEMENT.equalsIgnoreCase(subTagName)) {
                                result.setAssignmentTo(elfromTo.getTextContent());
                            }
                        }
                    }
                }
            }
        }
        return result;
    }

    /**
     * Returns the tag name , removing the namespace
     * @param node node to use to extract the tag name
     * @return tag name of node
     */
    private static String getElementName(Node node) {
        // ONLY if is a element returns the name
        if (node.getNodeType() == Element.ELEMENT_NODE) {
            Element el = (Element) node;
            String tagName = null;
            // checks if name space
            if (el.getTagName().contains(":")) {
                tagName = StringUtils.substringAfter(el.getTagName(), ":");
            } else {
                tagName = el.getTagName();
            }
            return tagName;
        }
        return null;
    }

}