int linkedObjectsCount = linkedObjects.size();
Iterator links = new LinkedList(_linkSet).iterator();
while (links.hasNext()) {
Link link = (Link) links.next();
// If this link matches a link in the linkedObjects list,
// then we remove that link from that list, since we don't
// have to manufacture that link.
Object tail = link.getTail();
Object tailObj = getSemanticObject(tail);
Object head = link.getHead();
Object headObj = getSemanticObject(head);
if ((tailObj != relation) && (headObj != relation)
&& (link.getRelation() != relation)) {
// The link does not involve this relation. Skip it.
// NOTE: Used to skip it if the relation field of the link
// didn't match this relation. But we need to ignore
// that field for links between relations, since that
// field will be arbitrarily one of the relations,
// and we'll end up creating two links where there
// should be one.
// EAL 6/26/05
continue;
}
if ((tailObj != null) && linkedObjects.contains(tailObj)) {
// The tail is an object in the list.
linkedObjects.remove(tailObj);
} else if (tailObj != relation) {
// Unless the tail object is this relation, the link
// must be spurious. Remove the link.
link.setHead(null);
link.setTail(null);
_linkSet.remove(link);
}
if ((headObj != null) && linkedObjects.contains(headObj)) {
// The head is an object in the list.
linkedObjects.remove(headObj);
} else if (headObj != relation) {
// Unless the head object is this relation, the link
// must be spurious. Remove the link.
link.setHead(null);
link.setTail(null);
_linkSet.remove(link);
}
}
// Count the remaining linked objects, which are those
// for which there is no Link object.
int unlinkedPortCount = linkedObjects.size();
// If there are no links left to create, then just return.
if (unlinkedPortCount == 0) {
return;
}
// Get the Root vertex. This is where we will manufacture links.
// The root vertex is the one with no linked vertices.
Vertex rootVertex = null;
Iterator vertexes = relation.attributeList(Vertex.class).iterator();
while (vertexes.hasNext()) {
Vertex v = (Vertex) vertexes.next();
if (v.getLinkedVertex() == null) {
rootVertex = v;
}
}
// If there are no verticies, and the relation has exactly
// two connections, neither of which has been made yet, then
// create a link without a vertex for the relation.
if ((rootVertex == null) && (linkedObjectsCount == 2)
&& (unlinkedPortCount == 2)
&& linkedObjects.get(0) instanceof Port
&& linkedObjects.get(1) instanceof Port) {
Port port1 = (Port) linkedObjects.get(0);
Port port2 = (Port) linkedObjects.get(1);
Object head = null;
Object tail = null;
if (port1.getContainer().equals(getRoot())) {
head = _getLocation(port1);
} else {
head = port1;
}
if (port2.getContainer().equals(getRoot())) {
tail = _getLocation(port2);
} else {
tail = port2;
}
Link link;
try {
link = new Link();
_linkSet.add(link);
} catch (Exception e) {
throw new InternalErrorException("Failed to create "
+ "new link, even though one does not "
+ "already exist:" + e.getMessage());
}
link.setRelation(relation);
link.setHead(head);
link.setTail(tail);
} else {
// A regular relation with a diamond.
// Create a vertex if one is not found.
if (rootVertex == null) {
try {
String name = relation.uniqueName("vertex");
rootVertex = new Vertex(relation, name);
// Have to manually handle propagation, since
// the MoML parser is not involved.
// FIXME: This could cause a name collision!
// (Unlikely though since auto naming will take
// into account subclasses).
rootVertex.propagateExistence();
} catch (Throwable throwable) {
throw new InternalErrorException(null, throwable,
"Failed to create "
+ "new vertex, even though one does not "
+ "already exist:" + throwable.getMessage());
}
}
// Create any required links for this relation.
Iterator linkedObjectsIterator = linkedObjects.iterator();
while (linkedObjectsIterator.hasNext()) {
Object portOrRelation = linkedObjectsIterator.next();
// Set the head to the port or relation. More precisely:
// If it is a port belonging to the composite, then
// set the head to a Location contained by the port.
// If is a port belonging to an actor, then set
// the head to the port.
// If it is a relation, then set the head to the
// root vertex of the relation.
Object head = null;
if (portOrRelation instanceof Port) {
Port port = (Port) portOrRelation;
if (port.getContainer().equals(getRoot())) {
head = _getLocation(port);
} else {
head = port;
}
} else {
// Get the Root vertex of the other relation.
// The root vertex is the one with no linked vertices.
vertexes = ((Relation) portOrRelation).attributeList(
Vertex.class).iterator();
while (vertexes.hasNext()) {
Vertex v = (Vertex) vertexes.next();
if (v.getLinkedVertex() == null) {
head = v;
}
}
}
Link link;
try {
link = new Link();
_linkSet.add(link);
} catch (Exception e) {
throw new InternalErrorException("Failed to create "
+ "new link, even though one does not "
+ "already exist:" + e.getMessage());
}
link.setRelation(relation);
link.setHead(head);
link.setTail(rootVertex);
}
}
}