// Parse port
ComponentPort port = _getPort(portName, context);
// Get relation if given
if (relationName != null) {
Relation tmpRelation = context.getRelation(relationName);
_checkForNull(tmpRelation, "No relation named \"" + relationName
+ "\" in " + context.getFullName());
ComponentRelation relation = (ComponentRelation) tmpRelation;
// Ensure that derived objects aren't changed.
if (_isLinkInClass(context, port, relation)) {
throw new IllegalActionException(port,
"Cannot unlink a port from a relation when both"
+ " are part of the class definition.");
}
// Handle the undoable aspect.
// Generate a link in the undo only if one or the other relation is
// not derived. If they are both derived, then the link belongs to
// the class definition and should not be recreated in undo.
if (_undoEnabled
&& (port.getDerivedLevel() == Integer.MAX_VALUE || relation
.getDerivedLevel() == Integer.MAX_VALUE)) {
// Get the relation at the given index
List linkedRelations = port.linkedRelationList();
int index = linkedRelations.indexOf(tmpRelation);
if (index != -1) {
// Linked on the outside...
_undoContext.appendUndoMoML("<link port=\"" + portName
+ "\" insertAt=\"" + index + "\" relation=\""
+ relationName + "\" />\n");
} else {
List insideLinkedRelations = port.insideRelationList();
index = insideLinkedRelations.indexOf(tmpRelation);
// Linked on the inside.
_undoContext.appendUndoMoML("<link port=\"" + portName
+ "\" insertInsideAt=\"" + index + "\" relation=\""
+ relationName + "\" />\n");
}
}
// Propagate. Get the derived list for the relation,
// then use its container as the context in which to
// find the port.
Iterator derivedObjects = relation.getDerivedList().iterator();
while (derivedObjects.hasNext()) {
ComponentRelation derivedRelation = (ComponentRelation) derivedObjects
.next();
CompositeEntity derivedContext = (CompositeEntity) derivedRelation
.getContainer();
ComponentPort derivedPort = _getPort(portName, derivedContext);
derivedPort.unlink(derivedRelation);
}
port.unlink(relation);
} else if (indexSpec != null) {
// index is given.
int index = Integer.parseInt(indexSpec);
// Ensure that derived objects aren't changed.
// Unfortunately, getting the relation is fairly
// expensive.
List relationList = port.linkedRelationList();
if (relationList.size() <= index) {
throw new IllegalActionException(port, "Cannot unlink index "
+ indexSpec + ", because there is no such link.");
}
Relation relation = (Relation) relationList.get(index);
if (_isLinkInClass(context, port, relation)) {
throw new IllegalActionException(port,
"Cannot unlink a port from a relation when both"
+ " are part of the class definition.");
}
// Handle the undoable aspect before doing the unlinking.
// Generate a link in the undo only if one or the other relation is
// not derived. If they are both derived, then the link belongs to
// the class definition and should not be recreated in undo.
if (_undoEnabled) {
// Get the relation at the given index.
List linkedRelations = port.linkedRelationList();
Relation r = (Relation) linkedRelations.get(index);
// Generate undo moml only if either the port is
// not derived or there is a relation and it is not derived.
if (port.getDerivedLevel() == Integer.MAX_VALUE
|| (r != null && r.getDerivedLevel() == Integer.MAX_VALUE)) {
// FIXME: need to worry about vertex?
_undoContext.appendUndoMoML("<link port=\"" + portName
+ "\" insertAt=\"" + indexSpec + "\" ");
// Only need to specify the relation if there was
// a relation at that index. Otherwise a null
// link is inserted
if (r != null) {
_undoContext.appendUndoMoML("relation=\""
+ r.getName(context) + "\" ");
}
_undoContext.appendUndoMoML(" />\n");
}
}
// Propagate.
Iterator derivedObjects = port.getDerivedList().iterator();
while (derivedObjects.hasNext()) {
ComponentPort derivedPort = (ComponentPort) derivedObjects
.next();
derivedPort.unlink(index);
}
port.unlink(index);
} else {
// insideIndex is given.
int index = Integer.parseInt(insideIndexSpec);
// Ensure that derived objects aren't changed.
// Unfortunately, getting the relation is fairly
// expensive.
List relationList = port.insideRelationList();
Relation relation = (Relation) relationList.get(index);
if (_isLinkInClass(context, port, relation)) {
throw new IllegalActionException(port,
"Cannot unlink a port from a relation when both"
+ " are part of the class definition.");
}
// Handle the undoable aspect before doing the unlinking
if (_undoEnabled) {
// Get the relation at the given index
List linkedRelations = port.insideRelationList();
Relation r = (Relation) linkedRelations.get(index);
// Generate undo moml only if either the port is
// not derived or there is a relation and it is not derived.
if (port.getDerivedLevel() == Integer.MAX_VALUE
|| (r != null && r.getDerivedLevel() == Integer.MAX_VALUE)) {
// FIXME: need to worry about vertex?
_undoContext.appendUndoMoML("<link port=\"" + portName
+ "\" insertInsideAt=\"" + index + "\" ");
// Only need to specify the relation if there was
// a relation at that index. Otherwise a null
// link is inserted
if (r != null) {
_undoContext.appendUndoMoML("relation=\""
+ r.getName(context) + "\" ");
}
_undoContext.appendUndoMoML(" />\n");
}
}