/** * For each port of the given entity, if the port's derived level is greater than 0 (i.e., it is * created automatically by the entity), store the persistent attributes of the port in a "port" * XML element. * * @param entity The entity whose ports are looked at. * @param output The output writer. * @param depth The depth for the MoML output. * @exception IOException If the output writer cannot be written to. */ public static void exportPortProperties(GTEntity entity, Writer output, int depth) throws IOException { if (entity instanceof Entity) { Entity ptEntity = (Entity) entity; for (Object portObject : ptEntity.portList()) { Port port = (Port) portObject; if (port.getDerivedLevel() == 0) { continue; } boolean outputStarted = false; for (Object attributeObject : port.attributeList()) { Attribute attribute = (Attribute) attributeObject; if (attribute.isPersistent()) { if (!outputStarted) { output.write( StringUtilities.getIndentPrefix(depth) + "<port name=\"" + port.getName() + "\">\n"); outputStarted = true; } attribute.exportMoML(output, depth + 1); } } if (outputStarted) { output.write(StringUtilities.getIndentPrefix(depth) + "</port>\n"); } } } }
/** * Set the name of the port, and mirror the change in all the mirror ports. This method is * write-synchronized on the workspace, and increments the version of the workspace. * * @exception IllegalActionException If the name has a period. * @exception NameDuplicationException If there is already a port with the same name in the * container. */ @Override public void setName(String name) throws IllegalActionException, NameDuplicationException { boolean disableStatus = _mirrorDisable; try { _workspace.getWriteAccess(); if (_mirrorDisable || getContainer() == null) { // change sibling if (_hasSibling && isOutput() && getContainer() != null) { TransitionRefinement container = (TransitionRefinement) getContainer(); TransitionRefinementPort sibling = (TransitionRefinementPort) container.getPort(getName() + "_in"); sibling._mirrorDisable = true; sibling.setName(name + "_in"); sibling._mirrorDisable = false; } // Have already called the super class. // This time, process the request. super.setName(name); } else { _mirrorDisable = true; boolean success = false; Nameable container = getContainer(); if (container != null) { Nameable modal = container.getContainer(); if (modal instanceof ModalModel) { Port port = ((ModalModel) modal).getPort(getName()); if (port != null) { port.setName(name); success = true; } } } if (!success) { super.setName(name); } } } finally { _mirrorDisable = disableStatus; _workspace.doneWriting(); } }
/** * Remove all the annotations from the graph. Actors, their ports, and relations are inspected to * see if they either a _color and/or an _explanation attribute. If so, then the attribute is * removed via a MoMl changeRequest. */ public void deAnnotateGraph() { StringBuffer moml = new StringBuffer(); Iterator entities = _model.entityList(ComponentEntity.class).iterator(); while (entities.hasNext()) { ComponentEntity entity = (ComponentEntity) (entities.next()); String entityDeletes = _deletesIfNecessary(entity); moml.append("<entity name=\"" + entity.getName() + "\">"); if (entityDeletes != null) { moml.append(entityDeletes); } Iterator ports = entity.portList().iterator(); while (ports.hasNext()) { Port port = (Port) (ports.next()); String portDeletes = _deletesIfNecessary(port); if (portDeletes != null) { moml.append("<port name=\"" + port.getName() + "\">" + portDeletes + "</port>"); } } moml.append("</entity>"); } Iterator relations = _model.relationList().iterator(); while (relations.hasNext()) { Relation relation = (Relation) (relations.next()); String relationDeletes = _deletesIfNecessary(relation); if (relationDeletes != null) { moml.append( "<relation name=\"" + relation.getName() + "\">" + relationDeletes + "\"/></relation>"); } } if (moml.length() > 0) { String momlUpdate = "<group>" + moml.toString() + "</group>"; MoMLChangeRequest request = new MoMLChangeRequest(this, _model, momlUpdate); request.setUndoable(true); request.setPersistent(false); _model.requestChange(request); } }
/** * Remove all ports by setting their container to null. As a side effect, the ports will be * unlinked from all relations. This method is write-synchronized on the workspace, and increments * its version number. */ public void removeAllPorts() { try { _workspace.getWriteAccess(); // Have to copy _portList to avoid corrupting the iterator. List portListCopy = new LinkedList(portList()); Iterator ports = portListCopy.iterator(); while (ports.hasNext()) { Port port = (Port) ports.next(); try { MoMLChangeRequest request = new MoMLChangeRequest(this, this, "<deletePort name=\"" + port.getName() + "\"/>"); request.setUndoable(true); requestChange(request); } catch (Exception ex) { // Ignore. } } } finally { _workspace.doneWriting(); } }
/** * Override the base class so that if the port is being removed from the current container, then * it is also removed from the controller and from each of the refinements. * * @param container The proposed container. * @exception IllegalActionException If the proposed container is not a ComponentEntity, doesn't * implement Actor, or has no name, or the port and container are not in the same workspace. * Or it's not null * @exception NameDuplicationException If the container already has a port with the name of this * port. */ public void setContainer(Entity container) throws IllegalActionException, NameDuplicationException { NamedObj oldContainer = getContainer(); if (container == oldContainer) { // Nothing to do. return; } boolean disableStatus = _mirrorDisable; try { _workspace.getWriteAccess(); if (_mirrorDisable || (getContainer() == null)) { // process request for the sibling if (_hasSibling && isOutput() && (getContainer() != null)) { TransitionRefinement transContainer = (TransitionRefinement) oldContainer; TransitionRefinementPort sibling = (TransitionRefinementPort) transContainer.getPort(getName() + "_in"); sibling._mirrorDisable = true; sibling.setContainer(container); sibling._mirrorDisable = false; } // Have already called the super class. // This time, process the request. super.setContainer(container); } else { // if this is the input port of a pair of siblings, // then forward request to the output port of the pair _mirrorDisable = true; boolean success = false; String portName = getName(); if (_hasSibling && isInput() && !isOutput()) { // we are the input sibling, extract "real" port name portName = getName().substring(0, getName().length() - 3); } if (oldContainer != null) { Nameable modal = oldContainer.getContainer(); if (modal instanceof ModalModel) { Port port = ((ModalModel) modal).getPort(portName); if (port != null) { port.setContainer(null); success = true; } } } if (!success) { super.setContainer(container); } } } finally { _mirrorDisable = disableStatus; _workspace.doneWriting(); } }
/** * Update the appearance (icons and ports) of the entity with the change in a * GTIngredientAttribute, such as a criterion or an operation. * * @param entity The entity. * @param attribute The attribute whose recent change leads to an update of the entity. */ public static void updateAppearance(final GTEntity entity, GTIngredientsAttribute attribute) { NamedObj object = (NamedObj) entity; Workspace workspace = object.workspace(); try { workspace.getWriteAccess(); List<?> icons = object.attributeList(EditorIcon.class); boolean foundPersistentIcon = false; for (Object iconObject : icons) { EditorIcon icon = (EditorIcon) iconObject; if (icon.isPersistent()) { foundPersistentIcon = true; break; } } Set<String> preservedPortNames = new HashSet<String>(); boolean isIconSet = false; int i = 1; GTIngredientList list = attribute.getIngredientList(); for (GTIngredient ingredient : list) { if (ingredient instanceof PortCriterion) { PortCriterion criterion = (PortCriterion) ingredient; String portID = criterion.getPortID(list); preservedPortNames.add(portID); TypedIOPort port = (TypedIOPort) ((ComponentEntity) entity).getPort(portID); boolean isInput = criterion.isInput(); boolean isOutput = criterion.isOutput(); boolean isMultiport = !criterion.isMultiportEnabled() || criterion.isMultiport(); if (port != null) { if (port instanceof PortMatcher) { port.setInput(isInput); port.setOutput(isOutput); } else { MoMLChangeRequest request = new MoMLChangeRequest( entity, object, "<deletePort name=\"" + port.getName() + "\"/>"); request.setUndoable(true); request.setMergeWithPreviousUndo(true); request.execute(); port = new PortMatcher(criterion, (ComponentEntity) entity, portID, isInput, isOutput); port.setDerivedLevel(1); } } else { port = new PortMatcher(criterion, (ComponentEntity) entity, portID, isInput, isOutput); port.setDerivedLevel(1); } port.setMultiport(isMultiport); } else if (ingredient instanceof SubclassCriterion && !isIconSet && !foundPersistentIcon) { SubclassCriterion criterion = (SubclassCriterion) ingredient; final String superclass = criterion.getSuperclass(); object.requestChange( new ChangeRequest(entity, "Deferred load actor icon action.") { protected void _execute() throws Exception { _loadActorIcon(entity, superclass); } }); isIconSet = true; } i++; } if (!isIconSet && !foundPersistentIcon) { object.requestChange(new RestoreAppearanceChangeRequest(entity)); } ComponentEntity component = (ComponentEntity) entity; try { component.workspace().getReadAccess(); List<?> portList = new LinkedList<Object>(component.portList()); for (i = 0; i < portList.size(); i++) { Port port = (Port) portList.get(i); if (port instanceof PortMatcher && !preservedPortNames.contains(port.getName())) { ((PortMatcher) port)._setPortCriterion(null); port.setContainer(null); } } } finally { component.workspace().doneReading(); } } catch (KernelException e) { throw new KernelRuntimeException( e, "Cannot update appearance for " + "actor " + entity.getName() + "."); } finally { workspace.doneWriting(); } }
/** * Create a new port with the specified name in the container of this controller, which in turn * creates a port in this controller and all the refinements. This method is write-synchronized on * the workspace. * * @param name The name to assign to the newly created port. * @return The new port. * @exception NameDuplicationException If the entity already has a port with the specified name. */ public Port newPort(String name) throws NameDuplicationException { try { _workspace.getWriteAccess(); ModalModel container = (ModalModel) getContainer(); if (_mirrorDisable == 1 || container == null) { // We are mirroring a change above in the hierarchy // (or there is no above in the hierarchy), // so we should not mirror this change upwards. // But we should mirror it downwards. ModalRefinementPort port = new ModalRefinementPort(this, name); // Create the links on the outside of the new port. if (container != null) { String relationName = name + "Relation"; Relation relation = container.getRelation(relationName); if (relation == null) { relation = container.newRelation(relationName); Port containerPort = container.getPort(name); containerPort.link(relation); } port.link(relation); } // Mirror the change downwards in the hierarchy. Iterator entities = entityList().iterator(); while (entities.hasNext()) { Entity entity = (Entity) entities.next(); if (entity instanceof RefinementActor) { if (entity.getPort(name) == null) { try { ((RefinementActor) entity).setMirrorDisable(1); entity.newPort(name); } finally { ((RefinementActor) entity).setMirrorDisable(0); } } } } return port; } else { // We are originating the change, or it originated from // below us in the hierarchy, and hence should delegate // it upwards. This will cause this newPort() method // to be called again by the container after it has // created its own port. That will result in the code // above executing because it will set _mirrorPort to 1 // on this port before doing the call. ModalRefinementPort containerPort = container == null ? null : (ModalRefinementPort) container.getPort(name); if (containerPort == null) { // The container does not have a mirror port. // Delegate upwards. // Note that this will result in the container // creating the port here by calling this // newPort() method. It will set my // _mirrorDisable to 1 before doing that, // and set it back to 0 after. container.newPort(name); return getPort(name); } else { // The container already has a mirror port, so // we cannot use it to create our port. // This can happen if the container was created first // and populated with its ports before this refinement // was created. ModalRefinementPort port = new ModalRefinementPort(this, name); // Create the link on the outside of the port. String relationName = name + "Relation"; Relation relation = container.getRelation(relationName); // The container should already have this relation, // but in case not, we create it. if (relation == null) { relation = container.newRelation(relationName); containerPort.link(relation); } port.link(relation); // Mirror the change downwards in the hierarchy. Iterator entities = entityList().iterator(); while (entities.hasNext()) { Entity entity = (Entity) entities.next(); if (entity instanceof RefinementActor) { if (entity.getPort(name) == null) { try { ((RefinementActor) entity).setMirrorDisable(1); entity.newPort(name); } finally { ((RefinementActor) entity).setMirrorDisable(0); } } } } return port; } } } catch (IllegalActionException ex) { // This exception should not occur, so we throw a runtime // exception. throw new InternalErrorException( "ModalRefinement.newPort: Internal error: " + ex.getMessage()); } finally { _mirrorDisable = 0; _workspace.doneWriting(); } }
/** * Write a MoML description of the contents of this object, wrapped in a configure element. This * is done by first populating the model, and then exporting its contents into a configure * element. This method is called by exportMoML(). Each description is indented according to the * specified depth and terminated with a newline character. * * @param output The output stream to write to. * @param depth The depth in the hierarchy, to determine indenting. * @exception IOException If an I/O error occurs. */ protected void _exportMoMLContents(Writer output, int depth) throws IOException { populate(); // Export top level attributes and ports List _attributes = attributeList(); String _displayName = getDisplayName(); // FIXME: start of duplicated code from NamedObj // If the display name has been set, then include a display element. // Note that copying parameters that have _displayName set need // to export _displayName. // See: http://bugzilla.ecoinformatics.org/show_bug.cgi?id=3361 if (!_displayName.equals(getName())) { output.write("<display name=\""); output.write(StringUtilities.escapeForXML(_displayName)); output.write("\"/>"); } // Callers of this method should hold read access // so as to avoid ConcurrentModificationException. if (_attributes != null) { // Iterator attributes = _attributes.elementList().iterator(); Iterator attributes = _attributes.iterator(); while (attributes.hasNext()) { Attribute attribute = (Attribute) attributes.next(); attribute.exportMoML(output, depth); } } // FIXME: end of duplicated code from NamedObj // FIXME: start of duplicated code from Entity Iterator ports = portList().iterator(); while (ports.hasNext()) { Port port = (Port) ports.next(); port.exportMoML(output, depth); } // FIXME: end of duplicated code from Entity // Everything else is in a configure output.write(_getIndentPrefix(depth) + "<configure>\n"); output.write(_getIndentPrefix(depth + 1) + "<group>\n"); // FIXME: start of duplicated code from CompositeEntity Iterator classes = classDefinitionList().iterator(); while (classes.hasNext()) { ComponentEntity entity = (ComponentEntity) classes.next(); entity.exportMoML(output, depth + 2); } Iterator entities = entityList().iterator(); while (entities.hasNext()) { ComponentEntity entity = (ComponentEntity) entities.next(); entity.exportMoML(output, depth + 2); } Iterator relations = relationList().iterator(); while (relations.hasNext()) { ComponentRelation relation = (ComponentRelation) relations.next(); relation.exportMoML(output, depth + 2); } // NOTE: We used to write the links only if // this object did not defer to another // (getMoMLInfo().deferTo was null), and // would instead record links in a MoMLAttribute. // That mechanism was far too fragile. // EAL 3/10/04 output.write(exportLinks(depth + 2, null)); // FIXME: end of duplicated code from CompositeEntity output.write(_getIndentPrefix(depth + 1) + "</group>\n"); output.write(_getIndentPrefix(depth) + "</configure>\n"); }