Names of the nodes in Workcraft are used to identify the mathematical and visual nodes in the model. Every node in the model must have some name and normally every name is unique within its namespace. The root node of the mathematical model provides a namespace at the highest level. Inside the model, there may be other nodes (such as pages) that create their own namespaces.
A model keeps track of node names by means of reference managers. A default reference manager for the mathematical model is manages namespaces and maps every namespace in a model to a name manager. A name manager generates new names within a given namespace. Every name is a C-style identifier, it follows the regular expression pattern:
[_A-Za-z][_A-Za-z0-9]*. There may be exceptions from this rule, e.g STG model uses
/ to specify signal transitions and their instances.
The automatic naming in a name manager is ensured by mixing some prefix with a number. For instance, connections can be named
con2, etc. while nodes can be named
node2, etc. The rules for prefix can be specified when the reference manager is created.
Currently there is no namespace concept in the visual model (none of the visual group nodes creates a new namespace) and by default a simpler ID generator is used for names.
Some nodes introduce new namespaces – pages and groups are examples of such containers. For instance pages
p2 may both have nodes named
n1, because they are in different namespaces. Such objects can be referenced hierarchically while using
/ as the hierarchy separator (just like in the folder structure). For instance,
p2/n1 are absolute references to two different nodes in two different namespaces. The
/ at the beginning of reference is not necessary, the reference is assumed to be an absolute path.
A special naming rule is used to mark different instances when the name stays the same in STGs. Here
/ followed by a number is considered a part of a name, and not the beginning of a new hierarchy. For instance
p1/t+/3 would read as
p1 followed by
t+/3, because there are several
t+ transition instances, and they all refer to the different nodes in the model.
Some models need to be simplified (flattened) before they can be processed by other tools. For instance, an export into a .g file would not support hierarchical names. For this purpose names are transformed so that they look like C-style identifiers while replacing all
/ with the double underscore symbol
__. For instance, a signal name
p1/a would be converted to
Note that the instance numbers are not prefixed with
__. For instance, the transition
p1/a+/3 would convert to
p1__a+/3, which is a normal name for a .g file format.
The model names are stored and managed by the
ReferenceManager object both in visual and mathematical models. Mainly it checks whether a name is unique/correct within a given model, it can also automatically generate unique names for new nodes and connections added to the model. The default name manager in the visual models is DefaultNameManager. It works within a single namespace and produces simple numeric IDs as names. These numeric IDs are not seen by the user, they are used to identify nodes when the model is converted to XML representation and saved into a file.
RefrenceManager in the math model is
HierarchicalReferenceManager, it is using the dedicated
NameManager to check and assign new names. The
NameManager only works with the names that are C-style identifiers, which cannot start with a number. For convenience, this manager creates new names based on a given prefix function
Func<Node,String>. For instance, the new places in a Petri net would be named
p2, etc. and the new transitions would be
The hierarchical reference manager is associated with multiple
NameManager for each
NamespaceProvider (such as
PageNode). It creates a new
NameManager automatically when it is required. The reference manager can be used to name some component, the
Model itself, however, is more commonly used for this task, it forwards these calls to the associate reference manager. The main methods of main interest are:
getNodeByReference(String):Node– return a node identified by a full path name, e.g.,
getNodeReference(Node):String– return a full path reference to a given node.
getName(Node)– return the name of the node only, without the path leading to it, e.g.
setName(Node, String):void– assign a new name to the node.
NamespaceHelper class that contains a number of useful static functions working with hierarchical name strings.