Package org.syrup.helpers

Source Code of org.syrup.helpers.NetworkParser$Struct

package org.syrup.helpers;

import org.apache.xml.serializer.OutputPropertiesFactory;
import org.apache.xml.serializer.Serializer;
import org.apache.xml.serializer.SerializerFactory;
import org.syrup.Function;
import org.syrup.InPort;
import org.syrup.OutPort;
import org.syrup.Task;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
* XML parser that parses a Workflow definition into a Network.
*
* @author Robbert van Dalen
*/
public class NetworkParser extends DefaultHandler
{
    static final String COPYRIGHT = "Copyright 2005 Robbert van Dalen."
        + "At your option, you may copy, distribute, or make derivative works under "
        + "the terms of The Artistic License. This License may be found at "
        + "http://www.opensource.org/licenses/artistic-license.php. "
        + "THERE IS NO WARRANTY; USE THIS PRODUCT AT YOUR OWN RISK.";

    private HashMap tasks = new HashMap();

    private ArrayList links = new ArrayList();

    private BindingStruct binding = new BindingStruct(null, null, null, null);

    private int depth;

    private int mark;

    private boolean inElement;

    private Struct currentElement;

    private ContentHandler subDocument = new DefaultHandler();

    private boolean rootElement = false;

    private Serializer serializer;

    private ByteArrayOutputStream outArray;

