In effect, every document is given a custom browser. The set of behaviors that are active is listed in a hub, which is an XML document pointing to Java classes with supporting attributes and data. Hubs can be compared to style sheets in that style sheets describe how to display a document, while hubs describe how one may interact with it. However, hubs go much farther and control the construction of the entire application.
When the system loads a document, it first load the relevant hub from
Multivalent.jar's hub,
then all hubs from all JARs in the same directory as Multivalent.jar
in undefined order, and then a user's hub, if any.
JARs store their hubs in a sys/hub directory,
and the users hub is in his home directory at the path
System.getProperty("user.dir")/.Multivalent/hub
.
For instance, when loading HTML-specific behaviors, the system
loads HTML.hub from Multivalent.jar,
then any sys/hub/HTML.hub from JARs,
then System.getProperty("user.dir")/.Multivalent/hub/HTML.hub
.
By editing the applicable hub, behaviors can be added, removed, rearranged (to affect their order in the user interface), replaced, and specialized (by editing attributes). For example, one could swap the Emacs editing key bindings for the Microsoft Windows ones, and enjoy Emacs editing commands in everything from URL type-ins to editable notes to text fields in HTML forms.
Hubs can hold both behaviors and content.
Behaviors are labelled with the attribute Behavior
giving the name of the implementing Java class.
Other attributes and the XML content subtree of the a behavior's
listing in a hub are passed to the Java class via
the class's restore() method.
Interpretation of these subtrees is at the exclusive control of
the controlling behavior,
but often the controlling behavior recurses to instantiate nested behaviors.
Content not specific to a single behavior can be included in a hub
as XML subtrees at the same level at top-level behaviors.
This content, or auxialiary data, is available with the
multivalent.Layer
's getAux()
method.
Hubs can import other hubs. For example, document formats
often have much in common as a fixed-format type with pages or as a
flowed-format type that is a long scroll, and hubs for these document
formats share the common behaviors by referring to the Fixed
or Flowed hub. Other XML files can be included with the
standard XML xinclude:include mechanism,
with xinclude:include as the tag and the href attribute
giving the relative path. Relative paths are relative to the current
JAR; use systemresource as the protocol to reach into
Multivalent.jar.
More often all hubs by some name in whatever JAR are imported.
In this case, use the processing target import,
as in <?import href='Flowed' ?>
.
Just as there are layers of content, there are layers of behaviors.
At runtime a hub is converted into a layer
(Java class: multivalent.Layer
)
consisting of a list of instantiated behaviors and
a list of non-behavior data subtrees.
Attributes in the hub become attributes in the runtime behaviors
and similarly with the data subtrees.
Thus layers can be converted between XML file and
runtime data structure representations
with no loss of data.
<?xml version='1.0' ?> <System title='System default behaviors'> <?import href='Core' ?> <?import href='Net' ?> <MenuBar behavior='multivalent.std.ui.Menubar' titles='File|Edit|Go|Lens|Style|Anno|CopyEd|View|Help' /> <MenuItem Behavior='SemanticUI' SCRIPT='event newBrowserInstance' title='New Browser' parent='File' category='File' TYPE='Button' /> <Events Behavior='multivalent.std.ui.BindingsEmacs' /> <MenuItem Behavior='SemanticUI' SCRIPT='event EXIT' title='Quit' parent='File' category='Quit' TYPE='Button' /> </System> |
At left is an excerpt from a hub. The name of the layer is given by the root of the XML parse tree, System which is normalized to all-lowercase system. Here two other hubs are imported, Core and Net, which are taken from all files named Core.hub and Net.hub from Multivalent.jar, all external JARs, and from the users home directory.
Behaviors are
identified as such by an attribute named behavior; in the absence of
such a tag, that subtree is added to the list of data subtrees.
The name of the behavior can be given as a fully qualified classnames,
such as multivalent.std.ui.Menubar, or as
a generic name like Hyperlink, in which
case it is mapped to a full classname via a table
established by remap
commands in Preferences.txt;
the map enables
all instances of some popular behavior type to be conveniently updated
to a new, more powerful implementation of that same class of functionality.
Other examples: Full hubs System hub, OCR genre hub, and per-document hub with annotations.
Current hubs included this directory of hubs. Many are tied to a specific document format, including ASCII, PDF, and ManualPage. Some are shared by document formats, including Fixed and Flowed. Many are categories of system services, including Net, Go, and Tool. System is the first hub loaded and establishes the basic behaviors always present.
Since many documents share functionality and other documents have no associated hub, the following types hubs are cascaded to produce the full set of behaviors active on a given document.
The separation of document function in hubs and document data in existing concrete formats gives a number of advantages.