OpenAjax Hub 2.0 Specification Libraries

From MemberWiki

Jump to: navigation, search

NOTE: This wiki page holds part of the OpenAjax Hub 2.0 Specification.


<--previous       contents--^       next-->


Contents

2 Library Management

Introduction

This chapter contains rules, guidelines and APIs concerning the use of Ajax libraries within a Web page, including the use of the OpenAjax Hub within a Web page. The sections below describe:

  • Rules and guidelines for including the OpenAjax Hub JavaScript library within a Web page
  • APIs for registering libraries, unregistering libraries, and querying about previously registered libraries
  • Conformance requirements on Ajax libraries that help prevent JavaScript name collisions

Using the OpenAjax Hub within a Web page

Overview of how the OpenAjax Hub typically is used within an application

The following are two typical scenarios by which the OpenAjax Hub is used within an Ajax application:

Scenario 1: Application loads a standalone version of OpenAjax.js before other Ajax libraries

In this scenario, the application's HTML file loads the Unmanaged Hub release configuration of the OpenAjax Hub (in the example below, OpenAjaxUnmanagedHub.js) by including a <script> tag that references this file before other <script> tags for other Ajax libraries. For example:

[01]<html...>
[02]  <head>
[03]    <script src="scripts/openajax/hub20/unmanagedhub/OpenAjaxUnmanagedHub.js" type="text/javascript"></script>
[04]    <script src="scripts/foolib1.5/foo.js" type="text/javascript"></script>
[05]    <script src="scripts/barlib0.7/bar.js" type="text/javascript"></script>
[06]    <script src="scripts/myapp.js" type="text/javascript"></script>
[07]  </head>
[08]  <body>
[09]    <!-- Application-specific HTML markup goes here -->
[10]  </body>
[11]</html>

The above example assumes that the application uses the "Unmanaged Hub" feature from the OpenAjax Hub (e.g., to allow publish/subscribe among trusted components within a single browser frame) along with two OpenAjax Conformant Ajax libraries (version 1.5 of the "foo" Ajax library and version 0.7 of the "bar" Ajax library), all of which have been installed on the same Web server where the application is installed. Because "foo" library and "bar" library are OpenAjax Conformant, these libraries:

  • Register themselves with the Hub, providing metadata for the library such as version number
  • Subscribe as appropriate to events managed by the Hub's publish/subscribe event manager

In the example above:

  • line [03]: the application loads the JavaScript source code for the OpenAjax Hub
  • lines [04] and [05]: the application loads the JavaScript source code for two OpenAjax Conformant Ajax libraries (foo and bar)
  • line [06]: the application loads its own application-specific JavaScript.

Scenario 2: Application loads an Ajax library that include the Hub within it

In this scenario, the application is using an Ajax runtime library that includes an implementation of the OpenAjax Hub within its distribution. For example:

[01]<html...>
[02]  <head>
[03]    <script src="scripts/foolib1.5/fooWithOpenAjaxHub.js" language="JavaScript" type="text/javascript"></script>
[04]    <script src="scripts/barlib0.7/bar.js" language="JavaScript" type="text/javascript"></script>
[05]    <script src="scripts/myapp.js" language="JavaScript" type="text/javascript"></script>
[06]  </head>
[07]  <body>
[08]    <!-- Application-specific HTML markup goes here -->
[09]  </body>
[10]</html>

Key things to note about this scenario:

  1. Make sure that the Ajax library that includes the OpenAjax Hub is loaded before the other Ajax libraries
  2. Make sure that the implementation of the OpenAjax Hub that is included first has all of the features needed by the other Ajax libraries used within the application. (For example, if "foo 1.5" includes version 2.0 of the OpenAjax Hub, but "bar 0.7" requires version 2.2, then the above source code may not work because the version of the Hub embedded within "foo 1.5" may not include the features needed by "bar 0.7".)

Overview of how libraries typically interact with the OpenAjax Hub

