001: /*
002: * ====================================================================
003: *
004: * XFLOW - Process Management System
005: * Copyright (C) 2003 Rob Tan
006: * All rights reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: *
012: * 1. Redistributions of source code must retain the above copyright
013: * notice, this list of conditions, and the following disclaimer.
014: *
015: * 2. Redistributions in binary form must reproduce the above copyright
016: * notice, this list of conditions, and the disclaimer that follows
017: * these conditions in the documentation and/or other materials
018: * provided with the distribution.
019: *
020: * 3. The name "XFlow" must not be used to endorse or promote products
021: * derived from this software without prior written permission. For
022: * written permission, please contact rcktan@yahoo.com
023: *
024: * 4. Products derived from this software may not be called "XFlow", nor
025: * may "XFlow" appear in their name, without prior written permission
026: * from the XFlow Project Management (rcktan@yahoo.com)
027: *
028: * In addition, we request (but do not require) that you include in the
029: * end-user documentation provided with the redistribution and/or in the
030: * software itself an acknowledgement equivalent to the following:
031: * "This product includes software developed by the
032: * XFlow Project (http://xflow.sourceforge.net/)."
033: * Alternatively, the acknowledgment may be graphical using the logos
034: * available at http://xflow.sourceforge.net/
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL THE XFLOW AUTHORS OR THE PROJECT
040: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: *
049: * ====================================================================
050: * This software consists of voluntary contributions made by many
051: * individuals on behalf of the XFlow Project and was originally
052: * created by Rob Tan (rcktan@yahoo.com)
053: * For more information on the XFlow Project, please see:
054: * <http://xflow.sourceforge.net/>.
055: * ====================================================================
056: */
057:
058: package xflow.util;
059:
060: import org.w3c.dom.*;
061: import org.xml.sax.*;
062: import javax.xml.parsers.*;
063: import java.util.*;
064: import java.text.*;
065: import java.io.*;
066: import xflow.util.*;
067: import xflow.common.*;
068:
069: public class GraphXMLParser {
070:
071: public static DirectedGraph parseGxl(String xml, String graphName)
072: throws XflowException {
073:
074: // Create a graph instance
075: DirectedGraph rgraph = new DirectedGraph(graphName);
076:
077: HashMap pm = new HashMap();
078: HashMap rootc = new HashMap();
079:
080: // Parse the xml string
081: try {
082: DocumentBuilderFactory factory = DocumentBuilderFactory
083: .newInstance();
084: DocumentBuilder builder = factory.newDocumentBuilder();
085:
086: StringReader sreader = new StringReader(xml);
087: InputSource is = new InputSource(sreader);
088: Document doc = builder.parse(is);
089:
090: NodeList els = doc.getElementsByTagName("node");
091: int count = els.getLength();
092: for (int i = 0; i < count; i++) {
093: Element el = (Element) els.item(i);
094: String nodeId = el.getAttribute("id");
095: NodeList els2 = el.getElementsByTagName("string");
096: Element e = (Element) els2.item(0);
097: org.w3c.dom.Node node = e.getFirstChild();
098: String nodeString = node.getNodeValue();
099: xflow.common.Node gnode = getNode(nodeString);
100:
101: System.out.println("Putting: " + nodeId + " : "
102: + gnode.getNodeName() + " "
103: + gnode.getNodeType());
104: pm.put(nodeId, gnode);
105: }
106:
107: els = doc.getElementsByTagName("edge");
108: count = els.getLength();
109: for (int i = 0; i < count; i++) {
110: Element el = (Element) els.item(i);
111: String fromNodeId = el.getAttribute("from");
112: String toNodeId = el.getAttribute("to");
113: rootc.put(toNodeId, toNodeId);
114: xflow.common.Node fromNode = (xflow.common.Node) pm
115: .get(fromNodeId);
116: xflow.common.Node toNode = (xflow.common.Node) pm
117: .get(toNodeId);
118:
119: System.out.println(fromNode.getNodeName() + " to "
120: + toNode.getNodeName());
121: NodeList els2 = el.getElementsByTagName("string");
122: Element e = (Element) els2.item(0);
123: String rule = null;
124: if (e != null) {
125: org.w3c.dom.Node node = e.getFirstChild();
126: rule = node.getNodeValue();
127: System.out.println(rule);
128: }
129:
130: fromNode.addDestination(toNode, rule);
131: }
132:
133: } catch (Exception e) {
134: throw new XflowException(e.getMessage());
135: }
136:
137: try {
138: String rootNodeId = findRootNodeId(pm, rootc);
139: if (rootNodeId == null) {
140: throw new XflowException("No root node in graph");
141: }
142: xflow.common.Node rootNode = (xflow.common.Node) pm
143: .get(rootNodeId);
144: rgraph.setRootNode(rootNode);
145: rootNode.traverse();
146: } catch (Exception e) {
147: throw new XflowException(e.getMessage());
148: }
149:
150: return rgraph;
151: }
152:
153: public static String findRootNodeId(HashMap pm, HashMap rootc)
154: throws Exception {
155:
156: String result = null;
157:
158: Iterator itr = pm.keySet().iterator();
159: while (itr.hasNext()) {
160: String nid = (String) itr.next();
161: if (rootc.get(nid) == null) {
162: if (result == null) {
163: result = nid;
164: } else {
165: throw new Exception(
166: "Graph has more than one root node");
167: }
168: }
169: }
170: return result;
171: }
172:
173: public static xflow.common.Node getNode(String nodeString) {
174:
175: StringTokenizer strtok = new StringTokenizer(nodeString, ";");
176: String nodeName = null;
177: String nodeType = null;
178: String containee = null;
179:
180: while (strtok.hasMoreTokens()) {
181: String tok1 = strtok.nextToken();
182: StringTokenizer strtok2 = new StringTokenizer(tok1, "=");
183: String lhs = strtok2.nextToken();
184: String rhs = strtok2.nextToken();
185: lhs = lhs.trim();
186: rhs = rhs.trim();
187: if (lhs.equals("name")) {
188: nodeName = rhs;
189: } else if (lhs.equals("type")) {
190: nodeType = rhs;
191: if (nodeType.equals(xflow.common.Node.AND)) {
192: nodeName = "And";
193: }
194: } else if (lhs.equals("containee")) {
195: containee = rhs;
196: }
197: }
198:
199: xflow.common.Node gnode = new xflow.common.Node(nodeName,
200: nodeType);
201: if (containee != null) {
202: gnode.setContainee(containee);
203: }
204: return gnode;
205: }
206:
207: // Simple test
208: public static void main(String[] args) throws Exception {
209: String xml = "<gxl><graph><node id=\"n0\"><attr name=\"Label\"><string>name=Start;type=Start</string></attr></node></graph></gxl>";
210: DirectedGraph g = parseGxl(xml, args[0]);
211:
212: }
213: }
|