Package de.danet.an.workflow.domain

Source Code of de.danet.an.workflow.domain.AbstractProcessDefinitionDirectory

/*
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
* All rights reserved.
*
* 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 2 of the License, or
* (at your option) 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* $Id: AbstractProcessDefinitionDirectory.java 2742 2008-04-07 22:37:22Z mlipp $
*/
package de.danet.an.workflow.domain;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.jaxen.JaxenException;
import org.jaxen.XPath;
import org.jaxen.jdom.JDOMXPath;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;
import org.jdom.input.SAXHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.XMLFilter;

import de.danet.an.util.sax.XmlnsUrisPatcher;
import de.danet.an.workflow.api.ImportException;
import de.danet.an.workflow.api.PrioritizedMessage;
import de.danet.an.workflow.api.ProcessDefinition;
import de.danet.an.workflow.localapi.ProcessDefinitionDirectoryLocal;
import de.danet.an.workflow.util.CollectingErrorHandler;
import de.danet.an.workflow.util.XPDLUtil;

/**
* This class provides a basic implementation of
* {@link de.danet.an.workflow.localapi.ProcessDefinitionDirectoryLocal
* <code>ProcessDefinitionDirectory</code>}.
*/
public abstract class AbstractProcessDefinitionDirectory
    implements ProcessDefinitionDirectoryLocal {

    private static final org.apache.commons.logging.Log logger
        = org.apache.commons.logging.LogFactory.getLog
        (AbstractProcessDefinitionDirectory.class);
   
    /**
     * Parses the input that describe process definitions and converts it
     * into a list of {@link ProcessDefinition <code>ProcessDefinition</code>}.
     *
     * @param toParse the input that describes the process definition as XPDL.
     * @return a list; the first element of this list is a list of prioritized
     * messages {@link de.danet.an.workflow.api.PrioritizedMessage
     * <code>PrioritizedMessage</code>} and then follows all the parsed process
     * definitions.
     * @exception ImportException if the XPDL is not correct.
     */
    public static List parseProcessDefinitions(InputSource toParse)
        throws ImportException {
        List resultList = new ArrayList();
        List processDefs = new ArrayList();
        CollectingErrorHandler eh = new CollectingErrorHandler();
        Document doc = null;
        try {
            SAXParserFactory spf = SAXParserFactory.newInstance ();
            spf.setValidating (true);
            spf.setNamespaceAware (true);
            maybeSetFeature
                (spf, "http://xml.org/sax/features/namespace-prefixes", eh);
            SAXParser sp = spf.newSAXParser();
            maybeSetProperty
                (sp, "http://java.sun.com/xml/jaxp/properties/schemaLanguage",
                 "http://www.w3.org/2001/XMLSchema", eh);
            maybeSetProperty
                (sp, "http://java.sun.com/xml/jaxp/properties/schemaSource",
                 schemaUris(), eh);
            SAXHandler sh = new SAXHandler ();
            XMLFilter filter = new XmlnsUrisPatcher ();
            filter.setParent(sp.getXMLReader());
            filter.setContentHandler(sh);
            filter.setDTDHandler(sh);
            filter.setEntityResolver(sh);
            filter.setErrorHandler(eh);
            // build Document
            filter.parse(toParse);
            doc = sh.getDocument();
            Element root = doc.getRootElement();
            if (root == null || !root.getName().equals ("Package")
          || !root.getNamespaceURI().equals (XPDLUtil.XPDL_NS)) {
          eh.add (new PrioritizedMessage
            (PrioritizedMessage.Priority.ERROR,
             "ImportMessages#package.missing"));
            } else if (eh.getErrors().size() == 0
                 && eh.getFatalErrors().size() == 0) {
          ProcDefValidator procDefValidator = new ProcDefValidator();
          procDefValidator.validate(doc, eh);
          processDefs = AbstractProcessDefinitionDirectory
              .getProcessDefinitionsFromXPDL(doc);
            }
        } catch (JDOMException e) {
            eh.add (new PrioritizedMessage (PrioritizedMessage.Priority.ERROR,
                    e.getMessage()));
        } catch (IOException e) {
            eh.add (new PrioritizedMessage (PrioritizedMessage.Priority.ERROR,
                    e.getMessage()));
        } catch (IllegalArgumentException e) {
            eh.add (new PrioritizedMessage (PrioritizedMessage.Priority.ERROR,
                    e.getMessage()));
        } catch (JaxenException e) {
            DefaultProcessDefinition.logger.error (e.getMessage(), e);
            throw new IllegalArgumentException
          ("Cannot traverse XPDL-JDOM: " + e.getMessage());
        } catch (SAXException e) {
            eh.add (new PrioritizedMessage (PrioritizedMessage.Priority.ERROR,
                    e.getMessage()));
        } catch (ParserConfigurationException e) {
            eh.add (new PrioritizedMessage (PrioritizedMessage.Priority.ERROR,
                    e.getMessage()));
        }
        List pms = eh.getMessages();
       
        if (eh.getErrors().size() > 0 || eh.getFatalErrors().size() > 0) {
            throw new ImportException
          ("There have been problems while parsing XPDL", pms);
        }
        // the first element of the result list is list of prioritized messages
        resultList.add(pms);
        // follows the list of process definitions
        resultList.addAll(processDefs);
        return resultList;
    }

    private static void maybeSetFeature
        (SAXParserFactory spf, String feature, CollectingErrorHandler eh)
            throws ParserConfigurationException {
        try {
            spf.setFeature (feature, true);
        } catch (SAXNotRecognizedException e) {
            logger.warn
                ("Feature " + feature + " not recognized, result may be "
                 + "inacurate: " + e.getMessage(), e);
            eh.add (new PrioritizedMessage (PrioritizedMessage.Priority.WARN,
                    e.getMessage()));
        } catch (SAXNotSupportedException e) {
            logger.warn
                ("Feature " + feature + " not recognized, result may be " +
                 "inacurate: " + e.getMessage(), e);
            eh.add (new PrioritizedMessage (PrioritizedMessage.Priority.WARN,
                    e.getMessage()));
        }
    }

    private static void maybeSetProperty
        (SAXParser sp, String property, Object value,
         CollectingErrorHandler eh) {
        try {
            sp.setProperty (property, value);
        } catch (SAXNotRecognizedException e) {
            logger.warn
                ("Property " + property + " not recognized, result may "
                 + "be inacurate: " + e.getMessage(), e);
        } catch (SAXNotSupportedException e) {
            logger.warn
                ("Property " + property + " not recognized, result may "
                 + "be inacurate: " + e.getMessage(), e);
        }
    }

    private static Object[] schemaUris() throws IllegalStateException {
        try {
            List schemas = new ArrayList();
            Set schemaSids = new HashSet();
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            Enumeration rese = cl.getResources
                ("de/danet/an/workflow/resources/schema.locations");
            // there are buggy classloaders that do not implement
            // getResources properly. As a workaround, we make an
            // additional call to getResource if getResources returns
            // an empty result.
            if (!rese.hasMoreElements()) {
                Object r = cl.getResource
                    ("de/danet/an/workflow/resources/schema.locations");
                if (r != null) {
                    Vector v = new Vector(1);
                    v.add (r);
                    rese = v.elements();
                }
            }
            while (rese.hasMoreElements()) {
                URL res = (URL)rese.nextElement();
                BufferedReader locFile = new BufferedReader
                    (new InputStreamReader(res.openStream(), "ISO-8859-1"));
                for (String line = locFile.readLine(); line != null;
                     line = locFile.readLine()) {
                    if (line.indexOf('#') >= 0) {
                        line = line.substring(0, line.indexOf('#'));
                    }
                    line = line.trim();
                    if (line.length() == 0) {
                        continue;
                    }
                    int equalsPos = line.indexOf("=");
                    if (equalsPos < 0) {
                        continue;
                    }
                    String sid = line.substring(0, equalsPos).trim();
                    String sloc = line.substring(equalsPos + 1).trim();
                    URL schemaUrl = new URL (res, sloc);
                    try {
                        if (logger.isDebugEnabled()) {
                            InputStream is = schemaUrl.openStream();
                            is.close();
                        }
                        if (!schemaSids.contains(sid)) {
                            schemas.add(schemaUrl.toString());
                            schemaSids.add(sid);
                        }
                    } catch (IOException e) {
                        logger.debug("Cannot open " + schemaUrl.toString()
                                    + " for " + sid + ": " + e.getMessage(), e);
                    }
                }
            }
            return schemas.toArray();
        } catch (IOException ioe) {
            throw new IllegalStateException ();
        }
    }

    private static List getProcessDefinitionsFromXPDL(Document doc)
        throws JDOMException, JaxenException, ImportException {
        List resultList = new ArrayList();
        List processes = new ArrayList();
        Element root = doc.getRootElement();
        // Namespace
        Namespace namespace = Namespace.getNamespace (XPDLUtil.XPDL_NS);
        // cut out the WorkflowProcess nodes
        XPath path = new JDOMXPath
            ("/xpdl:Package/xpdl:WorkflowProcesses/xpdl:WorkflowProcess");
        path.addNamespace("xpdl", XPDLUtil.XPDL_NS);
        Iterator processListIterator = path.selectNodes(doc).iterator();
        while (processListIterator.hasNext()) {
            Element child = (Element)processListIterator.next();
            processes.add(child);
        }
        if (processes.size() == 0) {
            return resultList;
        }
        Element parent = root.getChild("WorkflowProcesses", namespace);
        parent.removeContent();
        Iterator it2 = processes.iterator();
        while (it2.hasNext()) {
            Element rootClone = (Element)root.clone();
            Element newProcess = (Element)it2.next();
            // new Document
            // import the package description and add to new document
            Document newDoc = new Document(rootClone);
            // import process definition and add under processes
            Element newProcesses
          = rootClone.getChild("WorkflowProcesses", namespace);
            newProcesses.addContent(newProcess);
            ProcessDefinition pd = new DefaultProcessDefinition(newDoc);
            // add to resultlist
            resultList.add(pd);
        }
        return resultList;
    }
}
TOP

Related Classes of de.danet.an.workflow.domain.AbstractProcessDefinitionDirectory

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.