Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.coos.actorframe.ActorSpecParser Maven / Gradle / Ivy
/**
* 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.actorframe;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Hashtable;
import java.util.Vector;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.coos.actorframe.ActorPartSpec;
import org.coos.actorframe.ActorPortSpec;
import org.coos.actorframe.RoleSpec;
import org.coos.actorframe.application.Container;
import org.coos.actorframe.application.DomainSpec;
import org.coos.javaframe.ActorAddress;
import org.coos.javaframe.ActorSpec;
import org.coos.javaframe.ApplicationSpec;
import org.coos.javaframe.ConnectorSpec;
import org.coos.javaframe.PartSpec;
import org.coos.javaframe.SchedulerSpec;
import org.coos.javaframe.TraceConstants;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* @author Knut Eilif Husa, Tellu AS
* @author Robert Bjarum, Tellu AS
*/
public class ActorSpecParser {
/**
* Parse ApplicationSpec xml-file representation.
*
* @param fileName
* name of file
* @param container
* that runs the application
* @return application specification
* @throws FileNotFoundException
* when file not found
*/
public static ApplicationSpec parseXml(String fileName, Container container) throws ActorSpecException {
ApplicationSpec spec = new ApplicationSpec();
parseXml(fileName, spec, container);
return spec;
}
/**
* Parse ApplicationSpec xml-file representation.
*
* @param fileName
* name of file
* @return application specification
* @throws FileNotFoundException
* when file not found
*/
public static ApplicationSpec parseXml(String fileName) throws ActorSpecException {
return parseXml(fileName, (Container) null);
}
public static ApplicationSpec parseXml(String fileName, ApplicationSpec spec) throws ActorSpecException {
return parseXml(fileName, spec, null);
}
public static ApplicationSpec parseXml(String fileName, ApplicationSpec spec, Container container)
throws ActorSpecException {
InputStream is = null;
/* First try file on disk */
try {
is = new FileInputStream(fileName);
} catch (FileNotFoundException e) {
is = null;
}
/* File not found. Try resource instead. */
if (is == null) {
is = ActorSpecParser.class.getResourceAsStream(fileName);
}
parseXml(is, spec, container);
return spec;
}
public static ApplicationSpec createApplicationSpec(String name, String appName) {
return createApplicationSpec(name, appName, null);
}
public static ApplicationSpec createApplicationSpec(String name, String appName, Container container) {
ApplicationSpec appSpec = new ApplicationSpec(appName);
appSpec = createApplicationSpec(name, appSpec, container);
return appSpec;
}
public static ApplicationSpec createApplicationSpec(String name, ApplicationSpec appSpec) {
return createApplicationSpec(name, appSpec, null);
}
public static ApplicationSpec createApplicationSpec(String name, ApplicationSpec appSpec, Container container) {
InputStream fi = ActorSpecParser.class.getResourceAsStream(name);
parseXml(fi, appSpec, container);
return appSpec;
}
public static void parseXml(InputStream is, ApplicationSpec spec) throws ActorSpecException {
parseXml(is, spec, null);
}
public static void parseXml(InputStream is, ApplicationSpec spec, Container container) throws ActorSpecException {
if (is == null) {
throw new ActorSpecException("Inputstream cannot be null. Check name of application spec. (xml) resource.");
}
Document doc = null;
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setIgnoringElementContentWhitespace(true);
DocumentBuilder builder = dbf.newDocumentBuilder();
doc = builder.parse(is);
} catch (Exception e) {
throw new ActorSpecException("Failed to parse application spec. (xml). Check content.", e);
}
Element appElement = doc.getDocumentElement();
// read meta data about the application
Vector traces = getChildren(appElement, "trace");
if (traces.size() > 0) {
Element traceElement = (Element) traces.get(0);
spec.setTraceEnabled(getAttrBoolean(traceElement, "trace", spec.isTraceEnabled()));
}
String name = getAttrString(appElement, "name", spec.getAppName());
spec.setAppName(name);
Vector descriptions = getChildren(appElement, "description");
String description = null;
if (descriptions.size() > 0) {
description = ((Element) descriptions.get(0)).getFirstChild().getNodeValue();
}
// String description = getAttrString(appElement, "description", null);
spec.setDescription(description);
// parse the creation of the actor schedulerData
Vector domains = getChildren(appElement, "domain");
for (int x = 0; x < domains.size(); x++) {
DomainSpec aps = parseDomainSpec((Element) domains.get(x), spec.getDomainSpec());
spec.setDomainSpec(aps);
}
String extend = null;
// parse the actors
Vector actors = getChildren(appElement, "actor");
for (int x = 0; x < actors.size(); x++) {
Element e = (Element) actors.get(x);
extend = getAttrString(e, "extends", null);
String type = getAttrString(e, "name", null);
if (type == null) {
throw new ActorSpecException("Actor spec: No name defined in element " + e.getNodeName());
}
ActorSpec as = spec.getActorSpec(type);
if (as == null) {
as = new ActorSpec();
as.setActorType(type);
} else {
if (extend == null) {
throw new ActorSpecException("Actor spec: actor type <" + type
+ "> already exist, illegal extension");
}
}
// Get the class name
as.setActorClassName(parseClassName(e, as, container));
// Parse role spec
Vector roleSpecs = as.getRoleDesc();
Vector roleSpec = getChildren(e, "role");
for (int i = 0; i < roleSpec.size(); i++) {
RoleSpec aps = parseRoleSpec((Element) roleSpec.get(i), as);
as.addRoleSpec(aps);
}
// Reads the Port spec for the actor
Vector actorPortSpecs = as.getPortDesc();
Vector actorPorts = getChildren(e, "port");
for (int i = 0; i < actorPorts.size(); i++) {
ActorPortSpec aps = parseActorPortSpec((Element) actorPorts.get(i), as);
as.addPortSpec(aps);
}
// as.setPortDesc(actorPortSpecs);
// reads the connector specs
Vector connectors = as.getConnectorDesc();
connectors = parseConnectors(e, connectors, as);
as.setConnectorDesc(connectors);
Vector actorPartSpecs = as.getPartDesc();
Vector actorParts = getChildren(e, "part");
for (int i = 0; i < actorParts.size(); i++) {
ActorPartSpec aps = parseActorPartSpec((Element) actorParts.get(i), as);
if (as.getPartSpec(aps.getRoleType()) != null) {
as.deletePartSpec(aps.getRoleType());
}
actorPartSpecs.addElement(aps);
}
as.setPartDesc(actorPartSpecs);
spec.addActorSpec(as);
}
}
private static String parseClassName(Element e, ActorSpec as, Container container) {
String className = getAttrString(e, "class", as.getActorClassName());
try {
if (container != null) {
container.loadClass(className);
} else {
Class.forName(className);
}
return className;
} catch (ClassNotFoundException e1) {
throw new ActorSpecException("Class <" + className + "> not found");
}
}
/**
* Parse trace info
*
* @param e
* JDOM element for tags.
* @param ps
* Specification of the actor
*/
private static void parseTraceSpec(Element e, PartSpec ps) {
ps.setTraceLev(TraceConstants.getTraceLevel(getAttrString(e, "trace", TraceConstants.getTraceLevel(ps
.getTraceLev()))));
}
private static Vector parseConnectors(Element e, Vector connectors, ActorSpec as) {
// add ports
NodeList ic = e.getChildNodes(); // e.getElementsByTagName("connector");
for (int x = 0; x < ic.getLength(); x++) {
//
if (!ic.item(x).getNodeName().equals("connector"))
continue;
Element connector = (Element) ic.item(x);
String name = getAttrString(connector, "name", null);
if (name == null) {
throw new ActorSpecException("Connector spec: no connector name");
}
ConnectorSpec cs = as.getConnectorDesc(name);
if (cs == null) {
cs = new ConnectorSpec();
cs.setName(name);
}
cs.setIsBidirectional(getAttrBoolean(connector, "bidirectional", cs.isBidirectional()));
// parse from port spec
String fromString = getAttrString(connector, "from", null);
if ((fromString == null) || fromString.equals("")) {
throw new ActorSpecException("Connector spec: from address");
}
cs.setFrom(new ActorAddress(fromString)); // default port
// parse to spec
String toString = getAttrString(connector, "to", null);
if ((toString == null) || fromString.equals("")) {
throw new ActorSpecException("Connector spec: to address");
}
cs.setTo(new ActorAddress(toString)); // default port
connectors.addElement(cs);
}
return connectors;
}
private static int getAttrInt(Element e, String name, int defaultValue) {
String res = e.getAttribute(name);
if ((res == null) || res.equals("")) {
return defaultValue;
}
return Integer.parseInt(res.trim());
}
private static String getAttrString(Element e, String name, String defaultValue) {
String res = e.getAttribute(name);
if ((res == null) || res.equals("")) {
return defaultValue;
}
return res.trim();
}
private static boolean getAttrBoolean(Element e, String name, boolean defaultValue) {
String attr = e.getAttribute(name);
boolean res;
if (attr == null) {
res = defaultValue;
} else {
res = Boolean.parseBoolean(attr);
}
return res;
}
private static Vector getChildren(Element e, String type) {
Vector v = new Vector();
NodeList nl = e.getChildNodes();
for (int x = 0; x < nl.getLength(); x++) {
if (nl.item(x).getNodeName().equals(type))
v.add(nl.item(x));
}
return v;
}
private static RoleSpec parseRoleSpec(Element e, ActorSpec actorSpec) {
String type;
type = getAttrString(e, "type", null);
if (type == null) {
throw new ActorSpecException("Actor spec: illegal role type definition");
}
RoleSpec aps = actorSpec.getRoleSpec(type);
if (aps == null) {
aps = new RoleSpec();
aps.setType(type);
}
aps.setRoleClass(getAttrString(e, "class", aps.getRoleClass()));
aps.setInstance(getAttrString(e, "instance", aps.getInstance()));
aps.setPersistent(getAttrBoolean(e, "persistent", aps.isPersistent()));
return aps;
}
private static ActorPortSpec parseActorPortSpec(Element e, ActorSpec actorSpec) {
String portName = getAttrString(e, "name", null);
if (portName == null) {
throw new ActorSpecException("Port name < " + portName + "> cannot be null");
}
ActorPortSpec portSpec = (ActorPortSpec) actorSpec.getPortSpec(portName);
if (portSpec == null) {
portSpec = new ActorPortSpec(portName);
}
portSpec.setPortType(getAttrString(e, "class", portSpec.getPortType()));
portSpec.setBehavior(getAttrBoolean(e, "isbehavior", portSpec.isBehavior()));
// boolean hideInner = getAttrBoolean(e, "hideinner", );
// boolean sessionEnabled = getAttrBoolean(e, "sessionenabled", false);
// ActorPortSpec aps = new ActorPortSpec(portName, className,
// isBehavior);
// aps.setSessionEnabled(sessionEnabled);
// aps.setHideInner(hideInner);
return portSpec;
}
/**
* Creates a PartSpec based on a JDOM element.
*/
private static ActorPartSpec parseActorPartSpec(Element e, ActorSpec spec) {
//
String roleType = getAttrString(e, "actor", null);
if (roleType == null) {
throw new ActorSpecException("Part spec: illegal actor type definition");
}
ActorPartSpec apc = (ActorPartSpec) spec.getPartSpec(roleType);
if (apc == null) {
apc = new ActorPartSpec();
apc.setRoleType(roleType);
}
apc.setVisible(getAttrBoolean(e, "visible", apc.isVisible()));
apc.setLevel(getAttrInt(e, "level", apc.getLevel()));
apc.setCredentialsRequired(getAttrBoolean(e, "credentialsrequired", apc.isCredentialsRequired()));
String ad = getAttrString(e, "actordomain", null);
if (ad != null) {
// actordomain is by default set to null
apc.setActorDomain(new ActorAddress(ad));
}
apc.setBind(getAttrString(e, "bind", apc.getBind()));
// parse the set name , used to identyfy uniq sets
apc.setSetId(getAttrString(e, "set", apc.getSetId()));
apc.setLow(getAttrInt(e, "min", apc.getLow()));
apc.setHigh(getAttrInt(e, "max", apc.getHigh()));
// First check if one instance is defined as a property
Vector rn = toVector(apc.getRoleNames());
String instanceName = getAttrString(e, "instance", null);
if (instanceName != null) {
rn.add(instanceName);
}
// check properties for all instances
Hashtable instanceProperties = null;
Hashtable properties = readProperties(e);
if (properties != null) {
instanceProperties = new Hashtable();
instanceProperties.put("default", properties);
}
Vector inst = getChildren(e, "instance");
if (inst.size() > 0)
if (instanceProperties == null) {
instanceProperties = new Hashtable();
}
for (int i = 0; i < inst.size(); i++) {
Element ie = (Element) inst.get(i);
String s = getAttrString(ie, "name", null);
if (s != null) {
rn.add(s);
properties = readProperties(ie);
if (properties != null) {
instanceProperties.put(s, properties);
}
}
}
// merge instance names
apc.setActorProperties(instanceProperties);
apc.setRoleNames(toStringArray(rn));
// parse trace specification
parseTraceSpec(e, apc);
return apc;
}
private static String[] toStringArray(Vector v) {
if (v == null) {
return new String[0];
}
String[] sa = new String[v.size()];
for (int i = 0; i < v.size(); i++) {
sa[i] = (String) v.elementAt(i);
}
return sa;
}
private static Vector toVector(String[] sa) {
Vector v = new Vector();
if (sa == null) {
return v;
}
for (int i = 0; i < sa.length; i++) {
v.add(sa[i]);
}
return v;
}
/**
* Reads the properties for an instance
*
* @param ie
* the dom element that contains the property
* @return a hashtable of properties
*/
private static Hashtable readProperties(Element ie) {
Vector itProps = getChildren(ie, "property");
if (itProps.size() > 0) {
Hashtable properties = new Hashtable();
for (int x = 0; x < itProps.size(); x++) {
Element ieProp = (Element) itProps.get(x);
properties.put(getAttrString(ieProp, "name", null), getAttrString(ieProp, "value", null));
}
return properties;
}
return null;
}
/**
* Creates a DomainSpec based on a JDOM element.
*/
private static DomainSpec parseDomainSpec(Element e, DomainSpec domainSpec) {
String actor = getAttrString(e, "actor", "ActorDomain");
String name = getAttrString(e, "name", actor);
boolean validated = getAttrBoolean(e, "validated", false);
String extend = getAttrString(e, "extends", null);
if (domainSpec == null) {
domainSpec = new org.coos.actorframe.application.DomainSpec(name, actor);
} else {
if (extend == null) {
// Domain spec already exists, no extentions is defined
throw new ActorSpecException("Domain <" + domainSpec.getName()
+ "> already exists, no extension is defined");
}
}
domainSpec.setValidated(validated);
// parse the scheduler of the actor schedulerData
Vector scheduler = getChildren(e, "scheduler");
if (scheduler.size() > 0) {
for (int i = 0; i < scheduler.size(); i++) {
// iterate over scheduler
Element et = (Element) scheduler.get(i);
String id = getAttrString(et, "name", "sched" + String.valueOf(i));
if (id == null) {
throw new ActorSpecException("Scheduler name not defined");
}
SchedulerSpec ss = domainSpec.getSchedulerSpec(id);
if (ss == null) {
ss = new SchedulerSpec();
ss.setId(id);
}
String threads = getAttrString(et, "threads", String.valueOf(ss.getThreads()));
ss.setThreads(Integer.parseInt(threads));
if (ss.getThreads() > 1) {
ss.setClassName("org.coos.javaframe.ThreadPooledScheduler");
} else {
ss.setClassName("org.coos.javaframe.SchedulerImpl");
}
Vector r = getChildren(et, "actor");
for (int x = 0; x < r.size(); x++) {
String actorType = getAttrString((Element) r.get(x), "type", null);
SchedulerSpec spec = domainSpec.containsActorType(actorType);
// if (ss.getActorType(actorType) == null) {
if (spec == null) {
ss.addActorType(actorType);
} else {
throw new ActorSpecException("Scheduler: actor: " + actorType + " is already defined in <"
+ spec.getId() + ">");
}
}
domainSpec.addSchedulerSpec(ss);
}
} else {
SchedulerSpec ss = new SchedulerSpec();
ss.setId("default");
domainSpec.addSchedulerSpec(ss);
}
return domainSpec;
}
}