Skip to content

Programming Model: Data Addressing

ChrisRus edited this page Nov 9, 2013 · 27 revisions

See also: ONMjs.Address (address class reference)
See also: ONMjs.AddressToken (address token class reference)
See also: ONMjs.address.* (address helper function reference)

#PLEASE IGNORE THIS PAGE UNTIL THIS NOTICE IS REMOVED I started writing this page in September and realized that the ONMjs addressing API was simply to complicated to explain. I dropped off and completely refactored the library to hide all the nasty implementation details.

ONMjs.Address instances are now constructed solely with factory methods provided by the core ONMjs.Model and ONMjs.Namespace classes. These documents are up-to-date and should be used for reference until I have time to re-write this section.

Getting Started

ONMjs addresses are most easily understood by analogy:

Consider that you're an architect charged with creating the design for a new apartment complex comprising many buildings that are all identical save for the fact that they're not to be built in exactly the same location. Within each building are a number of different apartment configurations: some are large, others small. Some have a fireplace and walk-in closets, while others have fewer amenities.

In drawing up the design plans to be given to the construction crew, it's necessary to specify directions for each apartment. However, you don't need to duplicate this effort for each building to be constructed because all the buildings are identical. So you draw up a single generic design plan that omits the building numbers and address each apartment using a simple scheme that identifies each by its floor and unit number.

Relating this back to ONMjs:

An ONMjs data model is like your generic design plan for an apartment building.

An ONMjs object store is like a specific apartment building.

An ONMjs address is like the floor/unit number of an apartment.

And finally, run-time data is like the actual contents of a specific apartment in a specific apartment building once its built and someone has moved in.

Address Space Concept

The term "address space" is a just a fancy way of talking about the set of all possible addresses. In our apartment building analogy, the "address space" is the set containing all apartment units within a specific building as specified in the building's design plan. Similarly, an ONMjs address space is the set of all possible namespace addresses specified by your declared data model.

The salient point here is that an "address space" is something that's defined at design-time. Specifically, an ONMjs address space is defined when you declare your data model. We'll use this term subsequently as shorthand for discussing the set of legal addresses.

Note that unlike the "address space" of an apartment building, ONMjs address spaces may be, and typically are, infinite sets due to the common use extension point/component namespaces, and less frequently recursively-declared namespace hierarchies.

Address Paths, Path ID's, and Keys

Address Paths

Each namespace that you declare in your data model declaration object is given two identifiers when it is parsed by the constructor of class ONMjs.Model. Specifically, each namespace declaration is assigned a path and and path ID.

The path identifier is a dot-delimited string formed by concatenating the jsonTag values specified for each parent namespace declaration with the jsonTag value specified for a given namespace. For example:

    addressBook.contacts.contact.name

... is the path of the 'name' sub-namespace in our earlier address book example.

Paths are human-readable and easily understood. However, they are not an efficient way to represent this information internally. For this, ONMjs leverages path ID's.

Address Path ID's

Path ID's are non-negative integers assigned to each namespace declared in your data model. Path ID zero (0) is always assigned to the root namespace, and increasing values are assigned to each namespace as your data model declaration is parsed by the ONMjs.Model's constructor at run-time.

Precisely how path ID's are assigned is an implementation detail of the ONMjs.Model class. Path ID's are intended to be opaque handles used as an alias for a path. There's no other meaningful semantic information that can be safely determined by, for example, comparing path ID's. Do not take a dependency on any specific path ID numbering scheme. If you need to figure out what a path ID represents, or its relationship to some other path ID, use the methods provided by ONMjs.Model that are designed for this purpose:

  • ONMjs.Model.getPathIdFromPath
  • ONMjs.Model.getPathFromPathId
  • ONMjs.Model.getNamespaceDescriptorFromPathId

Keys

A key is a string assigned to a new instance of a data component created by your application logic when it calls the ONMjs.Store.createComponent method. As explained in the Data Modelling article (specifically refer to semanticBindings.getUniqueKey ONMjs.Store uses the key string to identify the new component object in a dictionary.

Recalling the earlier address book example, the path addressBook.contacts.contact.name indicates a subspace of the address book model's address space. However, it does not indicate a specific 'contact' instance because it does not contain any representation of the key that would be required to find a specific 'contact' within the 'contacts' (plural) dictionary.

All of this will make sense once we explore the ONMjs.AddressToken class below.

ONMjs.Address Class

Working with ONMjs.Address class instances is part and parcel to using ONMjs. There's essentially nothing you can do with the ONMjs library at run-time that does not require that you interact with ONMjs.Address class instances.

In the abstract, an instance of ONMjs.Address represents a specific namespace in the address space defined by your data model. Instances of ONMjs.Address are used at run-time gain access to meta-data contained in your data model, and to create, remove, and access specific data namespaces within an ONMjs.Store.

Internally, ONMjs.Address represents an address using an ordered array of ONMjs.AddressToken class instances (introduced below). Briefly, a single ONMjs.AddressToken specifies the information required by ONMjs.Store to resolve a specific data namespace in a specific data component. And, an ordered sequence of tokens specifies the information required by ONMjs.Store to resolve through a hierarchy of data components to a specific namespace. This can get rather tricky given that ONMjs supports nested collections, and recursive object structures.

Luckily, the ONMjs library shoulders most of the heavy burden by creating addresses behind the scenes and passing them by reference to your application logic. For example, ONMjs passes fully initialized addresses to your signal handler and visitor callback functions.

String Representation of Addresses

Human-Readable String

Uniform Resource Identifiers (URI)

Scope of Uniqueness

Uniform Resource Names (URN)

Uniform Resource Locators (URL)


Copyright (C) 2013 Christopher D. Russell