All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.coos.messaging.KXMLPluginParser Maven / Gradle / Ivy

The newest version!
/**
 * COOS - Connected Objects Operating System (www.connectedobjects.org).
 *
 * Copyright (C) 2009 Telenor ASA and Tellu AS. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see .
 *
 * You may also contact one of the following for additional information:
 * Telenor ASA, Snaroyveien 30, N-1331 Fornebu, Norway (www.telenor.no)
 * Tellu AS, Hagalokkveien 13, N-1383 Asker, Norway (www.tellu.no)
 */
package org.coos.messaging;

/**
 * @author Anders Storsveen, Telenor Objects AS
 */
import org.coos.messaging.util.URIHelper;
import org.coos.messaging.util.UuidHelper;

import org.kxml2.io.KXmlParser;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Random;
import java.util.Vector;


public class KXMLPluginParser {

    // Tags
    public static final String APPLICATION = "application";

    public static final String PLUGIN = "plugin";
    public static final String CHANNEL = "channel";
    public static final String TRANSPORT = "transport";

    public static final String PROPERTY = "property";

    public static final String INBOUND = "inBound";
    public static final String OUTBOUND = "outBound";
    public static final String FILTER = "filter";

    public static final String PROCESSOR = "processor";

    public static final String JVM_TRANSPORT_CLASS =
        "org.coos.messaging.cldc.transport.TCPTransport";

    private Vector plugins = new Vector();
    private Vector channels = new Vector();
    private Vector transports = new Vector();
    private Vector processors = new Vector();


    Hashtable ht_transports;
    Hashtable ht_channels;
    Hashtable ht_plugins;
    Hashtable ht_processors;
    Hashtable ht_shared_processors;

    COContainer cl;

    public KXMLPluginParser(COContainer co) {
        this.cl = co;
    }