    /**
     * The main program for the NetworkParser class
     *
     * @param args
     *            No arguments should be given.
     */
    public static void main(String[] args) throws Exception
    {
        try
        {
            NetworkImpl n = new NetworkParser().parse(System.in);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * Parses a XML network description deserialized from a byte array.
     *
     * @param b
     *            The byte array to be deserialized.
     * @return The NetworkImpl if succesful.
     */
    public NetworkImpl parse(byte[] b) throws Exception
    {
        return parse(new ByteArrayInputStream(b));
    }

    /**
     * Parses a XML network description, fed by an InputStream.
     *
     * @param in The InputStream to be parsed.
     *           
     * @return The NetworkImpl if succesful.
     */
    public NetworkImpl parse(InputStream in) throws Exception
    {
        XMLReader r = XMLReaderFactory.createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
        r.setContentHandler(this);
        r.parse(new InputSource(in));

        Set keys = tasks.keySet();
        Iterator kIt = keys.iterator();
        HashMap p = new HashMap();
        int i = 0;

        while (kIt.hasNext())
        {
            TaskStruct pp = (TaskStruct) tasks.get((String) kIt.next());
            Class s = null;

            s = Class.forName(pp.functionClass);
            Function f = (Function) s.newInstance();
            boolean orType = false;

            if (pp.orType != null)
            {
                if (pp.orType.equals("true"))
                {
                    orType = true;
                }
            }

            p.put(pp.name, new TaskImpl(orType, pp.functionClass, pp.name, pp.description, pp.environment, pp.parameter));
        }

        Iterator cs = links.iterator();
        LinkImpl c[] = new LinkImpl[links.size()];
        i = 0;
       
        while (cs.hasNext())
        {
            LinkStruct cc = (LinkStruct) cs.next();

            Task from = pr(cc.from, p);
            Task to = pr(cc.to, p);

            if (from == null
                && to == null)
            {
                throw new Exception("from or to must be a reference");
            }
            c[i++] = new LinkImpl(new OutPortImpl(from, pr_port(cc.from)), new InPortImpl(to, pr_port(cc.to)), new DataImpl(cc.content));
        }

        InPort in1 = null;
        InPort in2 = null;
        OutPort out1 = null;
        OutPort out2 = null;

        if (binding != null)
        {
            in1 = new InPortImpl(pr(binding.in_1, p), pr_port(binding.in_1));
            in2 = new InPortImpl(pr(binding.in_2, p), pr_port(binding.in_2));
            out1 = new OutPortImpl(pr(binding.out_1, p), pr_port(binding.out_1));
            out2 = new OutPortImpl(pr(binding.out_2, p), pr_port(binding.out_2));
        }

        Iterator p_v = p.values().iterator();

        Task pa[] = new Task[p.values().size()];
        i = 0;
        while (p_v.hasNext())
        {
            pa[i++] = (Task) p_v.next();
        }
        return new NetworkImpl(in1, in2, out1, out2, pa, c);
    }

    /**
     * Called at the start of a subdocument (contained by a Link)
     */
    private void startSubDocument() throws SAXException
    {
        startSubDocument("xml");
    }

    /**
     * Called at the start of a subdocument (contained by a Link)
     *
     * @param encoding
     *            The encoding of the subdocument (xml, text or base64)
     */
    private void startSubDocument(String encoding) throws SAXException
    {
        outArray = new ByteArrayOutputStream();

        if (encoding == null)
        {
            encoding = "xml";
        }

        if (encoding.equals("xml")
            || encoding.equals("text"))
        {
            Properties props = OutputPropertiesFactory.getDefaultMethodProperties(encoding);

            if (encoding.equals("xml"))
            {
                props.put("indent", "yes");
                props.put("{http://xml.apache.org/xalan}indent-amount", "4");
                props.remove("standalone");
            }
            serializer = SerializerFactory.getSerializer(props);
            serializer.setOutputStream(outArray);
            try
            {
                subDocument = serializer.asContentHandler();
                subDocument.startDocument();
            }
            catch (Exception e)
            {
                throw new SAXException("Could not serialize sub-stream");
            }
        }
        else if (encoding.equals("base64"))
        {
            subDocument = new BASE64ContentHandler(outArray);
        }
        else
        {
            throw new SAXException("encoding "
                + encoding + " not supported");
        }
    }

    /**
     * Called at the end of a subdocument (contained by a Link)
     */
    private void endSubDocument() throws SAXException
    {
        subDocument.endDocument();

        if (rootElement)
        {
            if (outArray.size() > 0)
            {
                currentElement.content = outArray.toByteArray();
            }
        }
        subDocument = new DefaultHandler();
    }

    /**
     * Returns a Task identified by it's name.
     *
     * @param k
     *            A Task's name.
     * @param m
     *            The Map holding all Tasks indentified by name.
     * @return The Task, indentified by it's name.
     */
    private static Task pr_get(String k, Map m) throws Exception
    {
        Task p = (Task) m.get(k);
        if (p == null)
        {
            throw new Exception("Reference to task '"
                + k + "' not found");
        }
        return p;
    }

    /**
     * Returns a Task identified by it's name + port.
     *
     * @param k
     *            A Task's name + port.
     * @param m
     *            The Map holding all Tasks indentified by name.
     * @return The Task, indentified by it's name.
     */
    private static Task pr(String s, Map m) throws Exception
    {
        if (s == null)
        {
            return null;
        }
        String t = s.trim();
        if (s.endsWith("-1")
            || s.endsWith("-2"))
        {
            String k = t.substring(0, t.length() - 2);
            return pr_get(k, m);
        }
        return pr_get(t, m);
    }

    /**
     * Returns the boolean encoding of a Port specification.
     *
     * @param s
     *            The Port specification
     * @return The boolean encoding of the Port specification.
     */
    private static boolean pr_port(String s)
    {
        if (s != null)
        {
            if (s.endsWith("-2"))
            {
                return true;
            }
        }
        return false;
    }

    /**
     */
    public void startPrefixMapping(java.lang.String prefix,
        java.lang.String namespaceUri) throws org.xml.sax.SAXException
    {
        if (rootElement)
        {
            subDocument.startPrefixMapping(prefix, namespaceUri);
        }
    }

    /**
     */
    public void endPrefixMapping(java.lang.String prefix)
        throws org.xml.sax.SAXException
    {
        if (rootElement)
        {
            subDocument.endPrefixMapping(prefix);
        }
    }

    /**
     */
    public void startElement(String namespaceUri, String localName,
        String qName, Attributes att) throws org.xml.sax.SAXException
    {
        depth++;

        if (inElement)
        {
            if (!rootElement)
            {
                mark = depth;
                rootElement = true;
                startSubDocument(att.getValue("encoding"));
            }
            else
            {
                subDocument.startElement(namespaceUri, localName, qName, att);
            }
        }
        else
        {
            rootElement = false;
            mark = depth;

            if (localName.equals("binding"))
            {
                inElement = true;
                String in1 = att.getValue("in-1");
                String in2 = att.getValue("in-2");
                String out1 = att.getValue("out-1");
                String out2 = att.getValue("out-2");
                binding = new BindingStruct(in1, in2, out1, out2);
                currentElement = binding;
            }
            else if (localName.equals("task"))
            {
                inElement = true;
                String name = att.getValue("name");
                if (name != null)
                {
                    if (tasks.get(name) == null)
                    {
                        String functionClass = att.getValue("functionClass");
                        String orType = att.getValue("orType");
                        String descr = att.getValue("description");
                        String environment = att.getValue("environment");
                        String parameter = att.getValue("parameter");
                        currentElement = new TaskStruct(name, functionClass, orType, descr, environment, parameter);
                        tasks.put(name, currentElement);
                    }
                    else
                    {
                        throw new SAXException("Duplicate task name: "
                            + name);
                    }
                }
                else
                {
                    throw new SAXException("Cannot process Tasks without a name");
                }
            }
            else if (localName.equals("link"))
            {
                inElement = true;
                String from = att.getValue("from");
                String to = att.getValue("to");
                currentElement = new LinkStruct(from, to);
                links.add(currentElement);
            }
        }
    }

    /**
     */
    public void endElement(String namespaceUri, String localName, String qName)
        throws org.xml.sax.SAXException
    {
        if (depth == mark
            && inElement)
        {
            endSubDocument();
            inElement = false;
            rootElement = false;
        }
        else
        {
            subDocument.endElement(namespaceUri, localName, qName);
        }
        depth--;
    }

    /**
     */
    public void characters(char[] arg1, int arg2, int arg3)
        throws org.xml.sax.SAXException
    {
        if (rootElement)
        {
            subDocument.characters(arg1, arg2, arg3);
        }
    }

    /**
     */
    public void ignorableWhitespace(char[] arg1, int arg2, int arg3)
        throws org.xml.sax.SAXException
    {
        if (rootElement)
        {
            subDocument.ignorableWhitespace(arg1, arg2, arg3);
        }
    }

    /**
     */

    public void processingInstruction(String target, String data)
        throws org.xml.sax.SAXException
    {
        if (rootElement)
        {
            subDocument.processingInstruction(target, data);
        }
    }

    /**
     */
    public void skippedEntity(java.lang.String arg1)
        throws org.xml.sax.SAXException
    {
        if (rootElement)
        {
            subDocument.skippedEntity(arg1);
        }
    }

    /**
     * Description of the Class
     *
     * @author Robbert van Dalen
     */
    private class BASE64ContentHandler extends DefaultHandler
    {
        OutputStream output;

        sun.misc.BASE64Decoder decoder = null;

        /**
         * Constructor for the BASE64ContentHandler object
         *
         * @param o
         *            Description of the Parameter
         */
        public BASE64ContentHandler(OutputStream o)
        {
            decoder = new sun.misc.BASE64Decoder();
            output = o;
        }

        /**
         * Description of the Method
         *
         * @param arg1
         *            Description of the Parameter
         * @param arg2
         *            Description of the Parameter
         * @param arg3
         *            Description of the Parameter
         * @exception org.xml.sax.SAXException
         *                Description of the Exception
         */
        public void characters(char[] arg1, int arg2, int arg3)
            throws org.xml.sax.SAXException
        {
            String s = new String(arg1, arg2, arg3);
            try
            {
                byte[] b = decoder.decodeBuffer(s);
                output.write(b);
            }
            catch (Exception e)
            {
                throw new SAXException("Could not decode/write to output");
            }
        }

        /**
         * Description of the Method
         *
         * @param arg1
         *            Description of the Parameter
         * @param arg2
         *            Description of the Parameter
         * @param arg3
         *            Description of the Parameter
         * @exception org.xml.sax.SAXException
         *                Description of the Exception
         */
        public void ignorableWhitespace(char[] arg1, int arg2, int arg3)
            throws org.xml.sax.SAXException
        {
        }
    }

    /**
     * Temporary data-structure to hold content.
     *
     * @author Robbert van Dalen
     */
    private class Struct
    {
        /**
         * Description of the Field
         */
        protected byte[] content;
    }

    /**
     * Temporary data-structure to hold Task content.
     *
     * @author Robbert van Dalen
     */
    private class TaskStruct extends Struct
    {
        /**
         * Description of the Field
         */
        public final String name;

        /**
         * Description of the Field
         */
        public final String functionClass;

        /**
         * Description of the Field
         */
        public final String orType;

        /**
         * Description of the Field
         */
        public final String description;

        /**
         * Description of the Field
         */
        public final String environment;

        /**
         * Description of the Field
         */
        public final String parameter;
       
        /**
         * Constructor for the TaskStruct object
         *
         * @param n
         *            Description of the Parameter
         * @param f
         *            Description of the Parameter
         * @param t
         *            Description of the Parameter
         * @param d
         *            Description of the Parameter
         * @param c
         *            Description of the Parameter
         * @param p
         *            Description of the Parameter
         */
        public TaskStruct(String n, String f, String t, String d, String c, String p)
        {
            name = n;
            functionClass = f;
            orType = t;
            description = d;
            environment = c;
            parameter = p;
        }
    }

    /**
     * Temporary data-structure to hold Link content.
     *
     * @author Robbert van Dalen
     */
    private class LinkStruct extends Struct
    {
        /**
         * Description of the Field
         */
        public final String from;

        /**
         * Description of the Field
         */
        public final String to;

        /**
         * Constructor for the LinkStruct object
         *
         * @param f
         *            Description of the Parameter
         * @param t
         *            Description of the Parameter
         */
        public LinkStruct(String f, String t)
        {
            from = f;
            to = t;
        }
    }

    /**
     * Temporary data-structure to hold Binding content.
     *
     * @author Robbert van Dalen
     */
    private class BindingStruct extends Struct
    {
        /**
         * Description of the Field
         */
        public final String in_1;

        /**
         * Description of the Field
         */
        public final String in_2;

        /**
         * Description of the Field
         */
        public final String out_1;

        /**
         * Description of the Field
         */
        public final String out_2;

        /**
         * Constructor for the BindingStruct object
         *
         * @param in1
         *            Description of the Parameter
         * @param in2
         *            Description of the Parameter
         * @param out1
         *            Description of the Parameter
         * @param out2
         *            Description of the Parameter
         */
        public BindingStruct(String in1, String in2, String out1, String out2)
        {
            in_1 = in1;
            in_2 = in2;
            out_1 = out1;
            out_2 = out2;
        }
    }
}
TOP

Related Classes of org.syrup.helpers.NetworkParser$Struct

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.