SDNC-11 merge
[sdnc/core.git] / sli / common / src / main / java / org / openecomp / sdnc / sli / SvcLogicParser.java
index 0e06b9e..3aa4068 100644 (file)
-/*-
+/*-\r
  * ============LICENSE_START=======================================================
  * openECOMP : SDN-C
  * ================================================================================
  * Copyright (C) 2017 AT&T Intellectual Property. All rights
  *                                             reserved.
  * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
  * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.openecomp.sdnc.sli;
-
-import java.io.File;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.LinkedList;
-
-import javax.xml.XMLConstants;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.Attributes;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXNotRecognizedException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * @author dt5972
- *
- */
-public class SvcLogicParser {
-
-    SvcLogicStore store = null;
-    static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
-    static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
-    static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
-    static final String JAXP_DYNAMIC_VALIDATION = "http://apache.org/xml/features/validation/dynamic";
-    static final String JAXP_SCHEMA_VALIDATION = "http://apache.org/xml/features/validation/schema";
-
-    private static final String LOAD_MESSAGE = "Getting SvcLogicGraph from database - ";
-    private static final String LOAD_ERROR_MESSAGE = "SvcLogicGraph not found - ";
-    private static final String ACTIVATION_ERROR_MESSAGE = "Could not activate SvcLogicGraph - ";
-    private static final String PRINT_ERROR_MESSAGE = "Could not print SvcLogicGraph - ";
-    private static final String SVC_LOGIC_STORE_ERROR = "Could not get service logic store";
-
-    private static final Logger LOGGER = LoggerFactory.getLogger(SvcLogicParser.class);
-    private static final String SLI_VALIDATING_PARSER = "org.openecomp.sdnc.sli.parser.validate";
-    private static final String SVCLOGIC_XSD = "/svclogic.xsd";
-
-    private class SvcLogicHandler extends DefaultHandler {
-    private Locator locator = null;
-    private String module = null;
-    private String version = null;
-    private LinkedList<SvcLogicGraph> graphs = null;
-    private SvcLogicGraph curGraph = null;
-    private SvcLogicNode curNode = null;
-    private LinkedList<SvcLogicNode> nodeStack = null;
-    private int curNodeId = 0;
-    private String outcomeValue = null;
-    private LinkedList<String> outcomeStack = null;
-    private SvcLogicStore svcLogicStore = null;
-
-    public SvcLogicHandler(LinkedList<SvcLogicGraph> graphs, SvcLogicStore store) {
-        this.graphs = graphs;
-        this.curNode = null;
-        this.nodeStack = new LinkedList<>();
-        this.outcomeStack = new LinkedList<>();
-        this.curNodeId = 1;
-        this.outcomeValue = null;
-        this.svcLogicStore = store;
-
-    }
-
-    @Override
-       public void setDocumentLocator(Locator locator) {
-        this.locator = locator;
-    }
-
-    @Override
-    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
-
-        // Handle service-logic (graph) tag
-        if ("service-logic".equalsIgnoreCase(qName)) {
-
-        module = attributes.getValue("module");
-        if (module == null || module.length() == 0) {
-            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Missing 'module' attribute from service-logic tag");
-        }
-
-        version = attributes.getValue("version");
-        if (version == null || version.length() == 0) {
-            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Missing 'version' attribute from service-logic tag");
-        }
-
-        return;
-        }
-
-        if ("method".equalsIgnoreCase(qName)) {
-        if (curGraph != null) {
-            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Cannot nest module tags");
-        }
-        curGraph = new SvcLogicGraph();
-        curGraph.setModule(module);
-        curGraph.setVersion(version);
-        this.curNodeId = 1;
-
-        String attrValue = attributes.getValue("rpc");
-        if (attrValue == null || attrValue.length() == 0) {
-            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Missing 'rpc' attribute for method tag");
-        }
-        curGraph.setRpc(attrValue);
-
-        attrValue = attributes.getValue("mode");
-        if (attrValue == null || attrValue.length() == 0) {
-            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Missing 'mode' attribute for method tag");
-        }
-        curGraph.setMode(attrValue);
-
-        return;
-
-        }
-
-        // Handle outcome (edge) tag
-        if ("outcome".equalsIgnoreCase(qName)) {
-        String refValue = attributes.getValue("ref");
-
-        if (refValue != null) {
-            SvcLogicNode refNode = curGraph.getNamedNode(refValue);
-
-            if (refNode != null) {
-            try {
-                curNode.addOutcome(attributes.getValue("value"), refNode);
-            } catch (SvcLogicException e) {
-                throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Cannot add outcome", e);
-            }
-            } else {
-            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "ref to unknown node " + refValue);
-            }
-            return;
-        }
-
-        if (outcomeValue != null) {
-            outcomeStack.push(outcomeValue);
-        }
-        outcomeValue = attributes.getValue("value");
-
-        return;
-        }
-
-        // Handle parameter tag
-        if ("parameter".equalsIgnoreCase(qName)) {
-        String parmName = attributes.getValue("name");
-        String parmValue = attributes.getValue("value");
-
-        if (parmName != null && parmName.length() > 0 && parmValue != null) {
-            try {
-
-            curNode.mapParameter(parmName, parmValue);
-            } catch (Exception e) {
-            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + " cannot set parameter " + parmName + " to " + parmValue + " [" + e.getMessage() + "]");
-            }
-        }
-
-        return;
-        }
-
-        // Handle node tags
-
-        String nodeName = attributes.getValue("name");
-        SvcLogicNode thisNode = null;
-
-        try {
-        if (!svcLogicStore.isValidNodeType(qName)) {
-            throw new SAXNotRecognizedException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Unknown tag " + qName);
-        }
-        } catch (Exception e) {
-        throw new SAXNotRecognizedException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Cannot validate node type " + qName);
-        }
-
-        try {
-        if (nodeName != null && nodeName.length() > 0) {
-            thisNode = new SvcLogicNode(curNodeId++, qName, nodeName, curGraph);
-        } else {
-            thisNode = new SvcLogicNode(curNodeId++, qName, curGraph);
-        }
-
-        if (curGraph.getRootNode() == null) {
-            curGraph.setRootNode(thisNode);
-        }
-        } catch (SvcLogicException e) {
-        throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + e.getMessage());
-
-        }
-
-        int numAttributes = attributes.getLength();
-
-        for (int i = 0; i < numAttributes; i++) {
-        String attrName = attributes.getQName(i);
-        if (!"name".equalsIgnoreCase(attrName)) {
-            try {
-
-            String attrValueStr = attributes.getValue(i);
-            SvcLogicExpression attrValue = null;
-            if (attrValueStr.trim().startsWith("`")) {
-                int lastParen = attrValueStr.lastIndexOf("`");
-                String evalExpr = attrValueStr.trim().substring(1, lastParen);
-                attrValue = SvcLogicExpressionFactory.parse(evalExpr);
-
-            } else {
-                if (Character.isDigit(attrValueStr.charAt(0))) {
-                attrValue = new SvcLogicAtom("NUMBER", attrValueStr);
-                } else {
-                attrValue = new SvcLogicAtom("STRING", attrValueStr);
-                }
-            }
-            thisNode.setAttribute(attrName, attrValue);
-            } catch (Exception e) {
-            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Cannot set attribute " + attrName, e);
-            }
-        }
-        }
-
-        if (curNode != null) {
-        try {
-            if ("block".equalsIgnoreCase(curNode.getNodeType()) || "for".equalsIgnoreCase(curNode.getNodeType())) {
-            curNode.addOutcome("" + (curNode.getNumOutcomes() + 1), thisNode);
-            } else {
-            if (outcomeValue == null) {
-                throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + curNode.getNodeType() + " node expects outcome, instead found " + thisNode.getNodeType());
-            }
-            curNode.addOutcome(outcomeValue, thisNode);
-            }
-        } catch (SvcLogicException e) {
-            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + e.getMessage());
-        }
-        nodeStack.push(curNode);
-        }
-        curNode = thisNode;
-
-    }
-
-    @Override
-    public void endElement(String uri, String localName, String qName) throws SAXException {
-
-        // Handle close of service-logic tag
-        if ("service-logic".equalsIgnoreCase(qName)) {
-        // Nothing more to do
-        return;
-        }
-
-        // Handle close of method tag
-        if ("method".equalsIgnoreCase(qName)) {
-        graphs.add(curGraph);
-        curGraph = null;
-        return;
-        }
-
-        // Handle close of outcome tag
-        if ("outcome".equalsIgnoreCase(qName)) {
-        // Finished this outcome - pop the outcome stack
-        if (outcomeStack.isEmpty()) {
-            outcomeValue = null;
-        } else {
-            outcomeValue = outcomeStack.pop();
-        }
-        return;
-        }
-
-        // Handle close of parameter tag - do nothing
-        if ("parameter".equalsIgnoreCase(qName)) {
-        return;
-        }
-
-        // Handle close of a node tag
-        if (nodeStack.isEmpty()) {
-        curNode = null;
-        } else {
-        curNode = nodeStack.pop();
-        }
-    }
-
-    @Override
-    public void error(SAXParseException arg0) throws SAXException {
-        throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + arg0.getMessage());
-    }
-
-    }
-
-    public SvcLogicParser(SvcLogicStore store) {
-    this.store = store;
-    }
-
-    public SvcLogicParser(String propFile) {
-
-    try {
-        this.store = SvcLogicStoreFactory.getSvcLogicStore(propFile);
-    } catch (Exception e) {
-        LOGGER.error(SVC_LOGIC_STORE_ERROR, e);
-
-    }
-
-    }
-
-    public SvcLogicParser(InputStream propStr) {
-
-    try {
-        this.store = SvcLogicStoreFactory.getSvcLogicStore(propStr);
-    } catch (Exception e) {
-        LOGGER.error(SVC_LOGIC_STORE_ERROR, e);
-
-    }
-
-    }
-
-    public LinkedList<SvcLogicGraph> parse(String fileName) throws SvcLogicException {
-    LinkedList<SvcLogicGraph> graphs = null;
-
-    URL xsdUrl = null;
-    Schema schema = null;
-    String validateSchema = System.getProperty(SLI_VALIDATING_PARSER, "true");
-
-    if (validateSchema != null || validateSchema.equalsIgnoreCase("true")) {
-        xsdUrl = getClass().getResource(SVCLOGIC_XSD);
-
-    }
-
-    if (xsdUrl != null) {
-        try {
-        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-        schema = schemaFactory.newSchema(xsdUrl);
-        } catch (Exception e) {
-        LOGGER.warn("Could not validate using schema " + xsdUrl.getPath(), e);
-        }
-    } else {
-        LOGGER.warn("Could not find resource " + SVCLOGIC_XSD);
-    }
-
-    try {
-        SAXParserFactory factory = SAXParserFactory.newInstance();
-
-        if (schema != null) {
-        factory.setNamespaceAware(true);
-        factory.setSchema(schema);
-        }
-        SAXParser saxParser = factory.newSAXParser();
-
-        if (saxParser.isValidating()) {
-        LOGGER.info("Validating against schema " + xsdUrl.getPath());
-        }
-        graphs = new LinkedList<>();
-
-        saxParser.parse(fileName, new SvcLogicHandler(graphs, store));
-
-    } catch (Exception e) {
-        String msg = e.getMessage();
-        if (msg != null) {
-        LOGGER.error(msg);
-        throw new SvcLogicException("Compiler error: " + fileName + " @ " + msg);
-        } else {
-        LOGGER.info("Caught exception parsing " + fileName, e);
-        throw new SvcLogicException("Compiler error: " + fileName, e);
-        }
-    }
-
-    return graphs;
-    }
-
-    public static void main(String argv[]) {
-
-    if (argv.length == 0) {
-        SvcLogicParser.usage();
-    }
-
-    if ("load".equalsIgnoreCase(argv[0])) {
-        if (argv.length == 3) {
-        String xmlfile = argv[1];
-        String propfile = argv[2];
-
-        SvcLogicStore store = SvcLogicParser.getStore(propfile);
-        try {
-            SvcLogicParser.load(xmlfile, store);
-        } catch (Exception e) {
-            LOGGER.error(e.getMessage(), e);
-        }
-        } else {
-        SvcLogicParser.usage();
-        }
-    } else if ("print".equalsIgnoreCase(argv[0])) {
-        String version = null;
-        String propfile = null;
-
-        switch (argv.length) {
-        case 6:
-        version = argv[4];
-        propfile = argv[5];
-        case 5:
-        if (propfile == null) {
-            propfile = argv[4];
-        }
-        SvcLogicStore store = SvcLogicParser.getStore(propfile);
-        SvcLogicParser.print(argv[1], argv[2], argv[3], version, store);
-        break;
-        default:
-        SvcLogicParser.usage();
-        }
-    } else if ("get-source".equalsIgnoreCase(argv[0])) {
-
-        switch (argv.length) {
-        case 6:
-        SvcLogicStore store = SvcLogicParser.getStore(argv[5]);
-        SvcLogicParser.getSource(argv[1], argv[2], argv[3], argv[4], store);
-        break;
-        default:
-        SvcLogicParser.usage();
-        }
-    } else if ("activate".equalsIgnoreCase(argv[0])) {
-        if (argv.length == 6) {
-        SvcLogicStore store = SvcLogicParser.getStore(argv[5]);
-        SvcLogicParser.activate(argv[1], argv[2], argv[3], argv[4], store);
-        } else {
-        SvcLogicParser.usage();
-        }
-    } else if ("validate".equalsIgnoreCase(argv[0])) {
-        if (argv.length == 3) {
-        String xmlfile = argv[1];
-        String propfile = argv[2];
-
-        System.setProperty(SLI_VALIDATING_PARSER, "true");
-        SvcLogicStore store = SvcLogicParser.getStore(propfile);
-        try {
-            SvcLogicParser.validate(xmlfile, store);
-        } catch (Exception e) {
-            LOGGER.error(e.getMessage(), e);
-        }
-        } else {
-        SvcLogicParser.usage();
-        }
-    }
-
-    System.exit(0);
-    }
-
-    private static SvcLogicStore getStore(String propfile) {
-
-    SvcLogicStore store = null;
-
-    try {
-        store = SvcLogicStoreFactory.getSvcLogicStore(propfile);
-    } catch (Exception e) {
-        LOGGER.error(SVC_LOGIC_STORE_ERROR, e);
-        System.exit(1);
-    }
-
-    return store;
-
-    }
-
-    public static void load(String xmlfile, SvcLogicStore store) throws SvcLogicException {
-    File xmlFile = new File(xmlfile);
-    if (!xmlFile.canRead()) {
-        throw new ConfigurationException("Cannot read xml file (" + xmlfile + ")");
-    }
-
-    SvcLogicParser parser = new SvcLogicParser(store);
-    LinkedList<SvcLogicGraph> graphs = null;
-    try {
-        graphs = parser.parse(xmlfile);
-    } catch (Exception e) {
-        throw new SvcLogicException(e.getMessage(), e);
-    }
-
-    if (graphs == null) {
-        throw new SvcLogicException("Could not parse " + xmlfile);
-    }
-
-    for (SvcLogicGraph graph : graphs) {
-
-        String module = graph.getModule();
-        String rpc = graph.getRpc();
-        String version = graph.getVersion();
-        String mode = graph.getMode();
-        try {
-        LOGGER.info("Saving SvcLogicGraph to database (module:" + module + ",rpc:" + rpc + ",version:" + version + ",mode:" + mode + ")");
-        store.store(graph);
-        } catch (Exception e) {
-        throw new SvcLogicException(e.getMessage(), e);
-        }
-
-    }
-
-    }
-
-    public static void validate(String xmlfile, SvcLogicStore store) throws SvcLogicException {
-    File xmlFile = new File(xmlfile);
-    if (!xmlFile.canRead()) {
-        throw new ConfigurationException("Cannot read xml file (" + xmlfile + ")");
-    }
-
-    SvcLogicParser parser = new SvcLogicParser(store);
-    LinkedList<SvcLogicGraph> graphs = null;
-    try {
-        LOGGER.info("Validating " + xmlfile);
-        graphs = parser.parse(xmlfile);
-    } catch (Exception e) {
-        throw new SvcLogicException(e.getMessage(), e);
-    }
-
-    if (graphs == null) {
-        throw new SvcLogicException("Could not parse " + xmlfile);
-    } else {
-        LOGGER.info("Compilation successful for " + xmlfile);
-    }
-
-    }
-
-    private static void print(String module, String rpc, String mode, String version, SvcLogicStore store) {
-    String details = "(module:" + module + ", rpc:" + rpc + ", version:" + version + ", mode:" + mode + ")";
-
-    try {
-        LOGGER.info(LOAD_MESSAGE + details);
-
-        SvcLogicGraph graph = store.fetch(module, rpc, version, mode);
-        if (graph == null) {
-        LOGGER.error(LOAD_ERROR_MESSAGE + details);
-        System.exit(1);
-        }
-        graph.printAsGv(System.out);
-    } catch (Exception e) {
-        LOGGER.error(PRINT_ERROR_MESSAGE + details, e);
-        System.exit(1);
-    }
-
-    }
-
-    private static void getSource(String module, String rpc, String mode, String version, SvcLogicStore store) {
-    String details = "(module:" + module + ", rpc:" + rpc + ", version:" + version + ", mode:" + mode + ")";
-
-    try {
-        LOGGER.info(LOAD_MESSAGE + details);
-
-        SvcLogicGraph graph = store.fetch(module, rpc, version, mode);
-        if (graph == null) {
-        LOGGER.error(LOAD_ERROR_MESSAGE + details);
-        System.exit(1);
-        }
-        graph.printAsXml(System.out);
-    } catch (Exception e) {
-        LOGGER.error(PRINT_ERROR_MESSAGE + details, e);
-        System.exit(1);
-    }
-
-    }
-
-    private static void activate(String module, String rpc, String version, String mode, SvcLogicStore store) {
-    String details = "(module:" + module + ", rpc:" + rpc + ", version:" + version + ", mode:" + mode + ")";
-
-    try {
-        LOGGER.info(LOAD_MESSAGE + details);
-
-        SvcLogicGraph graph = store.fetch(module, rpc, version, mode);
-        if (graph == null) {
-        LOGGER.error(LOAD_ERROR_MESSAGE + details);
-        System.exit(1);
-        }
-        store.activate(graph);
-    } catch (Exception e) {
-        LOGGER.error(ACTIVATION_ERROR_MESSAGE + details, e);
-        System.exit(1);
-    }
-
-    }
-
-    private static void usage() {
-    System.err.println("Usage: SvcLogicParser load <xml-file> <prop-file>");
-    System.err.println(" OR    SvcLogicParser print <module> <rpc> <mode> [<version>] <prop-file>");
-    System.err.println(" OR    SvcLogicParser get-source <module> <rpc> <mode> <version> <prop-file>");
-    System.err.println(" OR    SvcLogicParser activate <module> <rpc> <version> <mode>");
-    System.exit(1);
-    }
-
-}
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.openecomp.sdnc.sli;\r
+\r
+import java.io.File;\r
+import java.io.InputStream;\r
+import java.net.URL;\r
+import java.util.LinkedList;\r
+\r
+import javax.xml.XMLConstants;\r
+import javax.xml.parsers.SAXParser;\r
+import javax.xml.parsers.SAXParserFactory;\r
+import javax.xml.validation.Schema;\r
+import javax.xml.validation.SchemaFactory;\r
+\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.xml.sax.Attributes;\r
+import org.xml.sax.Locator;\r
+import org.xml.sax.SAXException;\r
+import org.xml.sax.SAXNotRecognizedException;\r
+import org.xml.sax.SAXParseException;\r
+import org.xml.sax.helpers.DefaultHandler;\r
+\r
+/**\r
+ * @author dt5972\r
+ *\r
+ */\r
+public class SvcLogicParser {\r
+\r
+    SvcLogicStore store = null;\r
+    static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";\r
+    static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";\r
+    static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";\r
+    static final String JAXP_DYNAMIC_VALIDATION = "http://apache.org/xml/features/validation/dynamic";\r
+    static final String JAXP_SCHEMA_VALIDATION = "http://apache.org/xml/features/validation/schema";\r
+\r
+    private static final String LOAD_MESSAGE = "Getting SvcLogicGraph from database - ";\r
+    private static final String LOAD_ERROR_MESSAGE = "SvcLogicGraph not found - ";\r
+    private static final String ACTIVATION_ERROR_MESSAGE = "Could not activate SvcLogicGraph - ";\r
+    private static final String PRINT_ERROR_MESSAGE = "Could not print SvcLogicGraph - ";\r
+    private static final String SVC_LOGIC_STORE_ERROR = "Could not get service logic store";\r
+\r
+    private static final Logger LOGGER = LoggerFactory.getLogger(SvcLogicParser.class);\r
+    private static final String SLI_VALIDATING_PARSER = "org.openecomp.sdnc.sli.parser.validate";\r
+    private static final String SVCLOGIC_XSD = "/svclogic.xsd";\r
+\r
+    private class SvcLogicHandler extends DefaultHandler {\r
+    private Locator locator = null;\r
+    private String module = null;\r
+    private String version = null;\r
+    private LinkedList<SvcLogicGraph> graphs = null;\r
+    private SvcLogicGraph curGraph = null;\r
+    private SvcLogicNode curNode = null;\r
+    private LinkedList<SvcLogicNode> nodeStack = null;\r
+    private int curNodeId = 0;\r
+    private String outcomeValue = null;\r
+    private LinkedList<String> outcomeStack = null;\r
+    private SvcLogicStore svcLogicStore = null;\r
+\r
+    public SvcLogicHandler(LinkedList<SvcLogicGraph> graphs, SvcLogicStore store) {\r
+        this.graphs = graphs;\r
+        this.curNode = null;\r
+        this.nodeStack = new LinkedList<>();\r
+        this.outcomeStack = new LinkedList<>();\r
+        this.curNodeId = 1;\r
+        this.outcomeValue = null;\r
+        this.svcLogicStore = store;\r
+\r
+    }\r
+\r
+    @Override\r
+       public void setDocumentLocator(Locator locator) {\r
+        this.locator = locator;\r
+    }\r
+\r
+    @Override\r
+    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {\r
+\r
+        // Handle service-logic (graph) tag\r
+        if ("service-logic".equalsIgnoreCase(qName)) {\r
+\r
+        module = attributes.getValue("module");\r
+        if (module == null || module.length() == 0) {\r
+            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Missing 'module' attribute from service-logic tag");\r
+        }\r
+\r
+        version = attributes.getValue("version");\r
+        if (version == null || version.length() == 0) {\r
+            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Missing 'version' attribute from service-logic tag");\r
+        }\r
+\r
+        return;\r
+        }\r
+\r
+        if ("method".equalsIgnoreCase(qName)) {\r
+        if (curGraph != null) {\r
+            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Cannot nest module tags");\r
+        }\r
+        curGraph = new SvcLogicGraph();\r
+        curGraph.setModule(module);\r
+        curGraph.setVersion(version);\r
+        this.curNodeId = 1;\r
+\r
+        String attrValue = attributes.getValue("rpc");\r
+        if (attrValue == null || attrValue.length() == 0) {\r
+            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Missing 'rpc' attribute for method tag");\r
+        }\r
+        curGraph.setRpc(attrValue);\r
+\r
+        attrValue = attributes.getValue("mode");\r
+        if (attrValue == null || attrValue.length() == 0) {\r
+            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Missing 'mode' attribute for method tag");\r
+        }\r
+        curGraph.setMode(attrValue);\r
+\r
+        return;\r
+\r
+        }\r
+\r
+        // Handle outcome (edge) tag\r
+        if ("outcome".equalsIgnoreCase(qName)) {\r
+        String refValue = attributes.getValue("ref");\r
+\r
+        if (refValue != null) {\r
+            SvcLogicNode refNode = curGraph.getNamedNode(refValue);\r
+\r
+            if (refNode != null) {\r
+            try {\r
+                curNode.addOutcome(attributes.getValue("value"), refNode);\r
+            } catch (SvcLogicException e) {\r
+                throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Cannot add outcome", e);\r
+            }\r
+            } else {\r
+            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "ref to unknown node " + refValue);\r
+            }\r
+            return;\r
+        }\r
+\r
+        if (outcomeValue != null) {\r
+            outcomeStack.push(outcomeValue);\r
+        }\r
+        outcomeValue = attributes.getValue("value");\r
+\r
+        return;\r
+        }\r
+\r
+        // Handle parameter tag\r
+        if ("parameter".equalsIgnoreCase(qName)) {\r
+        String parmName = attributes.getValue("name");\r
+        String parmValue = attributes.getValue("value");\r
+\r
+        if (parmName != null && parmName.length() > 0 && parmValue != null) {\r
+            try {\r
+\r
+            curNode.mapParameter(parmName, parmValue);\r
+            } catch (Exception e) {\r
+            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + " cannot set parameter " + parmName + " to " + parmValue + " [" + e.getMessage() + "]");\r
+            }\r
+        }\r
+\r
+        return;\r
+        }\r
+\r
+        // Handle node tags\r
+\r
+        String nodeName = attributes.getValue("name");\r
+        SvcLogicNode thisNode = null;\r
+\r
+        try {\r
+        if (!svcLogicStore.isValidNodeType(qName)) {\r
+            throw new SAXNotRecognizedException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Unknown tag " + qName);\r
+        }\r
+        } catch (Exception e) {\r
+        throw new SAXNotRecognizedException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Cannot validate node type " + qName);\r
+        }\r
+\r
+        try {\r
+        if (nodeName != null && nodeName.length() > 0) {\r
+            thisNode = new SvcLogicNode(curNodeId++, qName, nodeName, curGraph);\r
+        } else {\r
+            thisNode = new SvcLogicNode(curNodeId++, qName, curGraph);\r
+        }\r
+\r
+        if (curGraph.getRootNode() == null) {\r
+            curGraph.setRootNode(thisNode);\r
+        }\r
+        } catch (SvcLogicException e) {\r
+        throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + e.getMessage());\r
+\r
+        }\r
+\r
+        int numAttributes = attributes.getLength();\r
+\r
+        for (int i = 0; i < numAttributes; i++) {\r
+        String attrName = attributes.getQName(i);\r
+        if (!"name".equalsIgnoreCase(attrName)) {\r
+            try {\r
+\r
+            String attrValueStr = attributes.getValue(i);\r
+            SvcLogicExpression attrValue = null;\r
+            if (attrValueStr.trim().startsWith("`")) {\r
+                int lastParen = attrValueStr.lastIndexOf("`");\r
+                String evalExpr = attrValueStr.trim().substring(1, lastParen);\r
+                attrValue = SvcLogicExpressionFactory.parse(evalExpr);\r
+\r
+            } else {\r
+                if (Character.isDigit(attrValueStr.charAt(0))) {\r
+                attrValue = new SvcLogicAtom("NUMBER", attrValueStr);\r
+                } else {\r
+                attrValue = new SvcLogicAtom("STRING", attrValueStr);\r
+                }\r
+            }\r
+            thisNode.setAttribute(attrName, attrValue);\r
+            } catch (Exception e) {\r
+            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Cannot set attribute " + attrName, e);\r
+            }\r
+        }\r
+        }\r
+\r
+        if (curNode != null) {\r
+        try {\r
+            if ("block".equalsIgnoreCase(curNode.getNodeType()) || "for".equalsIgnoreCase(curNode.getNodeType()) || "while".equalsIgnoreCase(curNode.getNodeType())) {\r
+            curNode.addOutcome("" + (curNode.getNumOutcomes() + 1), thisNode);\r
+            } else {\r
+            if (outcomeValue == null) {\r
+                throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + curNode.getNodeType() + " node expects outcome, instead found " + thisNode.getNodeType());\r
+            }\r
+            curNode.addOutcome(outcomeValue, thisNode);\r
+            }\r
+        } catch (SvcLogicException e) {\r
+            throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + e.getMessage());\r
+        }\r
+        nodeStack.push(curNode);\r
+        }\r
+        curNode = thisNode;\r
+\r
+    }\r
+\r
+    @Override\r
+    public void endElement(String uri, String localName, String qName) throws SAXException {\r
+\r
+        // Handle close of service-logic tag\r
+        if ("service-logic".equalsIgnoreCase(qName)) {\r
+        // Nothing more to do\r
+        return;\r
+        }\r
+\r
+        // Handle close of method tag\r
+        if ("method".equalsIgnoreCase(qName)) {\r
+        graphs.add(curGraph);\r
+        curGraph = null;\r
+        return;\r
+        }\r
+\r
+        // Handle close of outcome tag\r
+        if ("outcome".equalsIgnoreCase(qName)) {\r
+        // Finished this outcome - pop the outcome stack\r
+        if (outcomeStack.isEmpty()) {\r
+            outcomeValue = null;\r
+        } else {\r
+            outcomeValue = outcomeStack.pop();\r
+        }\r
+        return;\r
+        }\r
+\r
+        // Handle close of parameter tag - do nothing\r
+        if ("parameter".equalsIgnoreCase(qName)) {\r
+        return;\r
+        }\r
+\r
+        // Handle close of a node tag\r
+        if (nodeStack.isEmpty()) {\r
+        curNode = null;\r
+        } else {\r
+        curNode = nodeStack.pop();\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void error(SAXParseException arg0) throws SAXException {\r
+        throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + arg0.getMessage());\r
+    }\r
+\r
+    }\r
+\r
+    public SvcLogicParser(SvcLogicStore store) {\r
+    this.store = store;\r
+    }\r
+\r
+    public SvcLogicParser(String propFile) {\r
+\r
+    try {\r
+        this.store = SvcLogicStoreFactory.getSvcLogicStore(propFile);\r
+    } catch (Exception e) {\r
+        LOGGER.error(SVC_LOGIC_STORE_ERROR, e);\r
+\r
+    }\r
+\r
+    }\r
+\r
+    public SvcLogicParser(InputStream propStr) {\r
+\r
+    try {\r
+        this.store = SvcLogicStoreFactory.getSvcLogicStore(propStr);\r
+    } catch (Exception e) {\r
+        LOGGER.error(SVC_LOGIC_STORE_ERROR, e);\r
+\r
+    }\r
+\r
+    }\r
+\r
+    public LinkedList<SvcLogicGraph> parse(String fileName) throws SvcLogicException {\r
+    LinkedList<SvcLogicGraph> graphs = null;\r
+\r
+    URL xsdUrl = null;\r
+    Schema schema = null;\r
+    String validateSchema = System.getProperty(SLI_VALIDATING_PARSER, "true");\r
+\r
+    if (validateSchema != null || validateSchema.equalsIgnoreCase("true")) {\r
+        xsdUrl = getClass().getResource(SVCLOGIC_XSD);\r
+\r
+    }\r
+\r
+    if (xsdUrl != null) {\r
+        try {\r
+        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);\r
+        schema = schemaFactory.newSchema(xsdUrl);\r
+        } catch (Exception e) {\r
+        LOGGER.warn("Could not validate using schema " + xsdUrl.getPath(), e);\r
+        }\r
+    } else {\r
+        LOGGER.warn("Could not find resource " + SVCLOGIC_XSD);\r
+    }\r
+\r
+    try {\r
+        SAXParserFactory factory = SAXParserFactory.newInstance();\r
+\r
+        if (schema != null) {\r
+        factory.setNamespaceAware(true);\r
+        factory.setSchema(schema);\r
+        }\r
+        SAXParser saxParser = factory.newSAXParser();\r
+\r
+        if (saxParser.isValidating()) {\r
+        LOGGER.info("Validating against schema " + xsdUrl.getPath());\r
+        }\r
+        graphs = new LinkedList<>();\r
+\r
+        saxParser.parse(fileName, new SvcLogicHandler(graphs, store));\r
+\r
+    } catch (Exception e) {\r
+        String msg = e.getMessage();\r
+        if (msg != null) {\r
+        LOGGER.error(msg);\r
+        throw new SvcLogicException("Compiler error: " + fileName + " @ " + msg);\r
+        } else {\r
+        LOGGER.info("Caught exception parsing " + fileName, e);\r
+        throw new SvcLogicException("Compiler error: " + fileName, e);\r
+        }\r
+    }\r
+\r
+    return graphs;\r
+    }\r
+\r
+    public static void main(String argv[]) {\r
+\r
+    if (argv.length == 0) {\r
+        SvcLogicParser.usage();\r
+    }\r
+\r
+    if ("load".equalsIgnoreCase(argv[0])) {\r
+        if (argv.length == 3) {\r
+        String xmlfile = argv[1];\r
+        String propfile = argv[2];\r
+\r
+        SvcLogicStore store = SvcLogicParser.getStore(propfile);\r
+        try {\r
+            SvcLogicParser.load(xmlfile, store);\r
+        } catch (Exception e) {\r
+            LOGGER.error(e.getMessage(), e);\r
+        }\r
+        } else {\r
+        SvcLogicParser.usage();\r
+        }\r
+    } else if ("print".equalsIgnoreCase(argv[0])) {\r
+        String version = null;\r
+        String propfile = null;\r
+\r
+        switch (argv.length) {\r
+        case 6:\r
+        version = argv[4];\r
+        propfile = argv[5];\r
+        case 5:\r
+        if (propfile == null) {\r
+            propfile = argv[4];\r
+        }\r
+        SvcLogicStore store = SvcLogicParser.getStore(propfile);\r
+        SvcLogicParser.print(argv[1], argv[2], argv[3], version, store);\r
+        break;\r
+        default:\r
+        SvcLogicParser.usage();\r
+        }\r
+    } else if ("get-source".equalsIgnoreCase(argv[0])) {\r
+\r
+        switch (argv.length) {\r
+        case 6:\r
+        SvcLogicStore store = SvcLogicParser.getStore(argv[5]);\r
+        SvcLogicParser.getSource(argv[1], argv[2], argv[3], argv[4], store);\r
+        break;\r
+        default:\r
+        SvcLogicParser.usage();\r
+        }\r
+    } else if ("activate".equalsIgnoreCase(argv[0])) {\r
+        if (argv.length == 6) {\r
+        SvcLogicStore store = SvcLogicParser.getStore(argv[5]);\r
+        SvcLogicParser.activate(argv[1], argv[2], argv[3], argv[4], store);\r
+        } else {\r
+        SvcLogicParser.usage();\r
+        }\r
+    } else if ("validate".equalsIgnoreCase(argv[0])) {\r
+        if (argv.length == 3) {\r
+        String xmlfile = argv[1];\r
+        String propfile = argv[2];\r
+\r
+        System.setProperty(SLI_VALIDATING_PARSER, "true");\r
+        SvcLogicStore store = SvcLogicParser.getStore(propfile);\r
+        try {\r
+            SvcLogicParser.validate(xmlfile, store);\r
+        } catch (Exception e) {\r
+            LOGGER.error(e.getMessage(), e);\r
+        }\r
+        } else {\r
+        SvcLogicParser.usage();\r
+        }\r
+    }\r
+\r
+    System.exit(0);\r
+    }\r
+\r
+    private static SvcLogicStore getStore(String propfile) {\r
+\r
+    SvcLogicStore store = null;\r
+\r
+    try {\r
+        store = SvcLogicStoreFactory.getSvcLogicStore(propfile);\r
+    } catch (Exception e) {\r
+        LOGGER.error(SVC_LOGIC_STORE_ERROR, e);\r
+        System.exit(1);\r
+    }\r
+\r
+    return store;\r
+\r
+    }\r
+\r
+    public static void load(String xmlfile, SvcLogicStore store) throws SvcLogicException {\r
+    File xmlFile = new File(xmlfile);\r
+    if (!xmlFile.canRead()) {\r
+        throw new ConfigurationException("Cannot read xml file (" + xmlfile + ")");\r
+    }\r
+\r
+    SvcLogicParser parser = new SvcLogicParser(store);\r
+    LinkedList<SvcLogicGraph> graphs = null;\r
+    try {\r
+        graphs = parser.parse(xmlfile);\r
+    } catch (Exception e) {\r
+        throw new SvcLogicException(e.getMessage(), e);\r
+    }\r
+\r
+    if (graphs == null) {\r
+        throw new SvcLogicException("Could not parse " + xmlfile);\r
+    }\r
+\r
+    for (SvcLogicGraph graph : graphs) {\r
+\r
+        String module = graph.getModule();\r
+        String rpc = graph.getRpc();\r
+        String version = graph.getVersion();\r
+        String mode = graph.getMode();\r
+        try {\r
+        LOGGER.info("Saving SvcLogicGraph to database (module:" + module + ",rpc:" + rpc + ",version:" + version + ",mode:" + mode + ")");\r
+        store.store(graph);\r
+        } catch (Exception e) {\r
+        throw new SvcLogicException(e.getMessage(), e);\r
+        }\r
+\r
+    }\r
+\r
+    }\r
+\r
+    public static void validate(String xmlfile, SvcLogicStore store) throws SvcLogicException {\r
+    File xmlFile = new File(xmlfile);\r
+    if (!xmlFile.canRead()) {\r
+        throw new ConfigurationException("Cannot read xml file (" + xmlfile + ")");\r
+    }\r
+\r
+    SvcLogicParser parser = new SvcLogicParser(store);\r
+    LinkedList<SvcLogicGraph> graphs = null;\r
+    try {\r
+        LOGGER.info("Validating " + xmlfile);\r
+        graphs = parser.parse(xmlfile);\r
+    } catch (Exception e) {\r
+        throw new SvcLogicException(e.getMessage(), e);\r
+    }\r
+\r
+    if (graphs == null) {\r
+        throw new SvcLogicException("Could not parse " + xmlfile);\r
+    } else {\r
+        LOGGER.info("Compilation successful for " + xmlfile);\r
+    }\r
+\r
+    }\r
+\r
+    private static void print(String module, String rpc, String mode, String version, SvcLogicStore store) {\r
+    String details = "(module:" + module + ", rpc:" + rpc + ", version:" + version + ", mode:" + mode + ")";\r
+\r
+    try {\r
+        LOGGER.info(LOAD_MESSAGE + details);\r
+\r
+        SvcLogicGraph graph = store.fetch(module, rpc, version, mode);\r
+        if (graph == null) {\r
+        LOGGER.error(LOAD_ERROR_MESSAGE + details);\r
+        System.exit(1);\r
+        }\r
+        graph.printAsGv(System.out);\r
+    } catch (Exception e) {\r
+        LOGGER.error(PRINT_ERROR_MESSAGE + details, e);\r
+        System.exit(1);\r
+    }\r
+\r
+    }\r
+\r
+    private static void getSource(String module, String rpc, String mode, String version, SvcLogicStore store) {\r
+    String details = "(module:" + module + ", rpc:" + rpc + ", version:" + version + ", mode:" + mode + ")";\r
+\r
+    try {\r
+        LOGGER.info(LOAD_MESSAGE + details);\r
+\r
+        SvcLogicGraph graph = store.fetch(module, rpc, version, mode);\r
+        if (graph == null) {\r
+        LOGGER.error(LOAD_ERROR_MESSAGE + details);\r
+        System.exit(1);\r
+        }\r
+        graph.printAsXml(System.out);\r
+    } catch (Exception e) {\r
+        LOGGER.error(PRINT_ERROR_MESSAGE + details, e);\r
+        System.exit(1);\r
+    }\r
+\r
+    }\r
+\r
+    private static void activate(String module, String rpc, String version, String mode, SvcLogicStore store) {\r
+    String details = "(module:" + module + ", rpc:" + rpc + ", version:" + version + ", mode:" + mode + ")";\r
+\r
+    try {\r
+        LOGGER.info(LOAD_MESSAGE + details);\r
+\r
+        SvcLogicGraph graph = store.fetch(module, rpc, version, mode);\r
+        if (graph == null) {\r
+        LOGGER.error(LOAD_ERROR_MESSAGE + details);\r
+        System.exit(1);\r
+        }\r
+        store.activate(graph);\r
+    } catch (Exception e) {\r
+        LOGGER.error(ACTIVATION_ERROR_MESSAGE + details, e);\r
+        System.exit(1);\r
+    }\r
+\r
+    }\r
+\r
+    private static void usage() {\r
+    System.err.println("Usage: SvcLogicParser load <xml-file> <prop-file>");\r
+    System.err.println(" OR    SvcLogicParser print <module> <rpc> <mode> [<version>] <prop-file>");\r
+    System.err.println(" OR    SvcLogicParser get-source <module> <rpc> <mode> <version> <prop-file>");\r
+    System.err.println(" OR    SvcLogicParser activate <module> <rpc> <version> <mode>");\r
+    System.exit(1);\r
+    }\r
+\r
+}\r