/*
* Copyright 2004 The Apache Software Foundation.
*
* 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
* limitations under the License.
*/
package org.apache.agila.util;
import org.apache.agila.model.BusinessProcess;
import org.apache.agila.model.Node;
import org.apache.agila.model.Actor;
import org.apache.agila.model.Binding;
import org.apache.agila.model.Variable;
import org.apache.agila.model.NodeID;
import org.apache.agila.impl.BusinessProcessImpl;
import org.apache.commons.beanutils.BeanUtils;
import org.dom4j.io.SAXReader;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Attribute;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
import java.util.List;
import java.util.Iterator;
import java.lang.reflect.InvocationTargetException;
/**
* Utility class for converting workflow XML to objects
*
*
* @author <a href="mailto:geir@gluecode.com">Geir Magnusson Jr.</a>
* @version $Id: XMLUtil.java 38 2005-06-01 19:39:54Z chirino $
*/
public class XMLUtil {
/**
* Turns an XML document of a workflow specification into
* a BusinessProcess object
*
* @param doc
* @return
*/
public static BusinessProcess deserializeXML(Reader doc) {
BusinessProcessImpl graph = new BusinessProcessImpl();
SAXReader reader = new SAXReader();
try {
Document d = reader.read(doc);
graph.setGraphAsXML(d.asXML());
graph.setName(d.getRootElement().attribute("name").getValue());
Element e = (Element) d.getRootElement().selectSingleNode("graph");
/*
* grab and process the variables
*/
List vars = d.getRootElement().selectNodes("variables/*");
Iterator it = vars.iterator();
while(it.hasNext()) {
digestVariable(graph, (Element) it.next());
}
/*
* process the nodes
*/
List nodes = e.selectNodes("nodes/*");
it = nodes.iterator();
while(it.hasNext()) {
digestNode(graph,(Element) it.next());
}
List conns = e.selectNodes("connections/*");
it = conns.iterator();
while(it.hasNext()) {
Element node = (Element) it.next();
String start = node.attribute("startid").getValue();
String end = node.attribute("endid").getValue();
String name = node.attribute("display_name").getValue();
graph.addConnection(Integer.parseInt(start), Integer.parseInt(end), name);
}
} catch (DocumentException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return graph;
}
protected static void digestVariable(BusinessProcessImpl graph, Element node) {
String name = getValueOfAttribute("name", node);
String desc = getValueOfAttribute("desc", node);
String type = getValueOfAttribute("type", node);
String def = getValueOfAttribute("def", node);
String req = getValueOfAttribute("required", node);
Object defObject = "";
// TODO - fix
if ("STRING".equals(type.toUpperCase())) {
defObject = def;
}
else if ("INT".equals(type.toUpperCase())) {
defObject = new Integer(def);
}
/*
* decide if we have a value for required. it was optional at first
* TODO - remove this at some point in figture when all code is
* generating
*/
boolean required = false;
if (req != null && !"".equals(req)) {
required = "TRUE".equals(req.toUpperCase());
}
Variable v = new Variable(name, desc, String.class, defObject, required);
graph.addVariable(v);
}
protected static void digestNode(BusinessProcessImpl graph, Element node)
throws ClassNotFoundException, IllegalAccessException, InstantiationException {
/*
* get the class, id and type
*/
String classname = node.attribute("class").getValue();
// TODO may wish to also use the Thread context class loader
Node n = (Node) Class.forName(classname).newInstance();
n.setNodeId(new NodeID(Integer.parseInt(node.attribute("id").getValue())));
if (node.attribute("type").getValue().equals("start")) {
graph.setRoot(n);
}
n.setDisplayName(node.attribute("display_name").getValue());
/*
* set node properties
*/
List properties = node.selectNodes("property");
Iterator it = properties.iterator();
while(it.hasNext()) {
Element property = (Element) it.next();
String name = property.attributeValue("name");
String value = property.attributeValue("value");
if (value == null || value.equals("")) {
value = property.getText();
}
setProperty(n, name, value);
}
/*
* get actors
*/
List actors = node.selectNodes("actors/actor");
it = actors.iterator();
while(it.hasNext()) {
Element actor = (Element) it.next();
Actor actorObj = new Actor(actor.attribute("name").getValue());
n.addActor(actorObj);
}
/*
* and now the bindings
*/
List bindings = node.selectNodes("bindings/binding");
it = bindings.iterator();
while(it.hasNext()) {
Element bindingNode = (Element) it.next();
String name = getValueOfAttribute("name", bindingNode);
String type = getValueOfAttribute("type", bindingNode);
String input = getValueOfAttribute("input", bindingNode);
String output = getValueOfAttribute("output", bindingNode);
String value = bindingNode.getTextTrim();
Binding binding = new Binding(name, value,
("EL".equals(type.toUpperCase()) ? Binding.EL : Binding.STATIC),
("TRUE".equals(input.toUpperCase())),
("TRUE".equals(output.toUpperCase())));
n.addBinding(binding);
}
graph.addNode(n);
}
/**
* Sets the JavaBean property on the given node from the given name and value
*/
protected static void setProperty(Node node, String name, String value) {
try {
BeanUtils.setProperty(node, name, value);
}
catch (Exception e) {
throw new RuntimeException("Could not set property: " + name + " on node: " + node + " due to: " + e, e);
}
}
private static String getValueOfAttribute(String name, Element node) {
Attribute a = node.attribute(name);
if (a == null) {
return null;
}
return a.getValue();
}
public static void main(String[] args) throws Exception {
FileReader reader = new FileReader(new File("workflow_simple.xml"));
XMLUtil.deserializeXML(reader);
}
}