* @return The deleted object, or null if none is found.
* @exception Exception If there is no such relation or if the relation
* is defined in the class definition.
*/
private Relation _deleteRelation(String relationName) throws Exception {
ComponentRelation toDelete = _searchForRelation(relationName);
if (toDelete == null) {
return null;
}
if (toDelete.getDerivedLevel() < Integer.MAX_VALUE) {
throw new IllegalActionException(toDelete,
"Cannot delete. This relation is part of the class definition.");
}
// Propagate and generate undo MoML.
// NOTE: not enough to simply record the MoML of the deleted relation
// as any links connected to it will also be deleted
// and derived relations will have to have similar undo MoML
// so that connections get remade.
// Construct the undo MoML as we go to ensure: (1) that
// the undo occurs in the opposite order of all deletions, and
// (2) that if a failure to delete occurs at any point, then
// the current undo only represents as far as the failure got.
StringBuffer undoMoML = new StringBuffer();
// Propagate. The name might be absolute and have
// nothing to do with the current context. So
// we look for its derived objects, not the context's derived objects.
// We have to do this before actually deleting it,
// which also has the side effect of triggering errors
// before the deletion.
// Note that deletion and undo need to occur in the opposite
// order.
try {
Iterator derivedObjects = toDelete.getDerivedList().iterator();
// NOTE: Deletion needs to occur in the reverse order from
// what appears in the derived objects list. So first we construct
// a reverse order list.
List reverse = new LinkedList();
while (derivedObjects.hasNext()) {
reverse.add(0, derivedObjects.next());
}
derivedObjects = reverse.iterator();
while (derivedObjects.hasNext()) {
ComponentRelation derived = (ComponentRelation) derivedObjects
.next();
// Since the Relation can't be a
// class itself (currently), it has derived objects
// only if its container has derived objects.
// Thus, we do not need to create undo MoML
// for the derived objects. The undo MoML for
// the principal relation will propagate when
// executed.
// FIXME: The above is not true, since a propagated
// relation may contain parameter values that are
// not in the original. Need to carefully choose
// the level at which the exportMoML is done.
derived.setContainer(null);
}
// Have to get this _before_ deleting.
String toUndo = _getUndoForDeleteRelation(toDelete);
toDelete.setContainer(null);