A library that is OpenAjax Conformant:

  • MAY implement the OpenAjax Hub feature set within the library itself (either by including the reference implementation from http://sourceforge.net/projects/openajaxallianc within the library or by including a different implementation of the Hub) or
  • check to see if the Hub has been previously loaded within the given application by an earlier <script> element, and if so, use that version of the Hub

If a library does not include its own version of the Hub, then it might include logic similar to the following: (Note: For conceptual simplicity, the logic below does not check return values or handle exceptions.)

if (typeof OpenAjax != "undefined") {
  // The OpenAjax object exists, so use it.
  OpenAjax.hub.registerLibrary(prefix,...); // Register library's prefix, namespaceURI, etc.
  OpenAjax.hub.subscribe(prefix,...);       // Register callback for when particular events occur 
} else {
  // The OpenAjax object does not exist, so don't use the Hub; instead,
  // perhaps the library uses its own publish/subscribe system.
}

Loading Requirements on the OpenAjax Hub

There are common Ajax application scenarios where a given Ajax application loads multiple Ajax libraries. In these scenarios, it is possible that the underlying JavaScript logic might attempt to load multiple instances of the Hub.

Only first version of the Hub must be loaded

In all cases, once one version of the OpenAjax Hub has been loaded, all other instances of the Hub MUST NOT initialize themselves nor alter the version of the Hub that is already present. Thus, the version of the Hub that is loaded by the earliest <script> element MUST be the one used by all Ajax libraries within the application.

Here is an example that indicates how an implementation of the Hub might prevent itself from initializing itself when a version of the Hub is already present:

// Only create window.OpenAjax if it does not already exist
if (typeof window.OpenAjax == "undefined") {
  OpenAjax = {
    implementer: "http://openajax.org",
    implVersion: "2.0",
    specVersion: "2.0",
    ...etc...
}

What if different libraries include different versions of the Hub?

As mentioned earlier, when a given Ajax application loads multiple Ajax libraries, it is possible that the underlying JavaScript logic might attempt to load multiple instances of the Hub. Furthermore, it is possible that the first library to load the Hub might use an earlier version of the Hub than libraries that are loaded later. To illustrate this scenario, suppose the application uses two Ajax libraries, foolib and barlib, with foolib loaded first, and suppose that foolib includes OpenAjax Hub version 1.0 and barlib includes OpenAjax Hub version 1.1. Since the first instance of the Hub that is loaded prevents other instances from loading, the result is that barlib may not work properly because it requires version 1.1, whereas version 1.0 instead will have been loaded.

One way to address this situation is for the application developer to explicitly load an implementation of the OpenAjax Hub before either foolib or barlib are loaded by including a <script> element that loads the necessary version of the Hub before foolib is loaded. As a result, the lower-version implementation of the Hub within foolib will not load itself.

Library Management APIs

The OpenAjax Hub provides the following APIs for registering libraries, unregistering libraries, and querying about previously registered libraries:

  • OpenAjax.hub.registerLibrary()
  • OpenAjax.hub.unregisterLibrary()

The APIs defined below use JSDoc commenting conventions to describe various details about a particular API, such as a method's parameters, return values and exceptions. For details about the subset of JSDoc used in this specification, refer to the write-up on JSDoc Conventions in the Introduction chapter.

APIs

OpenAjax.hub.registerLibrary(prefix, namespaceURI, version, extraData)

/**
 * Registers an Ajax library with the OpenAjax Hub.
 *
 * @param {String} prefix
 *     A unique string that identifies the library being registered. 
 * @param {String} namespaceURI
 *     A namespace URI string suitable for use with xmlns attribute, 
 *     such as xmlns:foo="http://example.com"
 * @param {String} version
 *     Version number.
 * @param {*} [extraData]
 *     An optional arbitrary Object holding extra information about the library. 
 */
OpenAjax.hub.registerLibrary(prefix, namespaceURI, version, extraData) {}

The prefix parameter MUST be compatible with the prefix value within an xmlns attribute per the W3C's Namespaces in XML Recommendation, such as the value foo in the following namespace declaration: xmlns:foo="http://example.com".

The namespaceURI MUST be compatible with the W3C's Namespaces in XML Recommendation.

The version parameter MUST be of the form of #[.#]*, such as "1", "1.1", "2.0" or "2.20.2", followed by an optional arbitrary string (e.g., "2.20.2Beta" or "1.1 Build 543"). The leading numeric part of the version string allows script to determine which version of a particular Ajax library has been loaded, using equal/greater-than/less-than comparisons. The optional trailing arbitrary string must begin with a character other than a numeric character (i.e., 0-9) or period character. The optional trailing string must be stripped before invoking version comparison logic.

The first (non-negative) integer token of the leading numeric part SHOULD reflect the library's major release number. If present, the second (non-negative) integer token of the leading numeric part SHOULD reflect the minor release number. If present, the third (non-negative) integer token of the leading numeric part SHOULD reflect the (next level down) minor release ("minor-minor" release number). It is acceptable to include other numeric values (4th, 5th, etc.) although probably not useful. To illustrate, with the value "1.20.3 beta 7", the major release is "1", the minor release is "20", and the minor-minor release is "3".

In version comparison logic, first extract the leading numeric part of the version string; then tokenize the numeric part. Now do a numeric comparison of major version tokens. If equal, then compare minor versions. If equal, then compare minor-minor versions. Etc. Missing tokens are equivalent to zero.

Subsequent releases of a given toolkit MUST have version numbers that are greater than or equal to previous releases. Although not required, it is recommended that each release have a higher version number than previous releases. One technique to accomplish this is to use the build number for the 3rd token (the "minor-minor" release number), such as "1.3.2065", where the major version is "1", the minor version is "3", and the build number is "2065".

This function has no return value.

It is not an error to re-register a library. If OpenAjax.hub.registerLibrary is called on a library that is already registered, then the new registration MUST replace the previous registration.

Immediately after the library has been registered (or re-registered), the Hub implementation MUST invoke OpenAjax.hub.publish(), where the event name is org.openajax.hub.registerLibrary and publisherData is a reference to the OpenAjax.hub.libraries[prefix] object for the given library.

OpenAjax.hub.unregisterLibrary(prefix)

/**
 * Unregisters an Ajax library with the OpenAjax Hub.
 *
 * @param {String} prefix
 *     A unique string that identifies the library being registered. 
 */
OpenAjax.hub.unregisterLibrary(prefix) {}

This function has no return value.

It is not an error to unregister a library that is not currently registered. If OpenAjax.hub.unregisterLibrary is called on a library which is not currently registered, then the unregister request MUST result in no action and MUST NOT generate an exception.

Immediately before the Hub implementation attempts to unregister the given library, even if the specified library is not currently registered, the Hub implementation MUST invoke OpenAjax.hub.publish(), where the event name is org.openajax.hub.unregisterLibrary and publisherData is a reference to the OpenAjax.hub.libraries[prefix] object for the given library (or null if the given library is not currently registered).

Public variables

OpenAjax.hub.libraries

This variable holds the list of libraries that have registered themselves with the OpenAjax Hub.

In order to achieve best execution time performance and smallest download size, OpenAjax Hub implementations MAY use OpenAjax.hub.libraries to store its own internal information about registered libraries. Because of this, OpenAjax-conformant libraries MUST treat OpenAjax.hub.libraries as a read-only variable and thus MUST NOT make any changes to this object or its contents.

OpenAjax.hub.libraries is a JavaScript associative array, where OpenAjax.hub.libraries contains a <prefix> property for each library that has registered itself via OpenAjax.hub.registerLibrary(). For example, if the FooLib library has prefix foo and has registered itself via OpenAjax.hub.registerLibrary(), then there will be an OpenAjax.hub.libraries.foo property. The OpenAjax.hub.libraries.foo property MUST point to an object that in turn will have four properties, 'prefix', 'namespaceURI', 'version', and 'extraData', which will hold the corresponding values that were passed to OpenAjax.hub.registerLibrary(). Therefore, the 'version' for FooLib can be found at: OpenAjax.hub.libraries.foo.version

Developers should be aware that the content of OpenAjax.hub.libraries is dynamic. It is possible, for example, that an Ajax library might unregister itself (and perhaps re-register itself) as the application runs. Therefore, applications SHOULD NOT retain persistent pointers to the internal contents of OpenAjax.hub.libraries because those pointers might become out of sync with the current state of the Hub; instead, applications SHOULD access the internal values via a reference to OpenAjax.hub.libraries each time before using those values.

Conformance Requirements

To be OpenAjax Conformant, libraries MUST register themselves properly via OpenAjax.registerLibrary() at the time when the <script> tag(s) that includes the given library is processed (i.e., when the JavaScript files are fetched and then parsed by the browser's JavaScript's engine).

To be OpenAjax Conformant, libraries MUST treat OpenAjax.libraries as a read-only public variable.

Library collision prevention

Prefixes and Namespace URIs

The OpenAjax Hub assumes that each library defines its own unique prefix and namespace URI.

To be OpenAjax Conformant, a library MUST define its own unique prefix and namespace URI. These two values MUST be passed as parameters to OpenAjax.hub.registerLibrary() (see /member/wiki/OpenAjax_Hub_Specification_Libraries). The prefix specifies a short name for the given library and the namespace URI holds a URI reference that uniquely identifies the library. prefix and the namespace URI MUST conform to W3C rules for namespace prefixes and URI references as defined in Namespaces in XML.

If an Ajax library's documentation contains a section on OpenAjax Conformance and/or compatibility with the OpenAjax Hub, that documentation SHOULD specify the parameters that are passed to OpenAjax.hub.registerLibrary() (i.e., prefix, namespace URI, version information, etc.).

Multiple Usage

When a developer integrates multiple independent Ajax components within a single frame within the same Web page, sometimes multiple components use the same Ajax library.

To be OpenAjax Conformant, libraries MUST provide a reasonable approach to application developers for addressing the possibility that the given library might be used multiple times within the same Ajax application, such as mashups where different mashup components use the given library multiple times (either same version of the given library or different versions of the given library).

There are multiple ways that an Ajax library can satisfy the above conformance requirement. One relatively simple approach is to have new releases maintain full backwards compatibility with older releases and instruct the developer to load a version of the Ajax library which is a high-enough revision to support the requirements of all components on the page.

Some Ajax libraries might find it is difficult or impossible to allow multiple usage due to their architecture. For example, an Ajax library that serves as a top-level UI manager of a Web page might have difficulty allowing another instance of itself within the same Web page. Therefore, it is reasonable in some scenarios for libraries to disallow multiple usage scenarios so long as this restriction is highlighted to the application developer, possibly with notes within the library's documentation or some sort of run-time notification to the developer, such as an error message.

If an Ajax library's documentation contains a section on OpenAjax Conformance and/or compatibility with the OpenAjax Hub, that documentation SHOULD describe how the given library addresses the above multiple usage conformance requirement.

OpenAjax Hub's Prefix, Namespace, Global Objects, and Multiple Usage

OpenAjax Hub is itself a library. Its prefix, namespace and global objects are:

Prefix
OpenAjax
Namespace
http://openajax.org/hub
Global objects
[window.]OpenAjax
All changes to the JavaScript runtime environment from the OpenAjax Hub are contained within the [window.]OpenAjax object.

To address the multiple usage conformance requirement: (see above: OpenAjax Conformance Requirement (Libraries): Multiple Usage)

  • Future versions of the OpenAjax Hub specification will be backwards compatible with previous specifications
  • Implementations of the Hub MUST have their loading logic (i.e., the Hub's JavaScript logic that gets eval'd when the <script> element is processed) check to see if another implementation of the Hub has already been loaded, and if so, MUST NOT remove, replace, or otherwise modify any of the objects associated with the existing Hub, and MUST NOT install or initial itself within the JavaScript environment
  • Libraries or components that have a requirement for a particular version of the Hub MUST check the currently installed version of the Hub and produce an appropriate error if the currently installed version does not support the features it needs.



<--previous       contents--^       next-->
Personal tools