// refer to files whose location is relative
// to the URL location.
if (_xmlFile != null) {
// Add a URL attribute to the toplevel to
// indicate where it was read from.
URIAttribute attribute = new URIAttribute(_toplevel,
"_uri");
attribute.setURL(_xmlFile);
}
}
boolean converted = false;
if (!existedAlready) {
entity.setClassDefinition(true);
// Adjust the classname and superclass of the object.
// NOTE: This used to set the class name to entity.getFullName(),
// and superclass to className. Now that we've consolidated
// these, we set the class name to the value of "extends"
// attribute that was used to create this.
entity.setClassName(className);
} else {
// If the object is not already a class, then convert
// it to one.
if (!entity.isClassDefinition()) {
entity.setClassDefinition(true);
converted = true;
}
}
_current = entity;
_namespace = _DEFAULT_NAMESPACE;
if (_undoEnabled) {
// Handle the undo aspect.
if (existedAlready) {
if (!converted) {
_undoContext.appendUndoMoML("<class name=\""
+ entityName + "\" >\n");
// Need to continue undoing and use an end tag
_undoContext.appendClosingUndoMoML("</class>\n");
} else {
// Converting from entity to class, so reverse this.
_undoContext.appendUndoMoML("<entity name=\""
+ entityName + "\" >\n");
// Need to continue undoing and use an end tag
_undoContext.appendClosingUndoMoML("</entity>\n");
}
_undoContext.setChildrenUndoable(true);
} else {
_undoContext.appendUndoMoML("<deleteEntity name=\""
+ entityName + "\" />\n");
// Do not need to continue generating undo MoML
// as the deleteEntity takes care of all
// contained MoML
_undoContext.setChildrenUndoable(false);
_undoContext.setUndoable(false);
// Prevent any further undo entries for this context.
_undoEnabled = false;
}
}
//////////////////////////////////////////////////////////////
//// configure
} else if (elementName.equals("configure")) {
_checkClass(_current, Configurable.class,
"Element \"configure\" found inside an element that "
+ "does not implement Configurable. It is: "
+ _current);
_configureSource = (String) _attributes.get("source");
_currentCharData = new StringBuffer();
// Count configure tags so that they can nest.
_configureNesting++;
//////////////////////////////////////////////////////////////
//// deleteEntity
} else if (elementName.equals("deleteEntity")) {
String entityName = (String) _attributes.get("name");
_checkForNull(entityName,
"No name for element \"deleteEntity\"");
// Link is stored and processed last, but before deletions.
DeleteRequest request = new DeleteRequest(_DELETE_ENTITY,
entityName, null);
// Only defer if we are in a class, entity, or model context,
// which is equivalent to the _current being an instance of
// InstantiableNamedObj.
if ((_deleteRequests != null)
&& _current instanceof InstantiableNamedObj) {
_deleteRequests.add(request);
} else {
// Very likely, the context is null, in which
// case the following will throw an exception.
// We defer to it in case somehow a link request
// is being made at the top level with a non-null
// context (e.g. via a change request).
request.execute();
}
// NOTE: deleteEntity is not supposed to have anything
// inside it, so we do not push the context.
//////////////////////////////////////////////////////////////
//// deletePort
} else if (elementName.equals("deletePort")) {
String portName = (String) _attributes.get("name");
_checkForNull(portName, "No name for element \"deletePort\"");
// The entity attribute is optional.
String entityName = (String) _attributes.get("entity");
// Delete the corresponding ParameterPort, if any.
Port toDelete = null;
try {
toDelete = _searchForPort(portName);
} catch (XmlException ex) {
// Ignore, there is no port by that name.
}
// Find the corresponding ParameterPort and delete it
if (toDelete != null) {
NamedObj container = toDelete.getContainer();
if (container != null && container instanceof Entity) {
Attribute attribute = ((Entity) container)
.getAttribute(portName);
if (attribute != null
&& attribute instanceof PortParameter) {
DeleteRequest request = new DeleteRequest(
_DELETE_PROPERTY, attribute.getName(), null);
// Only defer if we are in a class, entity, or
// model context, which is equivalent to the
// _current being an instance of
// InstantiableNamedObj.
if ((_deleteRequests != null)
&& _current instanceof InstantiableNamedObj) {
_deleteRequests.add(request);
} else {
// Very likely, the context is null, in which
// case the following will throw an exception.
// We defer to it in case somehow a link request
// is being made at the top level with a non-null
// context (e.g. via a change request).
request.execute();
}
}
}
}
// Link is stored and processed last, but before deletions.
DeleteRequest request = new DeleteRequest(_DELETE_PORT,
portName, entityName);
// Only defer if we are in a class, entity, or model context,
// which is equivalent to the _current being an instance of
// InstantiableNamedObj.
if ((_deleteRequests != null)
&& _current instanceof InstantiableNamedObj) {
_deleteRequests.add(request);
} else {
// Very likely, the context is null, in which
// case the following will throw an exception.
// We defer to it in case somehow a link request
// is being made at the top level with a non-null
// context (e.g. via a change request).
request.execute();
}
// NOTE: deletePort is not supposed to have anything
// inside it, so we do not push the context.
//////////////////////////////////////////////////////////////
//// deleteProperty
} else if (elementName.equals("deleteProperty")) {
String propName = (String) _attributes.get("name");
_checkForNull(propName,
"No name for element \"deleteProperty\"");
// Link is stored and processed last, but before deletions.
DeleteRequest request = new DeleteRequest(_DELETE_PROPERTY,
propName, null);
// We use toDelete to find any PortParameters
Attribute toDelete = _searchForAttribute(propName);
// Only defer if we are in a class, entity, or model context,
// which is equivalent to the _current being an instance of
// InstantiableNamedObj.
if ((_deleteRequests != null)
&& _current instanceof InstantiableNamedObj) {
_deleteRequests.add(request);
} else {
// Very likely, the context is null, in which
// case the following will throw an exception.
// We defer to it in case somehow a link request
// is being made at the top level with a non-null
// context (e.g. via a change request).
request.execute();
}
// Find the corresponding PortParameter and delete it
NamedObj container = toDelete.getContainer();
if (container != null && container instanceof Entity) {
Port port = ((Entity) container).getPort(propName);
if (port != null && port instanceof ParameterPort) {
request = new DeleteRequest(_DELETE_PORT, port
.getName(), container.getFullName());
// Only defer if we are in a class, entity, or
// model context, which is equivalent to the
// _current being an instance of
// InstantiableNamedObj.
if ((_deleteRequests != null)
&& _current instanceof InstantiableNamedObj) {
_deleteRequests.add(request);
} else {
// Very likely, the context is null, in which
// case the following will throw an exception.
// We defer to it in case somehow a link request
// is being made at the top level with a non-null
// context (e.g. via a change request).
request.execute();
}
}
}
// NOTE: deleteProperty is not supposed to have anything
// inside it, so we do not push the context.
//////////////////////////////////////////////////////////////
//// deleteRelation
} else if (elementName.equals("deleteRelation")) {
String relationName = (String) _attributes.get("name");
_checkForNull(relationName,
"No name for element \"deleteRelation\"");
// Link is stored and processed last, but before deletions.
DeleteRequest request = new DeleteRequest(_DELETE_RELATION,
relationName, null);
// Only defer if we are in a class, entity, or model context,
// which is equivalent to the _current being an instance of
// InstantiableNamedObj.
if ((_deleteRequests != null)
&& _current instanceof InstantiableNamedObj) {
_deleteRequests.add(request);
} else {
// Very likely, the context is null, in which
// case the following will throw an exception.
// We defer to it in case somehow a link request
// is being made at the top level with a non-null
// context (e.g. via a change request).
request.execute();
}
// NOTE: deleteRelation is not supposed to have anything
// inside it, so we do not push the context.
//////////////////////////////////////////////////////////////
//// director
} else if (elementName.equals("director")) {
// NOTE: The director element is deprecated.
// Use a property instead. This is kept here so that
// this parser can read older MoML files.
// NOTE: We do not check for a previously existing director.
// There is presumably no harm in just creating a new one.
String className = (String) _attributes.get("class");
_checkForNull(className, "No class for element \"director\"");
String dirName = (String) _attributes.get("name");
_checkForNull(dirName, "No name for element \"director\"");
_checkClass(_current, CompositeActor.class,
"Element \"director\" found inside an element that "
+ "is not a CompositeActor. It is: " + _current);
Object[] arguments = new Object[2];
arguments[0] = _current;
arguments[1] = dirName;
// NamedObj container = _current;
_pushContext();
Class newClass = Class.forName(className, true, _classLoader);
// NOTE: No propagation occurs here... Hopefully, deprecated
// elements are not used with class structures.
_current = _createInstance(newClass, arguments);
_namespace = _DEFAULT_NAMESPACE;
//////////////////////////////////////////////////////////////
//// display
} else if (elementName.equals("display")) {
String displayName = (String) _attributes.get("name");
if (_current != null) {
// Propagate.
Iterator derivedObjects = _current.getDerivedList()
.iterator();
String currentName = _current.getName();
while (derivedObjects.hasNext()) {
NamedObj derived = (NamedObj) derivedObjects.next();
// If the derived object has the same
// name as the old name, then we assume it
// should change.
if (derived.getName().equals(currentName)) {
if (displayName != null) {
if (displayName.equals(currentName)) {
// The displayName is the same as the
// name, so it should be reset to null.
derived.setDisplayName(null);
} else {
derived.setDisplayName(displayName);
}
}
}
}
// Now change the display name.
String oldDisplayName = _current.getDisplayName();
if (displayName != null) {
if (displayName.equals(currentName)
|| displayName.equals("")) {
// The displayName is the same as the
// name, so it should be reset to null.
_current.setDisplayName(null);
} else {
_current.setDisplayName(displayName);
}
// Handle the undo aspect if needed
if (_undoEnabled) {
// Simply create in the undo MoML another display element.
_undoContext.appendUndoMoML("<display name=\""
+ StringUtilities
.escapeForXML(oldDisplayName)
+ "\"/>\n");
// Do not need to continue generating undo MoML
// as rename does not have any child elements
_undoContext.setChildrenUndoable(false);
}
}
}
//////////////////////////////////////////////////////////////
//// doc
} else if (elementName.equals("doc")) {
_currentDocName = (String) _attributes.get("name");
_currentCharData = new StringBuffer();
// Count doc tags so that they can nest.
_docNesting++;
//////////////////////////////////////////////////////////////
//// entity
} else if (elementName.equals("entity")
|| elementName.equals("model")) {
// NOTE: The "model" element is deprecated. It is treated
// exactly as an entity.
String className = (String) _attributes.get("class");
String entityName = (String) _attributes.get("name");
_checkForNull(entityName, "No name for element \"entity\"");
String source = (String) _attributes.get("source");
// For undo purposes need to know if the entity existed
// already
Entity entity = _searchForEntity(entityName, _current);
boolean existedAlready = (entity != null);
boolean converted = false;
if (existedAlready) {
// Check whether it was previously a class, in which case
// it is being converted to an entity.
if (entity.isClassDefinition()) {
entity.setClassDefinition(false);
converted = true;
}
} else {
NamedObj candidate = _createEntity(className, entityName,
source);
if (candidate instanceof Entity) {
entity = (Entity) candidate;
entity.setClassName(className);
} else {
throw new IllegalActionException(_current,
"Attempt to create an entity named "
+ entityName + " from a class that "
+ "is not a subclass of Entity: "
+ className);
}
}
// NOTE: The entity may be at the top level, in
// which case _deleteRequests is null.
if (_deleteRequests != null) {
_deleteRequestStack.push(_deleteRequests);
pushedDeleteRequests = true;
}
_deleteRequests = new LinkedList();
// NOTE: The entity may be at the top level, in
// which case _linkRequests is null.
if (_linkRequests != null) {
_linkRequestStack.push(_linkRequests);
pushedLinkRequests = true;
}
_linkRequests = new LinkedList();
if (_current != null) {
_pushContext();
} else if (_toplevel == null) {
// NOTE: We used to set _toplevel to newEntity, but
// this isn't quite right because the entity may have a
// composite name.
_toplevel = entity.toplevel();
// Ensure that if any change requests occur as a
// consequence of adding items to this top level,
// that execution of those change requests is deferred
// until endDocument().
_toplevel.setDeferringChangeRequests(true);
// As early as possible, set URL attribute.
// This is needed in case any of the parameters
// refer to files whose location is relative
// to the URL location.
if (_xmlFile != null) {
// Add a URL attribute to the toplevel to
// indicate where it was read from.
URIAttribute attribute = new URIAttribute(_toplevel,
"_uri");
attribute.setURL(_xmlFile);
}
}
_current = entity;