4.2 Elements of a Solution
4.2.3 Common Hierarchical Data Modeling Facility
In order for an infrastructure to provide collaborative capabilities to an applica- tion, it must have access to either the state of the application’s model and/or view components, or to the outputs emitted by these components. For reasons that will become clear in Section 4.2.4, Concur takes the state approach.
There are two main approaches to giving the infrastructure access to the applica- tion state. Either the infrastructure can be provided direct access to the application state as it is naturally represented by the application, or the application can represent
(some of) its state in an infrastructure-determined form. The first approach requires less work on the part of the application developer, while the second makes the in- frastructure less dependent on particular application technologies (e.g., programming languages and environments).
Concur takes the latter approach, for a number of reasons:
• Technology independence. Standard data representation languages tend to outlive programming languages and runtime infrastructures. A standard data representation language helps to isolate the collaborative infrastructure from these technology changes.2
• Change notifications. Using a common data representation enables Con- cur to ensure that change notifications are supported by the data structures. This relieves the application from having to code view registrations and change notification events. The common data representation thus encapsulates the model/view protocol for the application, so that the model need know noth- ing about views. This is especially valuable when using the push MVC design pattern.
• Published vs. unpublished data. Requiring the application to separately represent model data that might contribute to a view (published data) supports an important data hiding capability at the component boundary, similar to public/private distinctions at the object boundary. This avoids both having to make private data public so that it can be accessed by the infrastructure, and 2The Concur proof of concept actually does not use a standard data representation language. The Document Object Model[Mar02] (DOM) was originally used, but it was found to have certain deficiencies with respect to the representation of hierarchical data structures. For example, repar- enting operations are mapped to remove and insert operations, which are awkward and inefficient for an observer/view to re-map back to reparenting operations. In the interest of expediency, I chose a hierarchal data representation API that was convenient for the chosen programming environment.
using separate mechanisms to avoid exposing public data that should not be exposed outside the component (unpublished data).
• Distribution. Concur distributes model state and view code, which generates view state based on model state. View code must run in a restricted container. If the model and view state were represented using the application’s native representation, infrastructure for maintaining that representation would have to be distributed as well, increasing container requirements.
• Testing, Debugging, and Scripting. A common data modeling language supports testing, debugging, and scripting in a manner that is independent of application technologies and less dependent on particular applications.
A common data representation language must support arbitrary application data structures. This implies that the language must support arbitrary graphs. On the other hand, hierarchical data structures are extremely common in applications, and it is sometimes helpful to the infrastructure if it can assume a hierarchical view of the data. For example, if the infrastructure needs to identify a portion of an arbitrary graph, it can only do so by maintaining a set of nodes and links defining that portion, or a computational rule defining that set. On the other hand, if it can assume the graph is a hierarchy (or directed acyclic graph (DAG)), it can often identify a sub- portion of the graph by simply specifying one (root) node. (In Figure 4.3, Chapter 1 can be used to refer to all the shaded nodes.) Like file systems, Concur uses a representation language that assumes a basic hierarchical structure with a special link type for specifying non-hierarchical graph structures (Figure 4.4) as an overlay on the hierarchy.
In Concur, a common hierarchical data representation is used to represent both model (view function inputs) and UI state (view function outputs). Low-level user
Figure 4.3: Hierarchical Data Structure
events such as keyboard and mouse events must be able to be applied to the declara- tive UI data structure representing the UI. Concur implements an event mechanism similar to those used by the X Window System[SGR92] and the Document Object Model (DOM)[Mar02]. Events can be applied to any node in the hierarchy, and in- terest in these events can be registered (by a controller) with respect to any node. Events bubble from the node to which they are applied up to the root, notifying ob- servers along the way (Figure 4.5). The same mechanism is also used for registering and notifying view functions of changes in its model or perspective inputs. Concur
Figure 4.5: Bubbling of Events or Changes
also requires that the set of (DAG) inputs to a continuously evaluated function always remain in the domain of that function. Concur’s data representation therefore imple-
ments transactional modifications to the data structure, enabling multiple changes to be made before event notifications are released.