An important responsibility of the GraphAPI involves the assignment of unique
identifiers to Graph and VisualGraph objects. These identifiers should allow for the unique
discovery and retrieval of graph objects within a particular graph context. Furthermore,
the identifiers of GraphObject instances and associated VisualGraphObject instances should be
equal to each other and thus provide an implicit mapping of VisualNode objects to their
counterparts in the model.
The Graph and VisualGraph objects support two different kinds of identifiers. Both of them are
assigned internally by the GraphAPI. Therefore it is not possible to set them manually. This
was done on purpose so as to eliminate a potential source of errors.
The methods provided by a GraphObject and a VisualGraphObject to access these identifiers have
the same names and signature so that they are easy to remember for both kinds of objects.
The one identifier supported by Graph and VisualGraph objects is returned by the method shown
below. Its responsibility is to let client code identity a GraphObject within a single
GraphObjectContainer or VisualGraphObjectContainer and also to indicate if the GraphObject or VisualGraphObject has been added to
a corresponding container or not. These characteristics are explained in detail later on.
The text refers to the identifier named 'container id'.
long getID()
The second identifier supported by Graph and VisualGraph objects is returned by the method:
long getUniqueID()
The responsibility of this method is to provide an identifier that is unique within an entire
hierarchy of GraphObjectContainer and VisualGraphObjectContainer objects and also to let you identify a GraphObject or
VisualGraphObject immediately after its creation.
The succeeding text refers to this identifier by the name 'global id'.
The two different identifier types have unique and shared characteristics. The list below gives an overview of these characteristics.
Both 'container id' and 'global id' are assigned internally by the Tensegrity Graph Framework. Therefore, it is not possible to set them manually. This was done on purpose in order to eliminate a potential source of errors.
Each VisualGraphObject is associated with a model object that has the same 'container id' and the
same 'global id'.
This means that identifiers are not unique in the combined scopes of the
model and view.
This characteristic allows you to find model objects by using one of the convenient
lookup methods defined in the Graph interface and it eliminates the need for
additional mapping data structures.
Identifiers are unique within their own scope. The rules for identifier scopes are as follows:
The 'container id' is unique within the scope of a single GraphObjectContainer object.
In other words, the same 'container id' is not assigned to more than one
GraphObject inside the same GraphObjectContainer object but the same 'container id' can be assigned
to two different GraphObject instances that reside in two different GraphObjectContainer
objects.
The 'global id' is unique within the scope of an entire hierarchy of GraphObjectContainer objects.
In other words, the same 'global id' is not assigned to more than one
GraphObject inside the same GraphObjectContainer object and the same 'global id' is not assigned
to two different GraphObject instances that reside in two different GraphObjectContainer
objects.
Consequently,
different objects of type Node and Edge residing in the same GraphObjectContainer have a
different 'container id' and a different 'global id'.
different objects of type Node and Edge residing in a different GraphObjectContainer may
have the same 'container id' but a different 'global id'.
an object of type Node or Edge associated with more than one view
counterparts residing in two different VisualGraphObjectContainer hierarchies have the same 'container id'
and the same 'global id'.
Upon creation of a Node or Edge, the 'container id' is initially set to -1 and therefore
invalid. The 'container id' becomes valid when the Node or Edge is subsequently added to a
Graph.
This allows you to determine if a Node or an Edge has already been assigned
to a Graph. Please remember that a Node or an Edge can be managed by just one
Graph at a given time.
When a Node or Edge is removed from a GraphObjectContainer its 'container id' becomes
invalid once again by being reset to -1.
A 'container id' that has been invalidated in this way is
not reused.
In the event a VisualNode or VisualEdge is removed from its VisualGraphObjectContainer but
the model object still resides in its GraphObjectContainer, the VisualNode or VisualEdge
still returns the 'container id' assigned to the Node or Edge.
Contrary to the 'container id', a newly-created Node and Edge is immediately
assigned a valid 'global id', which will not be changed added to or later
removed from a GraphObjectContainer. This is also true for the view counterparts
VisualNode and VisualEdge, because they share the same 'global id'
GraphObjectContainer and VisualGraphObjectContainer objects can be “deep-copied” to create
independent copies of the original data. Changes to any of these copied
objects are not automatically propogated back to the original objects,
since all objects are recursively deep-copied.
While the scoping rules only restrict the uniqueness of the 'container id'
within a single GraphObjectContainer, it is beneficial to assign the same 'container id'
to the deeply copied objects as well. This allows one to easily map
changes to a copy back to the source object.
On the other hand, the 'global id' is restricted to be unique within the
complete hierarchy of GraphObjectContainer objects, so it has to be different for all
deeply copied objects.
Finally, you should not rely on any kind of ordering in the identifier sequence. Even though assigned identifiers are likely to come from an incremental sequence, this may change in future versions. Therefore, the identifiers are not meant to be used to order nodes.
© 2004, 2005 Tensegrity Software GmbH