Java tutorial
/* * Copyright (c) 2003-2010 The Regents of the University of California. * All rights reserved. * * '$Author: crawl $' * '$Date: 2014-06-16 11:21:25 -0700 (Mon, 16 Jun 2014) $' * '$Revision: 32770 $' * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the above * copyright notice and the following two paragraphs appear in all copies * of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * */ package org.kepler.objectmanager; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.io.StringWriter; import java.lang.reflect.Constructor; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.StringTokenizer; import java.util.Vector; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.zip.ZipEntry; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.kepler.moml.CompositeClassEntity; import org.kepler.moml.NamedObjId; import org.kepler.moml.PortAttribute; import org.kepler.moml.PropertyAttribute; import org.kepler.objectmanager.lsid.KeplerLSID; import org.kepler.sms.SemanticType; import org.kepler.util.DotKeplerManager; import org.kepler.util.FileUtil; import org.kepler.util.TransientStringAttribute; import ptolemy.actor.Director; import ptolemy.actor.IOPort; import ptolemy.actor.TypedAtomicActor; import ptolemy.actor.TypedCompositeActor; import ptolemy.actor.TypedIOPort; import ptolemy.data.expr.Parameter; import ptolemy.data.expr.StringParameter; import ptolemy.data.expr.Variable; import ptolemy.kernel.ComponentEntity; import ptolemy.kernel.ComponentRelation; import ptolemy.kernel.CompositeEntity; import ptolemy.kernel.Entity; import ptolemy.kernel.InstantiableNamedObj; import ptolemy.kernel.Port; import ptolemy.kernel.util.Attribute; import ptolemy.kernel.util.IllegalActionException; import ptolemy.kernel.util.NameDuplicationException; import ptolemy.kernel.util.NamedObj; import ptolemy.kernel.util.SingletonConfigurableAttribute; import ptolemy.kernel.util.StringAttribute; import ptolemy.kernel.util.Workspace; import ptolemy.moml.MoMLParser; import ptolemy.moml.unit.UnitAttribute; import ptolemy.util.StringUtilities; import ptolemy.vergil.basic.KeplerDocumentationAttribute; /** * This class parses and contains metadata for an actor. this creates an entity * of the form: * * <pre> * <entity name="Constant"> * <property name="documentation" class="ptolemy.vergil.basic.KeplerDocumentationAttribute"> * actor to provide constant input * </property> * <property name="entityId" class="org.kepler.moml.NamedObjId" * value="urn:lsid:lsid.ecoinformatics.org:actor:101:1"/> * <property name="class" value="org.kepler.actor.TestActor" * class="ptolemy.kernel.util.StringAttribute"> * <property name="id" value="urn:lsid:lsid.ecoinformatics.org:actor:1001:1" * class="ptolemy.kernel.util.StringAttribute"/> * </property> * <property name="output" class="org.kepler.moml.PortProperty> * <property name="direction" value="output" class="ptolemy.kernel.util.StringAttribute"/> * <property name="dataType" value="unknown" class="ptolemy.kernel.util.StringAttribute"/> * <property name="isMultiport" value="false" class="ptolemy.kernel.util.StringAttribute"/> * </property> * <property name="trigger" class="org.kepler.moml.PortProperty> * <property name="direction" value="input" class="ptolemy.kernel.util.StringAttribute"/> * <property name="dataType" value="unknown" class="ptolemy.kernel.util.StringAttribute"/> * <property name="isMultiport" value="true" class="ptolemy.kernel.util.StringAttribute"/> * </property> * <property class="org.kepler.sms.SemanticType" name="semanticType" value="urn:lsid:lsid.ecoinformatics.org:onto:1:1#ConstantActor"/> * <property class="org.kepler.moml.Dependency" name="dependency" value="urn:lsid:lsid.ecoinformatics.org:nativeLib:1:1"/> * </entity> * </pre> * * Note: As of 8/18/09, this class no longer includes graphical ammentities, * such as icons in the moml. If you want graphical widgets for your actor, you * must use org.kepler.gui.GraphicalActorMetadata. * * @author Chad Berkley *@created April 07, 2005 */ public class ActorMetadata implements Serializable { private static final Log log = LogFactory.getLog(ActorMetadata.class.getName()); private static final boolean isDebugging = log.isDebugEnabled(); /** * The id of the class that implements this actor. */ private String _classId; /** * The java class name. For composites, this is the name of the xml file * like org.kepler.actor.MyCompositeActor */ private String _className; /** * The class name as represented in ptII. For composites, this is always * ptolemy.actor.TypedCompositeActor. For java classes, this is the name of * the java class. */ private String _internalClassName; /** * The id of the actor. */ private String _actorId; /** * The name of the actor */ private String _actorName; /** * The instantiation of the actor. TODO describe more about how/when this is * populated, etc. */ private NamedObj _actor; /** * True if the actor described by this ActorMetadata is a class description. */ private boolean _isClass; /** * dependency ids */ private Vector<ClassedProperty> _dependencyVector; /** * semantic types */ private Vector<ClassedProperty> _semanticTypeVector; /** * ports */ private Vector<PortMetadata> _portVector; /** * changed flag */ private boolean _changed = false; /** * attribute vector for generic attributes */ private Vector<Attribute> _attributeVector; /** * vector for relations in a composite */ private Vector<ComponentRelation> _relationVector; /** * */ private String _links = null; /** * */ private Vector<MetadataHandler> _metadataHandlerVector; /** * default constructor. this is for serialization only. do not use this. */ public ActorMetadata() { initialize(); // nothing here. } private void initialize() { _dependencyVector = new Vector<ClassedProperty>(); _semanticTypeVector = new Vector<ClassedProperty>(); _portVector = new Vector<PortMetadata>(); _attributeVector = new Vector<Attribute>(); _relationVector = new Vector<ComponentRelation>(); _metadataHandlerVector = new Vector<MetadataHandler>(); _isClass = false; } /** * Constructor. Takes in xml metadata. This should be a moml entity with the * kepler additional metadata properties. The entity is parsed and an * ActorMetadata object is created with appropriate fields. * * @param moml * the xml metadata */ public ActorMetadata(InputStream moml) throws InvalidMetadataException { if (isDebugging && moml != null) log.debug("ActorMetadata(" + moml.toString() + ")"); initialize(); try { String momlStr = FileUtil.convertStreamToString(moml); if (isDebugging) { // log.debug("\n********************************"); // log.debug(momlStr); // log.debug("********************************\n"); log.debug("**** MoMLParser ****"); } /** * The MoMLParser cannot be the first thing to be called on Kepler * generated MoML files. Because TypedIOPorts are converted to * PortAttributes, an error is thrown when trying to parse Kepler * generated MoMLs that have any added ports. TODO: How to fix this? */ MoMLParser parser = new MoMLParser(new Workspace()); parser.reset(); if (isDebugging) log.debug("got moml parser outputing moml"); NamedObj obj = null; try { obj = parser.parse(null, momlStr); } catch (Exception e) { log.error(e.getMessage()); } if (obj == null) return; if (isDebugging) { String filename = "parsed-actor_" + obj.getName() + ".moml"; writeDebugMomlFor(obj, filename); } if (obj instanceof TypedCompositeActor) { _links = ((TypedCompositeActor) obj).exportLinks(1, null); } _actorName = obj.getName(); StringAttribute classAttribute = (StringAttribute) obj.getAttribute("class"); if (classAttribute == null) { throw new InvalidMetadataException("Missing 'class' attribute for " + obj.getFullName()); } Attribute idAtt = classAttribute.getAttribute("id"); if (idAtt == null) { throw new InvalidMetadataException("Missing 'id' attribute for " + obj.getFullName()); } _classId = ((StringAttribute) idAtt).getExpression(); _className = classAttribute.getExpression(); _internalClassName = obj.getClassName(); Attribute actIdAtt = obj.getAttribute(NamedObjId.NAME); if (actIdAtt == null) { throw new InvalidMetadataException( "Missing '" + NamedObjId.NAME + "' attribute for " + obj.getFullName()); } _actorId = ((NamedObjId) actIdAtt).getExpression(); NamedObj actor = getActorClass(_className, _actorName, obj); // Handle class definitions if (actor instanceof InstantiableNamedObj) { InstantiableNamedObj ino = (InstantiableNamedObj) actor; if (ino.isClassDefinition()) { _isClass = true; //_internalClassName = _className; } } this.setActor(actor); if (isDebugging) { String filename = "instantiated-actor-before_" + getActor().getName() + ".moml"; writeDebugMomlFor(obj, filename); } // get the semantic type and dependency lsids and any general // properties for (Object o : obj.attributeList()) { Attribute a = null; if (o instanceof Attribute) { a = (Attribute) o; } else { log.error("Object is not an Attribute"); continue; } getSemanticTypesAndDependencyLsids(a); } // get the ports // NOTE: we parse obj instead of actor since actor does not have // the PortAttributes parseNamedObj(obj); addAllRelations(); if (isDebugging) { String filename = "instantiated-actor-after_" + getActor().getName() + ".moml"; writeDebugMomlFor(obj, filename); } } catch (IOException ioe) { throw new InvalidMetadataException("Error reading data from lsid " + _actorId + ": " + ioe.getMessage(), ioe); } catch (Exception e) { if (isDebugging) log.debug(e.getStackTrace()); throw new InvalidMetadataException("Error in parsing actor metadata: " + e.getMessage(), e); } } /** * TODO: What is this doing? * * @param a * @return */ private boolean checkAtt(Attribute a) { String attName = a.getName(); String acn = a.getClassName(); if (!attName.equals(NamedObjId.NAME) && !attName.equals("class") && !acn.equals("org.kepler.moml.PropertyEntity") && !acn.equals("org.kepler.moml.PropertyAttribute") && !acn.equals("org.kepler.moml.CompositeClassEntity") && !acn.equals("org.kepler.moml.PortAttribute")) { return true; } return false; } /** * TODO: What is this doing? * * @param a * @throws IllegalActionException * @throws NameDuplicationException * @throws CloneNotSupportedException */ private void getSemanticTypesAndDependencyLsids(Attribute a) throws IllegalActionException, NameDuplicationException, CloneNotSupportedException { String attName = a.getName(); String attClassName = a.getClassName(); String aClassName = a.getClass().getName(); String kd = "ptolemy.vergil.basic.KeplerDocumentationAttribute"; if (attClassName.equals(kd)) { // parse the documentation setDocumentationAttribute((KeplerDocumentationAttribute) a); } else if (checkAtt(a)) { String attValue = null; if (a instanceof StringAttribute) { attValue = ((StringAttribute) a).getExpression(); } else if (a instanceof UnitAttribute) { attValue = ((UnitAttribute) a).getExpression(); } else if (a instanceof Variable) { attValue = ((Variable) a).getExpression(); } if (attName.indexOf("semanticType") != -1) { addSemanticType(a.getName(), attValue); } else if (attName.indexOf("dependency") != -1) { ClassedProperty prop = new ClassedProperty(attName, attValue, aClassName); _dependencyVector.add(prop); } else if (attName.indexOf("_iconDescription") != -1) { NamedObj act = getActor(); Attribute iconAtt = act.getAttribute("_iconDescription"); if (act != null && iconAtt != null) { handleIconDescription(a); } else { addAttribute(a); } } else { // add generic attributes addAttribute(a); } } } /** * TODO: What is this doing? * * @param a */ private void handleIconDescription(Attribute a) { boolean objIsDefault = false; boolean actorIsDefault = false; String objIconStr = ((SingletonConfigurableAttribute) a).getExpression(); String actorIconStr = ((SingletonConfigurableAttribute) getActor().getAttribute("_iconDescription")) .getExpression(); // Should this come from somewhere else? String pp = "<polygon" + " points=\"-20,-10 20,0 -20,10\"" + " style=\"fill:blue\"/>"; if (objIconStr.indexOf(pp) != -1) { objIsDefault = true; } if (actorIconStr.indexOf(pp) != -1) { actorIsDefault = true; } if ((objIsDefault && actorIsDefault) || (objIsDefault && actorIsDefault) || (!objIsDefault && !actorIsDefault)) { addAttribute(a); } else if (objIsDefault && !actorIsDefault) { // do nothing. leave the attribute in the actor } } /** * builds a new ActorMetadata object from an existing NamedObj * * @param am * the ActorMetadata to build this object from. */ public ActorMetadata(NamedObj obj) { //System.out.println(obj.exportMoML()); initialize(); if (obj instanceof InstantiableNamedObj) { InstantiableNamedObj ino = (InstantiableNamedObj) obj; if (ino.isClassDefinition()) { _isClass = true; } } this.setActor(obj); if (obj.getAttribute(NamedObjId.NAME) != null) { _actorId = ((NamedObjId) obj.getAttribute(NamedObjId.NAME)).getExpression(); } _actorName = obj.getName(); if (_isClass) { Attribute classAtt = obj.getAttribute("tempClassName"); if (classAtt != null) { TransientStringAttribute classAttribute = (TransientStringAttribute) classAtt; String className = classAttribute.getExpression(); _className = className; _internalClassName = className; } _links = null; addAllAttributes(); addAllRelations(); removeLinks(); } else { _className = obj.getClassName(); _internalClassName = obj.getClassName(); try { if (obj instanceof TypedCompositeActor) { _links = ((TypedCompositeActor) obj).exportLinks(1, null); } } catch (Exception e) { System.out.println("Error looking at links: " + e.getMessage()); } // set the internalClassname if (obj instanceof TypedAtomicActor) { _internalClassName = "ptolemy.kernel.ComponentEntity"; } else if (obj instanceof Attribute) { _internalClassName = "org.kepler.moml.PropertyEntity"; } else if (obj instanceof TypedCompositeActor || obj instanceof CompositeEntity) { _internalClassName = "org.kepler.moml.CompositeClassEntity"; } addAllAttributes(); addAllRelations(); } parseActor(); } /** * return the actor this object was built from. */ public NamedObj getActor() { return _actor; } public void setActor(NamedObj actor) { _actor = actor; } /** * return the name of the actor */ public String getName() { return _actorName; } /** * set the name */ public void setName(String name) { _actorName = name; } /** * return the lsid of the actor class object */ public String getId() { return _actorId; } /** * returns the id of this object as a KeplerLSID */ public KeplerLSID getLSID() throws Exception { return new KeplerLSID(_actorId); } /** * */ public KeplerDocumentationAttribute getDocumentationAttribute() { KeplerDocumentationAttribute da = (KeplerDocumentationAttribute) getActor() .getAttribute("KeplerDocumentation"); return da; } /** * */ public void setDocumentationAttribute(KeplerDocumentationAttribute newda) throws IllegalActionException, NameDuplicationException, CloneNotSupportedException { NamedObj a = getActor(); if (a == null) return; Attribute da = a.getAttribute("documentation"); // if the actor already has a da, then get rid of it and set this one // instead if (da != null) da.setContainer(null); da = a.getAttribute("KeplerDocumentation"); if (da != null) da.setContainer(null); Workspace w = a.workspace(); KeplerDocumentationAttribute n = (KeplerDocumentationAttribute) newda.clone(w); n.setContainer(a); } /** * set the id */ public void setId(String id) { _actorId = id; } /** * return the classname of the actor object. this will be the java type * classname no matter what kind of actor we are describing. for instance if * it is a java class, it will be a.b.c.ClassName where the file is stored * in a/b/c/ClassName.class. If it is a MoML class, it will be * a.b.c.MomlClassName where the file is a/b/c/MomlClassName.xml */ public String getClassName() { return _className; } /** * return the internal class name of the actor object. for composites this * will be ptolemy.actor.TypedCompositeActor. For atomics, it will be the * full java class name. */ public String getInternalClassName() { return _internalClassName; } /** * return the id of the class */ public String getClassId() { return _classId; } public void setClassId(String id) { _classId = id; } /** * add the id of a dependency to the metadata * * @param id * the id of the dependency to add */ public void addDependency(String id) { ClassedProperty cp = new ClassedProperty("dependency", id, "org.kepler.moml.Dependency"); _dependencyVector.addElement(cp); } /** * add the id of a semantic type to the metadata * * @param id * the id of the semantic type to add */ public void addSemanticType(String name, String id) { ClassedProperty cp = new ClassedProperty(name, id, "org.kepler.sms.SemanticType"); _semanticTypeVector.addElement(cp); } /** * return a vector of the ids of the semantic type reference */ public Vector<String> getSemanticTypes() { Vector<String> v = new Vector<String>(); for (int i = 0; i < _semanticTypeVector.size(); i++) { v.addElement(((ClassedProperty) _semanticTypeVector.elementAt(i)).value); } return v; } public Hashtable<String, String> getSemanticTypeHash() { Hashtable<String, String> h = new Hashtable<String, String>(); for (int i = 0; i < _semanticTypeVector.size(); i++) { ClassedProperty cp = (ClassedProperty) _semanticTypeVector.elementAt(i); h.put(cp.name, cp.value); } return h; } public void removeSemanticType(String id) { for (int i = 0; i < _semanticTypeVector.size(); i++) { ClassedProperty cp = (ClassedProperty) _semanticTypeVector.elementAt(i); if (cp.name.equals(id)) { _semanticTypeVector.remove(i); break; } } } /** * return a vector of the ids of the semantic type reference */ public Vector<String> getDependencies() { Vector<String> v = new Vector<String>(); for (int i = 0; i < _dependencyVector.size(); i++) { v.addElement(((ClassedProperty) _dependencyVector.elementAt(i)).value); } return v; } /** * get the changed flag. this is useful for keeping track of the state of * the actor metadata. this flag does not affect this class in any internal * way except for setting the flag. */ public boolean getChanged() { return _changed; } /** * set the changed flag. this is useful for keeping track of the state of * the actor metadata. this flag does not affect this class in any internal * way except for setting the flag. * * @param b */ public void setChanged(boolean b) { _changed = b; } /** * add a generic attribute to this actorMetadata object. * * @param a * the attribute to add */ public void addAttribute(Attribute a) { // why did we intentionally skip PortParameters? // if // (a.getClassName().equals("ptolemy.actor.parameters.PortParameter")) { // return; // } _attributeVector.add(a); } /** * add a relation */ public void addRelation(ComponentRelation r) { _relationVector.add(r); } /** * return this actor as a ComponentEntity * * @param container * the new ComponentEntity's container */ public NamedObj getActorAsNamedObj(CompositeEntity container) throws Exception { NamedObj obj = null; // Throw a NullPointerException here with a good message. // If actor is null, clone() will fail anyway. if (getActor() == null) { throw new NullPointerException("Could not clone '" + _actorName + "' from the '" + _className + "' class; the object is null, possibly meaning it was not " + "found. Perhaps there is a classpath problem and/or the " + "karlib needs to be flushed?"); } else if (getActor() instanceof TypedCompositeActor) { /* * if we are dealing with a composite entity, do stuff a bit * differently we need to instantiate the composite or else it will * show up in the library as a class instead of an entity. this * causes kepler to think that the user wants to drag a class to the * canvas and it requires the user to instantiate the actor before * using it. by calling instantiate here, we bypass that. */ if (_internalClassName.equals("org.kepler.moml.CompositeClassEntity")) { obj = getActor(); obj = addPorts(obj, _portVector); if (container == null) { try { NamedObj newobj = (NamedObj) getActor().clone(new Workspace()); // this kinda works return newobj; } catch (java.lang.CloneNotSupportedException cnse) { System.out.println("trying to clone " + getActor().getName() + " but " + "you can't clone this object for some reason: " + cnse.getMessage()); } } else { return (NamedObj) getActor().clone(container.workspace()); // this kinda works } // return // (NamedObj)((TypedCompositeActor)actor).instantiate(container, // actor.getName()); // obj = // (NamedObj)((TypedCompositeActor)actor).instantiate(container, // actor.getName()); // obj.setClassName(className); // return obj; } else { // see if the internal class name is a subclass of composite actor Class<?> clazz = Class.forName(_internalClassName); Class<?> compositeActorClass = Class.forName("ptolemy.actor.TypedCompositeActor"); if (compositeActorClass.isAssignableFrom(clazz)) { // clone it if (container == null) { return (NamedObj) getActor().clone(new Workspace()); } else { return (NamedObj) getActor().clone(container.workspace()); } } else { obj = (NamedObj) ((TypedCompositeActor) getActor()).instantiate(container, getActor().getName()); obj.setClassName(_className); } } } else if (getActor() instanceof Director || getActor() instanceof Attribute) { // this is a director or other Attribute derived class // obj = new Director(container, actorName); // obj.setClassName(className); if (container == null) { obj = (NamedObj) getActor().clone(new Workspace()); } else { obj = (NamedObj) getActor().clone(container.workspace()); } } else { // this is an atomic actor if (container != null) { obj = (NamedObj) getActor().clone(container.workspace()); ((TypedAtomicActor) obj).setContainer(container); } else { obj = (NamedObj) getActor().clone(null); } } // call the metadata handlers for (int i = 0; i < _metadataHandlerVector.size(); i++) { MetadataHandler handler = (MetadataHandler) _metadataHandlerVector.elementAt(i); handler.handleMetadata(obj); } NamedObjId objId; StringAttribute classObj; StringAttribute classIdObj; try { objId = new NamedObjId(obj, NamedObjId.NAME); } catch (ptolemy.kernel.util.IllegalActionException iee) { objId = (NamedObjId) obj.getAttribute(NamedObjId.NAME); } catch (ptolemy.kernel.util.NameDuplicationException nde) { objId = (NamedObjId) obj.getAttribute(NamedObjId.NAME); } try { classObj = new StringAttribute(obj, "class"); classIdObj = new StringAttribute(classObj, "id"); } catch (ptolemy.kernel.util.InternalErrorException iee) { classObj = (StringAttribute) obj.getAttribute("class"); classIdObj = (StringAttribute) classObj.getAttribute("id"); } catch (ptolemy.kernel.util.NameDuplicationException nde) { classObj = (StringAttribute) obj.getAttribute("class"); classIdObj = (StringAttribute) classObj.getAttribute("id"); } if (objId != null) { objId.setExpression(_actorId); } classObj.setExpression(_className); classIdObj.setExpression(_classId); for (int i = 0; i < _semanticTypeVector.size(); i++) { ClassedProperty cp = (ClassedProperty) _semanticTypeVector.elementAt(i); Attribute attribute = obj.getAttribute(cp.name); if (attribute == null) { SemanticType semType = new SemanticType(obj, cp.name); semType.setExpression(cp.value); } else if (!(attribute instanceof SemanticType)) { log.warn("Attribute is not a SemanticType as expected"); } } /* * FIXME: TODO: add dependencies and other info to the NamedObj */ // add the general attributes to the object for (int i = 0; i < _attributeVector.size(); i++) { Attribute a = (Attribute) _attributeVector.elementAt(i); Attribute aClone = (Attribute) a.clone(obj.workspace()); try { aClone.setContainer(obj); } catch (NameDuplicationException nde) { // System.out.println("obj already has attribute " + // a.getName()); // ignore this, it shouldn't matter. // Specialized versions of some actors (e.g. RExpression actor // require that parameters be reset to new values // without the following code, these will not be reset // Dan Higgins - 1/20/2006 String attValue; String attName; attName = aClone.getName(); if (aClone instanceof StringAttribute) { attValue = ((StringAttribute) aClone).getExpression(); StringAttribute sa = (StringAttribute) obj.getAttribute(attName); sa.setExpression(attValue); } else if (aClone instanceof StringParameter) { attValue = ((StringParameter) aClone).getExpression(); StringParameter sp = (StringParameter) obj.getAttribute(attName); sp.setExpression(attValue); } else if (aClone instanceof Parameter) { attValue = ((Parameter) aClone).getExpression(); Parameter pp = (Parameter) obj.getAttribute(attName); pp.setExpression(attValue); } } } // copy any extra moml ports over if (!(getActor() instanceof Director)) { obj = addPorts(obj, _portVector); } return obj; } /** * return the moml xml representation of the actor. */ public String toString() { if (isDebugging) { log.debug("toString()"); } return toString(true, true, true); } /** * return the moml xml representation of the actor. * @param incSemanticTypeNames if true, add a suffix to property names * for semantic types, e.g. semanticType00 -> semanticType000 * @param includeAttributes if true, add the attributes and parameters * to the xml representation. this flag does not affect semantic types * or documentation attributes. * @param includePorts if true, add the ports to the xml representation. */ public String toString(boolean addSuffixToSemanticTypeNames, boolean includeAttributes, boolean includePorts) { StringBuffer sb = new StringBuffer(); sb.append("<?xml version=\"1.0\"?>\n"); sb.append("<!DOCTYPE entity PUBLIC " + "\"-//UC Berkeley//DTD MoML 1//EN\"\n" + " \"http://ptolemy.eecs.berkeley.edu" + "/xml/dtd/MoML_1.dtd\">\n"); if (getActor() instanceof PropertyAttribute) { sb.append("<property name=\"" + _actorName + "\" class=\"org.kepler.moml.PropertyAttribute\">\n"); } else if (getActor() instanceof Attribute) { sb.append("<property name=\"" + _actorName + "\" class=\"org.kepler.moml.PropertyEntity\">\n"); } else if (_internalClassName.equals("org.kepler.moml.CompositeClassEntity")) { sb.append("<entity name=\"" + _actorName + "\" class=\"org.kepler.moml.CompositeClassEntity\">\n"); } else { if (_isClass) { //System.out.println("isClass: " + _internalClassName); sb.append("<entity name=\"" + _actorName + "\" class=\"" + _internalClassName + "\">\n"); } else { sb.append("<entity name=\"" + _actorName + "\" class=\"ptolemy.kernel.ComponentEntity\">\n"); } } sb.append("<property name=\"" + NamedObjId.NAME + "\" value=\"" + _actorId + "\" class=\"org.kepler.moml.NamedObjId\"/>\n"); if (_internalClassName.equals("ptolemy.actor.Director") || _internalClassName.equals("ptolemy.actor.TypedCompositeActor") || _internalClassName.equals("ptolemy.kernel.ComponentEntity") || _internalClassName.equals("org.kepler.moml.PropertyEntity") || _internalClassName.equals("org.kepler.moml.CompositeClassEntity")) { sb.append("<property name=\"class\" value=\"" + _className + "\" class=\"ptolemy.kernel.util.StringAttribute\">\n"); } else { sb.append("<property name=\"class\" value=\"" + _internalClassName + "\" class=\"ptolemy.kernel.util.StringAttribute\">\n"); } // add another property to tell what the moml class is if (_internalClassName.equals("ptolemy.actor.TypedCompositeActor")) { sb.append(" <property name=\"momlClass\" value=\"" + _className + "\" class=\"ptolemy.kernel.util.StringAttribute\"/>\n"); } sb.append(" <property name=\"id\" value=\"" + _classId + "\" class=\"ptolemy.kernel.util.StringAttribute\"/>\n"); sb.append("</property>\n"); // print the dependencies if (_dependencyVector.size() != 0) { for (int i = 0; i < _dependencyVector.size(); i++) { ClassedProperty cp = (ClassedProperty) _dependencyVector.get(i); cp.addNameIterator(i); sb.append(cp.toString() + "\n"); } } // print the semantic types if (_semanticTypeVector.size() != 0) { for (int i = 0; i < _semanticTypeVector.size(); i++) { ClassedProperty cp = (ClassedProperty) _semanticTypeVector.get(i); if (addSuffixToSemanticTypeNames) { cp.addNameIterator(i); } sb.append(cp.toString() + "\n"); } } // add general attributes if (_attributeVector.size() != 0) { for (int i = 0; i < _attributeVector.size(); i++) { Attribute a = (Attribute) _attributeVector.elementAt(i); if (includeAttributes || (a instanceof SemanticType)) { sb.append(a.exportMoML() + "\n"); } } } // print the ports // NOTE: the ports must come after attributes since ParameterPorts // must come after the PortParameters. otherwise parsing the xml // results in a NameDuplicatonException. // see http://bugzilla.ecoinformatics.org/show_bug.cgi?id=4580 if (includePorts && _portVector.size() != 0) { for (int i = 0; i < _portVector.size(); i++) { if (getActor() instanceof TypedCompositeActor && getActor() instanceof InstantiableNamedObj && !((InstantiableNamedObj) getActor()).isClassDefinition()) { sb.append(((PortMetadata) _portVector.get(i)).toMoMLString()); } else { sb.append(((PortMetadata) _portVector.get(i)).toString()); } } } // add relations if (_relationVector.size() != 0) { for (int i = 0; i < _relationVector.size(); i++) { ComponentRelation r = (ComponentRelation) _relationVector.elementAt(i); sb.append(r.exportMoML() + "\n"); } } // add documentation KeplerDocumentationAttribute da = getDocumentationAttribute(); if (da != null) { sb.append(da.exportMoML()); } String cce = "org.kepler.moml.CompositeClassEntity"; if (_internalClassName.equals(cce)) { CompositeEntity ce = (CompositeEntity) getActor(); // add any class definitions // NOTE: these must be added before the entities since the // MoMLParser needs to read them first. List<?> classDefinitions = ce.classDefinitionList(); for (Object obj : classDefinitions) { String classDefinitionMoml = ((NamedObj) obj).exportMoML(); sb.append(classDefinitionMoml); } List<?> entList = ce.entityList(); Iterator<?> entityItt = entList.iterator(); while (entityItt.hasNext()) { Entity ent = (Entity) entityItt.next(); String entMoml = ent.exportMoML(); sb.append(entMoml); } } if (_links != null) { sb.append(_links); } if (getActor() instanceof Attribute || getActor() instanceof PropertyAttribute) { sb.append("</property>"); } else { sb.append("</entity>\n"); } return sb.toString(); } /** * this method allows other classes to add handlers to further process the * metadata produced by this class. The handlers will be called in the * getActorAsNamedObj() and getActorClass() methods. * * @param handler * the handler to add */ public void addMetadataHandler(MetadataHandler handler) { _metadataHandlerVector.add(handler); } /** * remove a metadata handler * * @param handler * the handler to remove */ public void removeMetadataHandler(MetadataHandler handler) { _metadataHandlerVector.remove(handler); } private boolean addPort(TypedIOPort p, PortMetadata pm) throws IllegalActionException { if (isDebugging) log.debug("*************p: " + p.exportMoML()); boolean found = false; String pName = p.getName(); String cpName = cleansePortName(pm.name); if (pName.equals(cpName)) { if (isDebugging) log.debug("adding port " + pm.name); Vector<NamedObj> pAtts = pm.attributes; for (int j = 0; j < pAtts.size(); j++) { try { if (isDebugging) log.debug("cloning port " + pm.name); NamedObj noAtt = pAtts.elementAt(j); Attribute pm_att = (Attribute) noAtt; if (isDebugging) log.debug("processing attribute: " + pm_att.getName()); if (pm_att instanceof SemanticType) { ((Attribute) ((Attribute) pAtts.elementAt(j)).clone(p.workspace())).setContainer(p); // System.out.println("added attribute " + // ((Attribute)pm.attributes.elementAt(j)).getName() // + " to port " + p.getName()); } // System.out.println("cloned port " + pm.name); // System.out.println("<port> is now: " + // p.exportMoML()); } catch (NameDuplicationException nde) { // System.out.println("tried to duplicate " + // pm.attributes.elementAt(j).toString()); } catch (java.lang.CloneNotSupportedException cnse) { } } found = true; } return found; } /** * adds any kepler ports to the actor */ private NamedObj addPorts(NamedObj obj, Vector<PortMetadata> portVector) throws IllegalActionException, NameDuplicationException { boolean found = false; for (int i = 0; i < portVector.size(); i++) { // if there are any ports in the port vector that are not in the // port iterator, add them Entity ent = (Entity) obj; List<?> pList = ent.portList(); Iterator<?> portIterator = pList.iterator(); PortMetadata pm = (PortMetadata) portVector.elementAt(i); Vector<NamedObj> pmAtts = pm.attributes; if (isDebugging) log.debug("**********pm: " + pm.toString()); while (portIterator.hasNext()) { TypedIOPort p = (TypedIOPort) portIterator.next(); found = addPort(p, pm); if (found) break; } if (!found) { TypedIOPort port = null; if (obj instanceof TypedAtomicActor) { TypedAtomicActor taa = (TypedAtomicActor) obj; List<?> taaPL = taa.portList(); Iterator<?> portList = taaPL.iterator(); boolean flag = true; while (portList.hasNext()) { TypedIOPort oldport = (TypedIOPort) portList.next(); String oldportName = oldport.getName(); if (oldportName.equals(pm.name)) flag = false; List<?> opAttList = oldport.attributeList(); if (isDebugging) { log.debug("old port atts: " + opAttList.size()); log.debug("pm att size: " + pmAtts.size()); } if (opAttList.size() != pmAtts.size()) flag = true; } if (flag) { if (isDebugging) log.debug("adding port " + pm.name + " to obj"); String cpName = cleansePortName(pm.name); port = new TypedIOPort(taa, cpName); } else { if (isDebugging) { log.debug("not adding port " + pm.name + " to obj"); } } } else { TypedCompositeActor tca = (TypedCompositeActor) obj; List<?> tcaPList = tca.portList(); Iterator<?> portList = tcaPList.iterator(); boolean flag = true; while (portList.hasNext()) { TypedIOPort oldport = (TypedIOPort) portList.next(); String oldportName = oldport.getName(); if (oldportName.equals(pm.name)) flag = false; } if (flag) { String cpName = cleansePortName(pm.name); port = new TypedIOPort(tca, cpName); } } if (port == null) { continue; } if (pm.direction.equals("input")) { port.setInput(true); } else if (pm.direction.equals("output")) { port.setOutput(true); } else if (pm.direction.equals("inputoutput")) { port.setInput(true); port.setOutput(true); } if (pm.multiport) { port.setMultiport(true); } Iterator<?> attItt = pmAtts.iterator(); while (attItt.hasNext()) { Attribute a = (Attribute) attItt.next(); try { Workspace pws = port.workspace(); Attribute attClone = (Attribute) a.clone(pws); attClone.setContainer(port); } catch (CloneNotSupportedException cnse) { System.out.println( "Cloning the attribute " + a.getName() + " is not supported: " + cnse.getMessage()); } } } else { found = false; } } return obj; } /** * removes the 'kepler:' from the port names. this tag is used to keep ptii * from throwing name duplication exceptions becuase our port metadata * Parameter has the same name as the port it describes */ private String cleansePortName(String portName) { if (portName.indexOf("kepler:") != -1) { // strip the kepler: off of the name. kepler: is there to // prevent namedup exceptions in the moml parser return portName.substring(7, portName.length()); } return portName; } /** * parse an actor to create the actorMetadata object * *@param actor */ private void parseActor() { NamedObj actor = getActor(); if (actor instanceof ComponentEntity /* * && !(actor instanceof * TypedCompositeActor) */) { List<?> list = ((ComponentEntity) actor).portList(); Iterator<?> portIterator = list.iterator(); while (portIterator.hasNext()) { Port p = (Port) portIterator.next(); PortMetadata pm = new PortMetadata(); pm.name = p.getName(); if (p instanceof TypedIOPort) { pm.type = ((TypedIOPort) p).getType().toString(); } if (p instanceof IOPort) { IOPort iop = (IOPort) p; pm.multiport = iop.isMultiport(); if (iop.isInput() && iop.isOutput()) { pm.direction = "inputoutput"; } else if (iop.isInput()) { pm.direction = "input"; } else if (iop.isOutput()) { pm.direction = "output"; } } pm.portClassName = p.getClassName(); // get any other port attributes and copy them List<?> portAttList = p.attributeList(); Iterator<?> portAttsIt = portAttList.iterator(); while (portAttsIt.hasNext()) { NamedObj att = (NamedObj) portAttsIt.next(); pm.addAttribute(att); if (isDebugging) log.debug("adding att: " + att.exportMoML()); } _portVector.addElement(pm); } } } /** * parse a named obj and get it's port info */ private void parseNamedObj(NamedObj obj) throws InvalidMetadataException { if (obj instanceof CompositeClassEntity) { // if it's a composite, look for the <port> objects instead of the // PortProperties Entity ent = (Entity) obj; List<?> pList = ent.portList(); Iterator<?> portIterator = pList.iterator(); while (portIterator.hasNext()) { TypedIOPort port = (TypedIOPort) portIterator.next(); PortMetadata pm = new PortMetadata(); pm.name = port.getName(); pm.type = port.getType().toString(); pm.multiport = port.isMultiport(); if (port.isInput()) { pm.direction = "input"; } if (port.isOutput()) { pm.direction = "output"; } if (port.isOutput() && port.isInput()) { pm.direction = "inputoutput"; } pm.portClassName = port.getClassName(); List<?> attList = port.attributeList(); Iterator<?> listIt = attList.iterator(); while (listIt.hasNext()) { NamedObj att = (NamedObj) listIt.next(); pm.addAttribute(att); } _portVector.addElement(pm); } } else if (obj instanceof ComponentEntity) { List<?> list = null; try { Class<?> cls = Class.forName("org.kepler.moml.PortAttribute"); ComponentEntity ce = (ComponentEntity) obj; list = ce.attributeList(cls); } catch (ClassNotFoundException cnfe) { } Iterator<?> portIterator = list.iterator(); while (portIterator.hasNext()) { PortAttribute pa = (PortAttribute) portIterator.next(); PortMetadata pm = new PortMetadata(); pm.name = pa.getName(); if (pm.name == null) { throw new InvalidMetadataException("Port is missing name."); } StringAttribute attribute = (StringAttribute) pa.getAttribute("dataType"); if (attribute == null) { throw new InvalidMetadataException("Port " + pm.name + " is missing dataType attribute."); } pm.type = attribute.getExpression(); attribute = (StringAttribute) pa.getAttribute("isMultiport"); if (attribute == null) { throw new InvalidMetadataException("Port " + pm.name + " is missing isMultiport attribute."); } // try parsing the boolean string try { pm.multiport = Boolean.valueOf(attribute.getExpression()).booleanValue(); } catch (Throwable t) { throw new InvalidMetadataException( "Invalid isMultiport value for port " + pm.name + ": " + attribute.getExpression()); } attribute = (StringAttribute) pa.getAttribute("direction"); if (attribute == null) { throw new InvalidMetadataException("Port " + pm.name + " is missing direction attribute."); } pm.direction = attribute.getExpression(); List<?> attList = pa.attributeList(); Iterator<?> listIt = attList.iterator(); while (listIt.hasNext()) { NamedObj att = (NamedObj) listIt.next(); if (!att.getName().equals("dataType") && !att.getName().equals("isMultiport") && !att.getName().equals("direction")) { if (isDebugging) log.debug("adding att: " + att.exportMoML()); pm.addAttribute(att); } } _portVector.addElement(pm); } } } /** * look for a moml class and try to instantiate it * * @param actorName * @param className * @param actorMetadataMoml * @return */ private NamedObj lookForMoml(String actorName, String className, NamedObj actorMetadataMoml) throws Exception { if (isDebugging) log.debug("lookForMoml"); if (_internalClassName.equals("org.kepler.moml.CompositeClassEntity")) { // This is a total hack, but I cannot get the // CompositeActors to clone correctly, so this try statement // basically clones them manually. It works so i'm leaving // it for now. try { StringBuffer sb = new StringBuffer(); // sb.append("<class name=\"" + actorName + // "\" extends=\"" + className + "\">"); sb.append("<entity name=\"" + actorName + "\" class=\"" + className + "\">"); // get attributes and clone them over to the new obj CompositeClassEntity cce = (CompositeClassEntity) actorMetadataMoml; Iterator<?> attItt = cce.attributeList().iterator(); while (attItt.hasNext()) { Attribute a = (Attribute) attItt.next(); sb.append(a.exportMoML()); } // get entities and clone them over to the new obj Iterator<?> entItt = cce.entityList().iterator(); while (entItt.hasNext()) { ComponentEntity ent = (ComponentEntity) entItt.next(); sb.append(ent.exportMoML()); } // get ports and clone them over to the new obj Iterator<?> portItt = cce.portList().iterator(); while (portItt.hasNext()) { Port p = (Port) portItt.next(); sb.append(p.exportMoML()); } // get relations and clone them over to the new obj TypedCompositeActor tca = (TypedCompositeActor) actorMetadataMoml; Iterator<?> relationItt = tca.relationList().iterator(); while (relationItt.hasNext()) { ComponentRelation r = (ComponentRelation) relationItt.next(); sb.append(r.exportMoML()); } sb.append(_links); // sb.append("</class>"); sb.append("</entity>"); Workspace w = actorMetadataMoml.workspace(); if (isDebugging) log.debug("**** MoMLParser ****"); MoMLParser parser = new MoMLParser(w); parser.reset(); NamedObj obj = parser.parse(sb.toString()); return obj; } catch (Exception exc) { System.out.println("error creating compositeClassEntity: " + exc.getMessage()); exc.printStackTrace(); throw exc; } } else { // see if the internal class name is a subclass of composite actor Class<?> clazz = Class.forName(_internalClassName); Class<?> compositeActorClass = Class.forName("ptolemy.actor.TypedCompositeActor"); if (compositeActorClass.isAssignableFrom(clazz)) { // parse the moml in the actor metadata MoMLParser parser = new MoMLParser(actorMetadataMoml.workspace()); parser.reset(); NamedObj obj = parser.parse(actorMetadataMoml.exportMoML()); return obj; } else { // ptolemy.kernel.ComponentEntity ComponentEntity actor = parseMoMLFile(className); if (isDebugging) { log.debug("returning " + actor.getName()); } return (TypedCompositeActor) actor; } } } /** * get the actor class and instantiate it to a NamedObj and return it */ private NamedObj getActorClass(String className, String actorName, NamedObj actorMetadataMoml) { if (isDebugging && actorMetadataMoml != null) { log.debug("getActorClass(" + className + "," + actorName + "," + actorMetadataMoml.getName() + ")"); } // try to get the actor class and instantiate it try { TypedAtomicActor actor; Class<?> actorClass = Class.forName(className); CompositeEntity ce = new CompositeEntity(); Object[] args = { ce, actorName }; actor = (TypedAtomicActor) createInstance(actorClass, args); // call the metadata handlers for (int i = 0; i < _metadataHandlerVector.size(); i++) { Object o = _metadataHandlerVector.elementAt(i); MetadataHandler handler = (MetadataHandler) o; handler.handleMetadata(actor); } return actor; } catch (Exception e) { if (isDebugging) { log.debug(e.toString()); log.debug(_internalClassName); } NamedObj secTry; try { secTry = lookForMoml(actorName, className, actorMetadataMoml); return secTry; } catch (Exception ee) { if (isDebugging) log.debug(ee.toString()); NamedObj thirdTry; try { thirdTry = handleNonEntityDirectors(actorName, className, actorMetadataMoml); return thirdTry; } catch (Exception eee) { if (isDebugging) log.debug(eee.toString()); NamedObj fourthTry; try { fourthTry = handleMiscAtt(actorName, className, actorMetadataMoml); return fourthTry; } catch (Exception eeee) { printFinalException(eeee, className); return null; } } } } } /** * Helper method. * @param eeee * @param className */ private void printFinalException(Exception eeee, String className) { System.out.println( "The class name you entered was either not " + "found in classpath or could not be instantiated:"); System.out.println(className); System.out.println( "Note that this class must be in the " + "classpath from which you launched this program."); String msg = eeee.getMessage(); if (msg != null) { System.out.println(msg); } } /** * Todo: What is this doing? * @param className * @param actorName * @param actorMetadataMoml * @return * @throws Exception */ private NamedObj handleMiscAtt(String actorName, String className, NamedObj actorMetadataMoml) throws Exception { Attribute att; Class<?> attClass = Class.forName(className); Object[] args = { new CompositeEntity(), actorName }; att = (Attribute) createInstance(attClass, args); return att; } /** * This handles directors which are not entities, but attributes * * @param className * @param actorName * @param actorMetadataMoml * @return * @throws Exception */ private NamedObj handleNonEntityDirectors(String actorName, String className, NamedObj actorMetadataMoml) throws Exception { Director director; Class<?> directorClass = Class.forName(className); Object[] args = { new CompositeEntity(), actorName }; director = (Director) createInstance(directorClass, args); return director; } /** * add all of the attributes with the exception of the kepler attributes * (which should already be in the metadata) to the AM object. * * @param obj * the NamedObj to get the attributes from. */ private void addAllAttributes() { NamedObj obj = getActor(); if (obj != null && obj.attributeList() != null) { List<?> attList = obj.attributeList(); Iterator<?> i = attList.iterator(); while (i.hasNext()) { Attribute a = (Attribute) i.next(); String name = a.getName(); if (!name.equals(NamedObjId.NAME) && !name.equals("class") && !name.equals("KeplerDocumentation") && name.indexOf("dependency") == -1) { addAttribute(a); } } } } private void removeLinks() { NamedObj obj = getActor(); if (obj == null) return; } /** * add all of the relations * * @param obj * the NamedObj to get the attributes from. */ private void addAllRelations() { NamedObj obj = getActor(); if (obj == null) return; if (obj instanceof TypedCompositeActor) { TypedCompositeActor tca = (TypedCompositeActor) obj; List<?> relList = tca.relationList(); if (relList != null) { Iterator<?> i = relList.iterator(); while (i.hasNext()) { ComponentRelation r = (ComponentRelation) i.next(); addRelation(r); } } } } /** * search the classpath for a specific class and return the file. In the * tradition of ptolemy, this will also search for moml files with a class * definition. this is required for composite actors. * * @param className * the name of the class to search for * @param workDir * the directory where temp files can be created */ protected File searchClasspath(String className) throws FileNotFoundException { // separate the class name from the package path String actualClassName = className.substring(className.lastIndexOf(".") + 1, className.length()); String packagePath = className.substring(0, className.lastIndexOf(".")); String[] packagePathStruct = packagePath.split("\\."); // get the classpath so we can search for the class files String classpath = System.getProperty("java.class.path"); String sep = System.getProperty("path.separator"); StringTokenizer st = new StringTokenizer(classpath, sep); while (st.hasMoreTokens()) { String path = st.nextToken(); File pathDir = new File(path); if (pathDir.isDirectory()) { // search the directory for the file if (matchDirectoryPath(pathDir, packagePathStruct, 0)) { // now we found a candidate...see if the class is in there File classDir = new File(pathDir.getAbsolutePath() + File.separator + packagePath.replace('.', File.separator.toCharArray()[0])); File[] classDirFiles = classDir.listFiles(); for (int i = 0; i < classDirFiles.length; i++) { String dirFileName = classDirFiles[i].getName(); if (dirFileName.indexOf(".") != -1) { String extension = dirFileName.substring(dirFileName.lastIndexOf("."), dirFileName.length()); String prefix = dirFileName.substring(0, dirFileName.lastIndexOf(".")); if (actualClassName.equals(prefix) && (extension.equals(".class") || extension.equals(".xml"))) { // search for xml or class files return classDirFiles[i]; } } } } } else if (pathDir.isFile()) { // search a jar file for the file. if it's not a jar file, // ignore it try { String entryName = className.replace('.', '/') + ".class"; JarFile jarFile = null; try { jarFile = new JarFile(pathDir); // this looks for a class file JarEntry entry = jarFile.getJarEntry(entryName); if (entry != null) { // get the class file from the jar and return it return pathDir; } else { // look for the xml file instead entryName = className.replace('.', '/') + ".xml"; entry = jarFile.getJarEntry(entryName); if (entry != null) { return pathDir; } } } finally { if (jarFile != null) { jarFile.close(); } } } catch (Exception e) { // keep going if this isn't a jar file continue; } } } throw new FileNotFoundException("Cannot find the specified class " + "file in the classpath."); } /** * locates a directory based on an array of paths to look for. for instance, * if you are searching for org/kepler/kar searchForMe would be {org, * kepler, kar}. dir is where the search starts. Index should start out as * 0. */ private boolean matchDirectoryPath(File dir, String[] searchForMe, int index) { File[] dirContents = dir.listFiles(); for (int i = 0; i < dirContents.length; i++) { if (dirContents[i].getName().equals(searchForMe[index])) { if (index < searchForMe.length - 1) { if (index < searchForMe.length) { return matchDirectoryPath(dirContents[i], searchForMe, ++index); } else { return false; } } else { return true; } } } return false; } /** * try to locate and parse a moml file as a class */ protected ComponentEntity parseMoMLFile(String className) throws Exception { if (isDebugging) log.debug("parseMoMLFile(" + className + ")"); JarFile jarFile = null; InputStream xmlStream = null; try { // first we need to find the file and read it File classFile = searchClasspath(className); StringWriter sw = new StringWriter(); if (classFile.getName().endsWith(".jar")) { jarFile = new JarFile(classFile); ZipEntry entry = jarFile.getEntry(className.replace('.', '/') + ".xml"); xmlStream = jarFile.getInputStream(entry); } else { xmlStream = new FileInputStream(classFile); } byte[] b = new byte[1024]; int numread = xmlStream.read(b, 0, 1024); while (numread != -1) { String s = new String(b, 0, numread); sw.write(s); numread = xmlStream.read(b, 0, 1024); } sw.flush(); // get the moml document String xmlDoc = sw.toString(); sw.close(); if (isDebugging) log.debug("**** MoMLParser ****"); // use the moml parser to parse the doc MoMLParser parser = new MoMLParser(); parser.reset(); // System.out.println("processing " + className); NamedObj obj = parser.parse(xmlDoc); return (ComponentEntity) obj; } finally { if (jarFile != null) { jarFile.close(); } if (xmlStream != null) { xmlStream.close(); } } } /** * createInstance. creates an instance of a class object. taken from * ptolemy's MomlParser class. modified for this application. * * @param newClass *@param arguments *@return TypedAtomicActor *@exception Exception */ public static NamedObj createInstance(Class<?> newClass, Object[] arguments) throws Exception { if (isDebugging) log.debug("createInstance(" + newClass + "," + arguments + ")"); Constructor<?>[] constructors = newClass.getConstructors(); for (int i = 0; i < constructors.length; i++) { Constructor<?> constructor = constructors[i]; Class<?>[] parameterTypes = constructor.getParameterTypes(); for (int j = 0; j < parameterTypes.length; j++) { Class<?> c = parameterTypes[j]; if (isDebugging) log.debug(c.getName()); } if (parameterTypes.length != arguments.length) { continue; } boolean match = true; for (int j = 0; j < parameterTypes.length; j++) { if (!(parameterTypes[j].isInstance(arguments[j]))) { match = false; break; } } if (match) { NamedObj newEntity = (NamedObj) constructor.newInstance(arguments); return newEntity; } } // If we get here, then there is no matching constructor. // Generate a StringBuffer containing what we were looking for. StringBuffer argumentBuffer = new StringBuffer(); for (int i = 0; i < arguments.length; i++) { argumentBuffer.append(arguments[i].getClass() + " = \"" + arguments[i].toString() + "\""); if (i < (arguments.length - 1)) { argumentBuffer.append(", "); } } throw new Exception("Cannot find a suitable constructor (" + arguments.length + " args) (" + argumentBuffer + ") for '" + newClass.getName() + "'"); } /** * This method is just a helper debugging method to write out the object * moml to a file in a specified location on disk, the cache dir. * * @param obj * @param filename */ private void writeDebugMomlFor(NamedObj obj, String filename) { String momlExport = obj.exportMoML(); DotKeplerManager dkm = DotKeplerManager.getInstance(); File f = new File(dkm.getCacheDir(), filename); FileWriter fw; try { fw = new FileWriter(f); fw.write(momlExport, 0, momlExport.length()); fw.flush(); fw.close(); System.out.println("done exporting debug moml: " + f.toString()); } catch (IOException e) { e.printStackTrace(); } } /** * metadata object for a classed property */ private static class ClassedProperty implements Serializable { public String name = ""; public String value = ""; public String className = ""; public Integer iterator = null; /** * constructor */ public ClassedProperty(String name, String value, String className) { this.name = name; this.value = value; this.className = className; } /** * adds an integer to the end of the name of the property if there is * more than one of these properties. for instance: semanticType0, * semanticType1, etc. * * @param int i the number to add to the name. */ public void addNameIterator(int i) { iterator = Integer.valueOf(i); } /** * create the xml rep of the ClassedProperty */ public String toString() { if (iterator == null) { return "<property name=\"" + name + "\" value=\"" + value + "\" class=\"" + className + "\"/>"; } else { int itt = iterator.intValue(); return "<property name=\"" + name + itt + "\" value=\"" + value + "\" class=\"" + className + "\"/>"; } } } /** * metadata object that represents a port */ private static class PortMetadata implements Serializable { public String name = ""; public String direction = ""; public String type = ""; public boolean multiport = false; public Vector<NamedObj> attributes = new Vector<NamedObj>(); /** The class name of the port, e.g., ptolemy.actor.TypedIOPort */ public String portClassName; public void addAttribute(NamedObj att) { attributes.addElement(att); } /** * return the moml xml rep of the port * * */ public String toString() { StringBuffer sb = new StringBuffer(); if (name.indexOf("kepler:") != -1) { sb.append("<property name=\"" + name + "\" class=\"org.kepler.moml.PortAttribute\">\n"); } else { sb.append("<property name=\"kepler:" + name + "\" class=\"org.kepler.moml.PortAttribute\">\n"); } sb.append(" <property name=\"direction\" value=\"" + direction + "\" class=\"ptolemy.kernel.util.StringAttribute\"/>\n"); sb.append(" <property name=\"dataType\" value=\"" + type + "\" class=\"ptolemy.kernel.util.StringAttribute\"/>\n"); sb.append(" <property name=\"isMultiport\" value=\"" + multiport + "\" class=\"ptolemy.kernel.util.StringAttribute\"/>\n"); for (int i = 0; i < attributes.size(); i++) { // System.out.println("appending port attribute: " + // ((NamedObj)attributes.elementAt(i)).exportMoML()); sb.append(" " + ((NamedObj) attributes.elementAt(i)).exportMoML()); } sb.append("</property>\n"); /* * sb.append("<port name=\"" + name + * "\" class=\"ptolemy.actor.IOPort\">\n"); * sb.append(" <property name=\"direction\" value=\"" + direction + * "\" class=\"ptolemy.kernel.util.StringAttribute\"/>\n"); * sb.append(" <property name=\"dataType\" value=\"" + type + * "\" class=\"ptolemy.kernel.util.StringAttribute\"/>\n"); * sb.append(" <property name=\"isMultiport\" value=\"" + multiport * + "\" class=\"ptolemy.kernel.util.StringAttribute\"/>\n"); * sb.append("</port>\n"); */ return sb.toString(); } public String toMoMLString() { StringBuffer sb = new StringBuffer(); String dispName = name; if (name.indexOf("kepler:") != -1) { dispName = name.substring(8, name.length()); } String escapedDispName = StringUtilities.escapeForXML(dispName); sb.append("<port name=\"" + escapedDispName + "\" class=\"" + portClassName + "\">\n"); if (direction.equals("input")) { sb.append(" <property name=\"input\"/>\n"); } if (direction.equals("output")) { sb.append(" <property name=\"output\"/>\n"); } if (direction.equals("inputoutput")) { sb.append(" <property name=\"output\"/>\n"); sb.append(" <property name=\"input\"/>\n"); } // added by Dan Higgins April 2007 sb.append(" <property name=\"dataType\" value=\"" + type + "\" class=\"ptolemy.kernel.util.StringAttribute\"/>\n"); sb.append(" <property name=\"isMultiport\" value=\"" + multiport + "\" class=\"ptolemy.kernel.util.StringAttribute\"/>\n"); for (int i = 0; i < attributes.size(); i++) { // System.out.println("appending port attribute: " + // ((NamedObj)attributes.elementAt(i)).exportMoML()); sb.append(" " + ((NamedObj) attributes.elementAt(i)).exportMoML()); } // end addition by Dan Higgins April 2007 sb.append("</port>\n"); return sb.toString(); } } }