When complex layout knowledge has to be expressed, it is often required to use information about the current result. It is stored in a so-called document graph, a network of somehow connected design objects. In this section, we will briefly discuss how one can access the this graph to gather data which are of interest to solve a given task.
Gathering information from the graph means is the first place to select a certain design object, and then to select some of its specific data for further processing. The second step is easy to realize using the access methods for design object components. Therefor we will concentrate here on the question how to select objects from the graph.
To understand how this works, one should have a look on the basic structures the graph is build upon. Here we have atomic objects and container objects, which have been produced by constructor methods. Also important is the fact, that design-patterns produce always a container, which carries all the objects produced in the patterns context.
How do you have to apply this knowledge to access an object? In principle, you have to perform two actions. First, you have to figure out where you are in the graph. When the access should occur within a pattern's composition description, you are inside of the patterns container; when an event handling method should be modified, you are inside of an logical container which collects the methods results, similar to the pattern container.
Now you are able to start traversing the graph. Access the container using the helper method this(), and jump to its container or its neighbors using the provided graph access methods. Please remember during these actions, that the results may be undefined.
Often one is not interested in all objects of the graph - only a few, specific objects should be selected. Imagine that you want to count the number of list entries, in particular the results of a command called "listItem", inside a given container. Unfortunately, using here getNumChildren() may lead to problems even if you think that all children are of type "listItem", because the layout generator could have added further objects automatically which are not visible to you.
A solution would be to iterate all children of the container and to check them "by hand". But since such problems are very common, we decided to add a more comfortable object selection mechanism to DCL: access filters. The idea behind these filters is that before an access takes place, a user may specify a filter which describes more detailed, which objects she is interested in; then the access methods return the next object which meet the filter criteria.
To continue our example, let's define a filter which lets only objects of type "listItem" pass. Such a filter is just a regular method with the only specific property that it gets as first argument a design object and returns a Boolean value. Thus our filter method could look as follows.
boolean exampleFilter(designobj curDO) {
if ( getName(curDO)=="listItem" ) return true;
return false;
}
This simple method does all we need. Next we have to activate the filter before the access.
... setFilter(exampleFilter); math listItemCount = getNumChildren(this()); ...
The helper method setFilter activates the filter; from this point, the access to the result graph makes use of the filter. Thus getNumChildren will count only the objects we were interested in.
Some details remain to discuss here. First, you should note that the first argument of the filter method is generated automatically by the system and has therefor to be suppressed here. Further arguments may be specified as usual. Further, when a filter has been set it will remain active until it is explicitly turned off by resetFiter or the current processing scope is left, this means the patterns or event methods execution is completed.