    public void parse(InputStream is) {

        //Initilialize XML parser
        KXmlParser parser = new KXmlParser();

        try {
            parser.setInput(new InputStreamReader(is));

            parser.nextTag();

            parser.require(XmlPullParser.START_TAG, null, "plugins");
            System.out.println("");

            //Iterate through our XML file

            while (parser.nextTag() != XmlPullParser.END_TAG) {

                parser.require(XmlPullParser.START_TAG, null, null);

                String name = parser.getName();
                System.out.println("<" + name + ">");

                if (name.equals(PLUGIN))
                    plugins.addElement(parsePlugin(parser));
                else if (name.equals(PROCESSOR))
                    processors.addElement(parseProcessor(parser));
                else if (name.equals(CHANNEL))
                    channels.addElement(parseChannel(parser));
                else if (name.equals(TRANSPORT))
                    transports.addElement(parseTransport(parser));
                else if (name.equals(PROCESSOR))
                    processors.addElement(parseProcessor(parser));

                parser.require(XmlPullParser.END_TAG, null, name);
                System.out.println("");
            }

            parser.require(XmlPullParser.END_TAG, null, "plugins");
            System.out.println("");
            parser.next();

            parser.require(XmlPullParser.END_DOCUMENT, null, null);

            instanciatePlugins();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private TransportBundle parseTransport(KXmlParser parser) throws XmlPullParserException,
        IOException {
        TransportBundle tb = new TransportBundle(parser.getAttributeValue(null, "name"),
                parser.getAttributeValue(null, "class"), new Hashtable());

        while (parser.nextTag() != KXmlParser.END_TAG) {

            if (parser.getName().equals("property")) {
                parseProperty(parser, tb);
            }
        }

        return tb;
    }

    private ChannelBundle parseChannel(KXmlParser parser) throws XmlPullParserException,
        IOException {
        ChannelBundle ch = new ChannelBundle(parser.getAttributeValue(null, "name"),
                parser.getAttributeValue(null, "class"), parser.getAttributeValue(null, "segment"),
                parser.getAttributeValue(null, "transport"),
                parser.getAttributeValue(null, "protocol"), new Hashtable());

        while (parser.nextTag() != XmlPullParser.END_TAG) {

            parser.require(XmlPullParser.START_TAG, null, null);

            String name = parser.getName();

            if (name.equals("property")) {
                parseProperty(parser, ch);
            } else if (name.equals(INBOUND)) {
                parseFilter(parser, ch, true);
            } else {
                parseFilter(parser, ch, false);
            }

        }

        return ch;
    }


    private void parseFilter(KXmlParser parser, ChannelBundle ch, boolean inbound)
        throws XmlPullParserException, IOException {

        while (parser.nextTag() != XmlPullParser.END_TAG) {
            parser.require(XmlPullParser.START_TAG, null, "filter");
            System.out.println("");

            String proc = new String(parser.getAttributeValue(null, "processor"));

            if (inbound) {
                ch.inBound.addElement(proc);
            } else {
                ch.outBound.addElement(proc);
            }

            parser.nextTag();
            parser.require(XmlPullParser.END_TAG, null, "filter");
            System.out.println("");
        }
    }

    private ProcessorBundle parseProcessor(KXmlParser parser) throws XmlPullParserException,
        IOException {
        ProcessorBundle prb = new ProcessorBundle(parser.getAttributeValue(null, "name"),
                parser.getAttributeValue(null, "class"), parser.getAttributeValue(null, "shared"),
                new Hashtable());

        while (parser.nextTag() != KXmlParser.END_TAG) {

            if (parser.getName().equals("property")) {
                parseProperty(parser, prb);
            }
        }

        return prb;
    }

    private PluginBundle parsePlugin(KXmlParser parser) throws XmlPullParserException, IOException {
        PluginBundle pb = new PluginBundle(parser.getAttributeValue(null, "name"),
                parser.getAttributeValue(null, "channel"), parser.getAttributeValue(null, "class"),
                new Hashtable());

        while (parser.nextTag() != KXmlParser.END_TAG) {

            if (parser.getName().equals("property")) {
                parseProperty(parser, pb);
            }
        }

        return pb;
    }

    private void parseProperty(KXmlParser parser, Bundle bundle) throws XmlPullParserException,
        IOException {

        parser.require(XmlPullParser.START_TAG, null, "property");

        String name = parser.getAttributeValue(null, "name");
        String value = parser.getAttributeValue(null, "value");
        System.out.println("");

        bundle.properties.put(name, value);
        parser.nextTag();
        parser.require(XmlPullParser.END_TAG, null, "property");
        System.out.println("");
    }

    public void instanciatePlugins() {

        try {
            ht_processors = new Hashtable();

            for (int i = 0; i < processors.size(); i++) {
                ProcessorBundle prb = (ProcessorBundle) processors.elementAt(i);

                String name = prb.name;

                ht_processors.put(name, prb);

                Processor processor = instantiateProcessor(prb, cl);

                if (processor.isShared()) {

                    if (ht_shared_processors == null) {
                        ht_shared_processors = new Hashtable();
                    }

                    ht_shared_processors.put(name, prb);
                }
            }

            // create the plugins
            ht_transports = new Hashtable();

            // Always create default transport (localhost connection in cldc, for testing)
            if (transports.size() == 0) {
                Hashtable props = new Hashtable();
                props.put("host", "localhost");
                props.put("port", "15656");
                props.put("retry", "true");

                TransportBundle transport = new TransportBundle("TCP1",
                        "org.coos.messaging.cldc.transport.TCPTransport", props);
                transports.addElement(transport);

                ChannelBundle channel = new ChannelBundle("ch1",
                        "org.coos.messaging.plugin.PluginChannel", "", "TCP1", "coos",
                        new Hashtable());
                channels.addElement(channel);
            }

            for (int i = 0; i < transports.size(); i++) {
                TransportBundle tb = (TransportBundle) transports.elementAt(i);

                // TransportType transportType = model.getTransportArray()[i];
                // String name = transportType.getName();
                // String className = transportType.getClass1();
                // Map props = new HashMap();
                /*
                 * for (int j = 0; j < transportType.getPropertyArray().length;
                 * j++) { PropertyType propertyType =
                 * transportType.getPropertyArray()[j];
                 * props.put(propertyType.getName(), propertyType.getValue()); }
                 */
                String className = tb.className;
                String name = tb.name;

                Class transportClass = Class.forName(className);
                Transport transport = (Transport) transportClass.newInstance();

                transport.setProperties(tb.properties);
                ht_transports.put(name, transport);
            }

            ht_channels = new Hashtable();


            for (int i = 0; i < channels.size(); i++) {
                ChannelBundle ch = (ChannelBundle) channels.elementAt(i);

                String className = ch.className;
                String name = ch.name;
                String protocol = ch.protocol;
                Class channelClass = Class.forName(className);
                Channel channel = (Channel) channelClass.newInstance();

                channel.setName(name);
                channel.setProperties(ch.properties);

                if (protocol != null) {
                    channel.addProtocol(protocol);
                } else {
                    channel.addProtocol("coos"); //The default protocol
                }

                String transportType = ch.transport;

                if (transportType != null) {
                    boolean found = false;

                    for (Enumeration e = ht_transports.keys(); e.hasMoreElements();) {

                        if (e.nextElement().equals(transportType)) {
                            found = true;

                            break;
                        }
                    }

                    if (!found) {
                        throw new Exception("Transport " + transportType + " is not declared.");
                    }

                    channel.setTransport((Transport) ((Transport) ht_transports.get(transportType))
                        .copy());
                    channel.setInit(true); // The Plugin shall always initiate a
                                           // connection
                } else {
                    Class transportClass = Class.forName(JVM_TRANSPORT_CLASS);
                    Transport transport = (Transport) transportClass.newInstance();
                    channel.setTransport(transport);
                    channel.setInit(true); // The Plugin shall always initiate a
                                           // connection
                }

                String segment = ch.segment; // pluginType.getSegment();

                if (segment == null) {
                    segment = "";
                }

                channel.setSegment(segment);

                Vector outBound = ch.outBound;

                if (outBound != null) {

                    for (int j = 0; j < outBound.size(); j++) {
                        String processor = (String) outBound.elementAt(j);

                        ProcessorBundle procType = (ProcessorBundle) ht_processors.get(processor);

                        if (procType == null) {
                            throw new Exception("Processor " + processor + " is not declared.");
                        }

                        if (procType.shared) {
                            channel.getOutLink().addFilterProcessor((Processor)
                                ht_shared_processors.get(processor));
                        } else {
                            channel.getOutLink().addFilterProcessor(instantiateProcessor(procType,
                                    cl));
                        }
                    }
                }

                Vector inBound = ch.inBound;

                if (inBound != null) {

                    for (int j = 0; j < inBound.size(); j++) {
                        String processor = (String) inBound.elementAt(j);
                        ProcessorBundle procType = (ProcessorBundle) ht_processors.get(processor);

                        if (procType == null) {
                            throw new Exception("Processor " + processor + " is not declared.");
                        }

                        if (procType.shared) {
                            channel.getInLink().addFilterProcessor((Processor)
                                ht_shared_processors.get(processor));
                        } else {
                            channel.getInLink().addFilterProcessor(instantiateProcessor(procType,
                                    cl));
                        }
                    }
                }

                ht_channels.put(name, channel);
            }

            ht_plugins = new Hashtable();

            for (int i = 0; i < plugins.size(); i++) {
                PluginBundle pb = (PluginBundle) plugins.elementAt(i);

                Plugin plugin = new Plugin();

                // PluginType pluginType = model.getPluginArray()[i];
                String name = pb.name;

                String className = pb.className;

                String channel = pb.channel;

                Class pluginClass = Class.forName(className);

                Endpoint endpoint = (Endpoint) pluginClass.newInstance();
                endpoint.setCoContainer(cl);

                String nameSegment = "";

                if (name != null) {

                    if (UuidHelper.isUuid(name)) {
                        name = UuidHelper.getQualifiedUuid(name);
                        endpoint.setEndpointUuid(name);
                        endpoint.setEndpointUri("coos://" + name);
                        nameSegment = UuidHelper.getSegmentFromEndpointNameOrEndpointUuid(name);
                    } else {
                        endpoint.setEndpointUri("coos://" + name);

                        URIHelper uHelper = new URIHelper(endpoint.getEndpointUri());
                        nameSegment = uHelper.getSegment();
                    }

                    endpoint.setName(name); // the alias
                }

                // Map props = new HashMap();
                /*
                 * for (int k = 0; k < pluginType.getPropertyArray().length;
                 * k++) { PropertyType propertyType =
                 * pluginType.getPropertyArray()[k];
                 * props.put(propertyType.getName(), propertyType.getValue()); }
                 */
                endpoint.setProperties(pb.properties);

                plugin.setEndpoint(endpoint);

                //Set default channel if not available.
                if (channel == null) {
                    channel = "ch1";
                }

                plugin.addChannel((Channel) ht_channels.get(channel));

                ht_plugins.put((pb.name != null) ? pb.name
                                                 : ("plugin" + (new Random().nextInt() % 100)),
                    plugin);
            }
        } catch (ClassNotFoundException err) {
            err.printStackTrace();
        } catch (Exception err) {
            err.printStackTrace();
        }
    }

    private static Processor instantiateProcessor(ProcessorBundle processor, COContainer cl)
        throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        String className = processor.className;
        boolean isShared = processor.shared;
        /*
         * Map props = new HashMap(); for (int j
         * = 0; j < processorType.getPropertyArray().length; j++) { PropertyType
         * propertyType = processorType.getPropertyArray()[j];
         * props.put(propertyType.getName(), propertyType.getValue()); }
         */

        Class procClass = cl.loadClass(className);
        Processor p = (Processor) procClass.newInstance();
        p.setProperties(processor.properties);
        p.setShared(new Boolean(isShared));

        return p;
    }

    public Plugin[] getPlugins() {
        Plugin[] retp = new Plugin[ht_plugins.size()];
        int counter = 0;

        for (Enumeration e = ht_plugins.keys(); e.hasMoreElements();) {
            retp[counter++] = (Plugin) ht_plugins.get(e.nextElement());
        }

        return retp;
    }

    class PluginBundle extends Bundle {
        public String channel, className;

        public PluginBundle(String name, String channel, String className, Hashtable properties) {
            super(name, properties);
            this.channel = channel;
            this.className = className;
        }
    }

    class ChannelBundle extends Bundle {
        public String className, segment, transport, protocol;
        public Vector inBound = new Vector();
        public Vector outBound = new Vector();

        public ChannelBundle(String name, String className, String segment, String transport,
            String protocol, Hashtable properties) {
            super(name, properties);
            this.className = className;
            this.segment = segment;
            this.transport = transport;
            this.protocol = protocol;

        }

    }

    class TransportBundle extends Bundle {
        public String className;

        public TransportBundle(String name, String className, Hashtable properties) {
            super(name, properties);
            this.className = className;
        }
    }

    class ProcessorBundle extends Bundle {
        public String className;
        public boolean shared = false;


        public ProcessorBundle(String name, String className, String shared, Hashtable properties) {
            super(name, properties);
            this.className = className;

            if (shared != null) {
                this.shared = shared.equals("true");
            }
        }
    }

    class Bundle {
        public String name;
        public Hashtable properties;

        public Bundle(String name, Hashtable properties) {
            this.name = name;
            this.properties = properties;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy