You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by hn...@apache.org on 2010/10/04 18:21:18 UTC
svn commit: r1004309 [1/2] - in
/shindig/trunk/extras/src/main/javascript/features-extras: ./
org.openajax.hub-2.0.3/ org.openajax.hub-2.0.4/ org.openajax.hub-2.0.5/
pubsub-2/
Author: hnguy
Date: Mon Oct 4 16:21:18 2010
New Revision: 1004309
URL: http://svn.apache.org/viewvc?rev=1004309&view=rev
Log:
SHINDIG-1438 - Patch from Han Nguyen - upgrade OpenAjaxHub from v2.0.4 to v2.0.5 for pubsub-2 gadgets refresh error.
Added:
shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/
shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/OpenAjax-mashup.js
shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/crypto.js
shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/feature.xml
shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/iframe.js
Removed:
shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.3/
shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.4/
Modified:
shindig/trunk/extras/src/main/javascript/features-extras/features.txt
shindig/trunk/extras/src/main/javascript/features-extras/pubsub-2/feature.xml
Modified: shindig/trunk/extras/src/main/javascript/features-extras/features.txt
URL: http://svn.apache.org/viewvc/shindig/trunk/extras/src/main/javascript/features-extras/features.txt?rev=1004309&r1=1004308&r2=1004309&view=diff
==============================================================================
--- shindig/trunk/extras/src/main/javascript/features-extras/features.txt (original)
+++ shindig/trunk/extras/src/main/javascript/features-extras/features.txt Mon Oct 4 16:21:18 2010
@@ -20,4 +20,4 @@ features-extras/org.jquery.core-1.4.2/fe
features-extras/wave/feature.xml
features-extras/opensocial-payment/feature.xml
features-extras/pubsub-2/feature.xml
-features-extras/org.openajax.hub-2.0.4/feature.xml
+features-extras/org.openajax.hub-2.0.5/feature.xml
Added: shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/OpenAjax-mashup.js
URL: http://svn.apache.org/viewvc/shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/OpenAjax-mashup.js?rev=1004309&view=auto
==============================================================================
--- shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/OpenAjax-mashup.js (added)
+++ shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/OpenAjax-mashup.js Mon Oct 4 16:21:18 2010
@@ -0,0 +1,1357 @@
+/*******************************************************************************
+ * OpenAjax-mashup.js
+ *
+ * Reference implementation of the OpenAjax Hub, as specified by OpenAjax Alliance.
+ * Specification is under development at:
+ *
+ * http://www.openajax.org/member/wiki/OpenAjax_Hub_Specification
+ *
+ * Copyright 2006-2009 OpenAjax Alliance
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0 . Unless
+ * required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ ******************************************************************************/
+
+var OpenAjax = OpenAjax || {};
+
+if ( !OpenAjax.hub ) { // prevent re-definition of the OpenAjax.hub object
+
+OpenAjax.hub = function() {
+ var libs = {};
+ var ooh = "org.openajax.hub.";
+
+ return /** @scope OpenAjax.hub */ {
+ implementer: "http://openajax.org",
+ implVersion: "2.0.5",
+ specVersion: "2.0",
+ implExtraData: {},
+ libraries: libs,
+
+ registerLibrary: function(prefix, nsURL, version, extra) {
+ libs[prefix] = {
+ prefix: prefix,
+ namespaceURI: nsURL,
+ version: version,
+ extraData: extra
+ };
+ this.publish(ooh+"registerLibrary", libs[prefix]);
+ },
+
+ unregisterLibrary: function(prefix) {
+ this.publish(ooh+"unregisterLibrary", libs[prefix]);
+ delete libs[prefix];
+ }
+ };
+}();
+
+/**
+ * Error
+ *
+ * Standard Error names used when the standard functions need to throw Errors.
+ */
+OpenAjax.hub.Error = {
+ // Either a required argument is missing or an invalid argument was provided
+ BadParameters: "OpenAjax.hub.Error.BadParameters",
+ // The specified hub has been disconnected and cannot perform the requested
+ // operation:
+ Disconnected: "OpenAjax.hub.Error.Disconnected",
+ // Container with specified ID already exists:
+ Duplicate: "OpenAjax.hub.Error.Duplicate",
+ // The specified ManagedHub has no such Container (or it has been removed)
+ NoContainer: "OpenAjax.hub.Error.NoContainer",
+ // The specified ManagedHub or Container has no such subscription
+ NoSubscription: "OpenAjax.hub.Error.NoSubscription",
+ // Permission denied by manager's security policy
+ NotAllowed: "OpenAjax.hub.Error.NotAllowed",
+ // Wrong communications protocol identifier provided by Container or HubClient
+ WrongProtocol: "OpenAjax.hub.Error.WrongProtocol",
+ // A 'tunnelURI' param was specified, but current browser does not support security features
+ IncompatBrowser: "OpenAjax.hub.Error.IncompatBrowser"
+};
+
+/**
+ * SecurityAlert
+ *
+ * Standard codes used when attempted security violations are detected. Unlike
+ * Errors, these codes are not thrown as exceptions but rather passed into the
+ * SecurityAlertHandler function registered with the Hub instance.
+ */
+OpenAjax.hub.SecurityAlert = {
+ // Container did not load (possible frame phishing attack)
+ LoadTimeout: "OpenAjax.hub.SecurityAlert.LoadTimeout",
+ // Hub suspects a frame phishing attack against the specified container
+ FramePhish: "OpenAjax.hub.SecurityAlert.FramePhish",
+ // Hub detected a message forgery that purports to come to a specified
+ // container
+ ForgedMsg: "OpenAjax.hub.SecurityAlert.ForgedMsg"
+};
+
+/**
+ * Debugging Help
+ *
+ * OpenAjax.hub.enableDebug
+ *
+ * If OpenAjax.hub.enableDebug is set to true, then the "debugger" keyword
+ * will get hit whenever a user callback throws an exception, thereby
+ * bringing up the JavaScript debugger.
+ */
+OpenAjax.hub._debugger = function() {
+// if ( OpenAjax.hub.enableDebug ) debugger; // REMOVE ON BUILD
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Hub interface
+ *
+ * Hub is implemented on the manager side by ManagedHub and on the client side
+ * by ClientHub.
+ */
+//OpenAjax.hub.Hub = function() {}
+
+/**
+ * Subscribe to a topic.
+ *
+ * @param {String} topic
+ * A valid topic string. MAY include wildcards.
+ * @param {Function} onData
+ * Callback function that is invoked whenever an event is
+ * published on the topic
+ * @param {Object} [scope]
+ * When onData callback or onComplete callback is invoked,
+ * the JavaScript "this" keyword refers to this scope object.
+ * If no scope is provided, default is window.
+ * @param {Function} [onComplete]
+ * Invoked to tell the client application whether the
+ * subscribe operation succeeded or failed.
+ * @param {*} [subscriberData]
+ * Client application provides this data, which is handed
+ * back to the client application in the subscriberData
+ * parameter of the onData callback function.
+ *
+ * @returns subscriptionID
+ * Identifier representing the subscription. This identifier is an
+ * arbitrary ID string that is unique within this Hub instance
+ * @type {String}
+ *
+ * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
+ * @throws {OpenAjax.hub.Error.BadParameters} if the topic is invalid (e.g. contains an empty token)
+ */
+//OpenAjax.hub.Hub.prototype.subscribe = function( topic, onData, scope, onComplete, subscriberData ) {}
+
+/**
+ * Publish an event on a topic
+ *
+ * @param {String} topic
+ * A valid topic string. MUST NOT include wildcards.
+ * @param {*} data
+ * Valid publishable data. To be portable across different
+ * Container implementations, this value SHOULD be serializable
+ * as JSON.
+ *
+ * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
+ * @throws {OpenAjax.hub.Error.BadParameters} if the topic cannot be published (e.g. contains
+ * wildcards or empty tokens) or if the data cannot be published (e.g. cannot be serialized as JSON)
+ */
+//OpenAjax.hub.Hub.prototype.publish = function( topic, data ) {}
+
+/**
+ * Unsubscribe from a subscription
+ *
+ * @param {String} subscriptionID
+ * A subscriptionID returned by Hub.subscribe()
+ * @param {Function} [onComplete]
+ * Callback function invoked when unsubscribe completes
+ * @param {Object} [scope]
+ * When onComplete callback function is invoked, the JavaScript "this"
+ * keyword refers to this scope object.
+ * If no scope is provided, default is window.
+ *
+ * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
+ * @throws {OpenAjax.hub.Error.NoSubscription} if no such subscription is found
+ */
+//OpenAjax.hub.Hub.prototype.unsubscribe = function( subscriptionID, onComplete, scope ) {}
+
+/**
+ * Return true if this Hub instance is in the Connected state.
+ * Else returns false.
+ *
+ * This function can be called even if the Hub is not in a CONNECTED state.
+ *
+ * @returns Boolean
+ * @type {Boolean}
+ */
+//OpenAjax.hub.Hub.prototype.isConnected = function() {}
+
+/**
+ * Returns the scope associated with this Hub instance and which will be used
+ * with callback functions.
+ *
+ * This function can be called even if the Hub is not in a CONNECTED state.
+ *
+ * @returns scope object
+ * @type {Object}
+ */
+//OpenAjax.hub.Hub.prototype.getScope = function() {}
+
+/**
+ * Returns the subscriberData parameter that was provided when
+ * Hub.subscribe was called.
+ *
+ * @param {String} subscriptionID
+ * The subscriberID of a subscription
+ *
+ * @returns subscriberData
+ * @type {*}
+ *
+ * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
+ * @throws {OpenAjax.hub.Error.NoSubscription} if there is no such subscription
+ */
+//OpenAjax.hub.Hub.prototype.getSubscriberData = function(subscriptionID) {}
+
+/**
+ * Returns the scope associated with a specified subscription. This scope will
+ * be used when invoking the 'onData' callback supplied to Hub.subscribe().
+ *
+ * @param {String} subscriberID
+ * The subscriberID of a subscription
+ *
+ * @returns scope
+ * @type {*}
+ *
+ * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
+ * @throws {OpenAjax.hub.Error.NoSubscription} if there is no such subscription
+ */
+//OpenAjax.hub.Hub.prototype.getSubscriberScope = function(subscriberID) {}
+
+/**
+ * Returns the params object associated with this Hub instance.
+ *
+ * @returns params
+ * The params object associated with this Hub instance
+ * @type {Object}
+ */
+//OpenAjax.hub.Hub.prototype.getParameters = function() {}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * HubClient interface
+ *
+ * Extends Hub interface.
+ *
+ * A HubClient implementation is typically specific to a particular
+ * implementation of Container.
+ */
+
+/**
+ * Create a new HubClient. All HubClient constructors MUST have this
+ * signature.
+ * @constructor
+ *
+ * @param {Object} params
+ * Parameters used to instantiate the HubClient.
+ * Once the constructor is called, the params object belongs to the
+ * HubClient. The caller MUST not modify it.
+ * Implementations of HubClient may specify additional properties
+ * for the params object, besides those identified below.
+ *
+ * @param {Function} params.HubClient.onSecurityAlert
+ * Called when an attempted security breach is thwarted
+ * @param {Object} [params.HubClient.scope]
+ * Whenever one of the HubClient's callback functions is called,
+ * references to "this" in the callback will refer to the scope object.
+ * If not provided, the default is window.
+ * @param {Function} [params.HubClient.log]
+ * Optional logger function. Would be used to log to console.log or
+ * equivalent.
+ *
+ * @throws {OpenAjax.hub.Error.BadParameters} if any of the required
+ * parameters is missing, or if a parameter value is invalid in
+ * some way.
+ */
+//OpenAjax.hub.HubClient = function( params ) {}
+
+/**
+ * Requests a connection to the ManagedHub, via the Container
+ * associated with this HubClient.
+ *
+ * If the Container accepts the connection request, the HubClient's
+ * state is set to CONNECTED and the HubClient invokes the
+ * onComplete callback function.
+ *
+ * If the Container refuses the connection request, the HubClient
+ * invokes the onComplete callback function with an error code.
+ * The error code might, for example, indicate that the Container
+ * is being destroyed.
+ *
+ * In most implementations, this function operates asynchronously,
+ * so the onComplete callback function is the only reliable way to
+ * determine when this function completes and whether it has succeeded
+ * or failed.
+ *
+ * A client application may call HubClient.disconnect and then call
+ * HubClient.connect.
+ *
+ * @param {Function} [onComplete]
+ * Callback function to call when this operation completes.
+ * @param {Object} [scope]
+ * When the onComplete function is invoked, the JavaScript "this"
+ * keyword refers to this scope object.
+ * If no scope is provided, default is window.
+ *
+ * @throws {OpenAjax.hub.Error.Duplicate} if the HubClient is already connected
+ */
+//OpenAjax.hub.HubClient.prototype.connect = function( onComplete, scope ) {}
+
+/**
+ * Disconnect from the ManagedHub
+ *
+ * Disconnect immediately:
+ *
+ * 1. Sets the HubClient's state to DISCONNECTED.
+ * 2. Causes the HubClient to send a Disconnect request to the
+ * associated Container.
+ * 3. Ensures that the client application will receive no more
+ * onData or onComplete callbacks associated with this
+ * connection, except for the disconnect function's own
+ * onComplete callback.
+ * 4. Automatically destroys all of the HubClient's subscriptions.
+ *
+ * In most implementations, this function operates asynchronously,
+ * so the onComplete callback function is the only reliable way to
+ * determine when this function completes and whether it has succeeded
+ * or failed.
+ *
+ * A client application is allowed to call HubClient.disconnect and
+ * then call HubClient.connect.
+ *
+ * @param {Function} [onComplete]
+ * Callback function to call when this operation completes.
+ * @param {Object} [scope]
+ * When the onComplete function is invoked, the JavaScript "this"
+ * keyword refers to the scope object.
+ * If no scope is provided, default is window.
+ *
+ * @throws {OpenAjax.hub.Error.Disconnected} if the HubClient is already
+ * disconnected
+ */
+//OpenAjax.hub.HubClient.prototype.disconnect = function( onComplete, scope ) {}
+
+/**
+ * If DISCONNECTED: Returns null
+ * If CONNECTED: Returns the origin associated with the window containing the
+ * Container associated with this HubClient instance. The origin has the format
+ *
+ * [protocol]://[host]
+ *
+ * where:
+ *
+ * [protocol] is "http" or "https"
+ * [host] is the hostname of the partner page.
+ *
+ * @returns Partner's origin
+ * @type {String}
+ */
+//OpenAjax.hub.HubClient.prototype.getPartnerOrigin = function() {}
+
+/**
+ * Returns the client ID of this HubClient
+ *
+ * @returns clientID
+ * @type {String}
+ */
+//OpenAjax.hub.HubClient.prototype.getClientID = function() {}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * OpenAjax.hub.ManagedHub
+ *
+ * Managed hub API for the manager application and for Containers.
+ *
+ * Implements OpenAjax.hub.Hub.
+ */
+
+/**
+ * Create a new ManagedHub instance
+ * @constructor
+ *
+ * This constructor automatically sets the ManagedHub's state to
+ * CONNECTED.
+ *
+ * @param {Object} params
+ * Parameters used to instantiate the ManagedHub.
+ * Once the constructor is called, the params object belongs exclusively to
+ * the ManagedHub. The caller MUST not modify it.
+ *
+ * The params object may contain the following properties:
+ *
+ * @param {Function} params.onPublish
+ * Callback function that is invoked whenever a
+ * data value published by a Container is about
+ * to be delivered to some (possibly the same) Container.
+ * This callback function implements a security policy;
+ * it returns true if the delivery of the data is
+ * permitted and false if permission is denied.
+ * @param {Function} params.onSubscribe
+ * Called whenever a Container tries to subscribe
+ * on behalf of its client.
+ * This callback function implements a security policy;
+ * it returns true if the subscription is permitted
+ * and false if permission is denied.
+ * @param {Function} [params.onUnsubscribe]
+ * Called whenever a Container unsubscribes on behalf of its client.
+ * Unlike the other callbacks, onUnsubscribe is intended only for
+ * informative purposes, and is not used to implement a security
+ * policy.
+ * @param {Object} [params.scope]
+ * Whenever one of the ManagedHub's callback functions is called,
+ * references to the JavaScript "this" keyword in the callback
+ * function refer to this scope object
+ * If no scope is provided, default is window.
+ * @param {Function} [params.log] Optional logger function. Would
+ * be used to log to console.log or equivalent.
+ *
+ * @throws {OpenAjax.hub.Error.BadParameters} if any of the required
+ * parameters are missing
+ */
+OpenAjax.hub.ManagedHub = function( params )
+{
+ if ( ! params || ! params.onPublish || ! params.onSubscribe )
+ throw new Error( OpenAjax.hub.Error.BadParameters );
+
+ this._p = params;
+ this._onUnsubscribe = params.onUnsubscribe ? params.onUnsubscribe : null;
+ this._scope = params.scope || window;
+
+ if ( params.log ) {
+ var that = this;
+ this._log = function( msg ) {
+ try {
+ params.log.call( that._scope, "ManagedHub: " + msg );
+ } catch( e ) {
+ OpenAjax.hub._debugger();
+ }
+ };
+ } else {
+ this._log = function() {};
+ }
+
+ this._subscriptions = { c:{}, s:null };
+ this._containers = {};
+
+ // Sequence # used to create IDs that are unique within this hub
+ this._seq = 0;
+
+ this._active = true;
+
+ this._isPublishing = false;
+ this._pubQ = [];
+}
+
+/**
+ * Subscribe to a topic on behalf of a Container. Called only by
+ * Container implementations, NOT by manager applications.
+ *
+ * This function:
+ * 1. Checks with the ManagedHub's onSubscribe security policy
+ * to determine whether this Container is allowed to subscribe
+ * to this topic.
+ * 2. If the subscribe operation is permitted, subscribes to the
+ * topic and returns the ManagedHub's subscription ID for this
+ * subscription.
+ * 3. If the subscribe operation is not permitted, throws
+ * OpenAjax.hub.Error.NotAllowed.
+ *
+ * When data is published on the topic, the ManagedHub's
+ * onPublish security policy will be invoked to ensure that
+ * this Container is permitted to receive the published data.
+ * If the Container is allowed to receive the data, then the
+ * Container's sendToClient function will be invoked.
+ *
+ * When a Container needs to create a subscription on behalf of
+ * its client, the Container MUST use this function to create
+ * the subscription.
+ *
+ * @param {OpenAjax.hub.Container} container
+ * A Container
+ * @param {String} topic
+ * A valid topic
+ * @param {String} containerSubID
+ * Arbitrary string ID that the Container uses to
+ * represent the subscription. Must be unique within the
+ * context of the Container
+ *
+ * @returns managerSubID
+ * Arbitrary string ID that this ManagedHub uses to
+ * represent the subscription. Will be unique within the
+ * context of this ManagedHub
+ * @type {String}
+ *
+ * @throws {OpenAjax.hub.Error.Disconnected} if this.isConnected() returns false
+ * @throws {OpenAjax.hub.Error.NotAllowed} if subscription request is denied by the onSubscribe security policy
+ * @throws {OpenAjax.hub.Error.BadParameters} if one of the parameters, e.g. the topic, is invalid
+ */
+OpenAjax.hub.ManagedHub.prototype.subscribeForClient = function( container, topic, containerSubID )
+{
+ this._assertConn();
+ // check subscribe permission
+ if ( this._invokeOnSubscribe( topic, container ) ) {
+ // return ManagedHub's subscriptionID for this subscription
+ return this._subscribe( topic, this._sendToClient, this, { c: container, sid: containerSubID } );
+ }
+ throw new Error(OpenAjax.hub.Error.NotAllowed);
+}
+
+/**
+ * Unsubscribe from a subscription on behalf of a Container. Called only by
+ * Container implementations, NOT by manager application code.
+ *
+ * This function:
+ * 1. Destroys the specified subscription
+ * 2. Calls the ManagedHub's onUnsubscribe callback function
+ *
+ * This function can be called even if the ManagedHub is not in a CONNECTED state.
+ *
+ * @param {OpenAjax.hub.Container} container
+ * container instance that is unsubscribing
+ * @param {String} managerSubID
+ * opaque ID of a subscription, returned by previous call to subscribeForClient()
+ *
+ * @throws {OpenAjax.hub.Error.NoSubscription} if subscriptionID does not refer to a valid subscription
+ */
+OpenAjax.hub.ManagedHub.prototype.unsubscribeForClient = function( container, managerSubID )
+{
+ this._unsubscribe( managerSubID );
+ this._invokeOnUnsubscribe( container, managerSubID );
+}
+
+/**
+ * Publish data on a topic on behalf of a Container. Called only by
+ * Container implementations, NOT by manager application code.
+ *
+ * @param {OpenAjax.hub.Container} container
+ * Container on whose behalf data should be published
+ * @param {String} topic
+ * Valid topic string. Must NOT contain wildcards.
+ * @param {*} data
+ * Valid publishable data. To be portable across different
+ * Container implementations, this value SHOULD be serializable
+ * as JSON.
+ *
+ * @throws {OpenAjax.hub.Error.Disconnected} if this.isConnected() returns false
+ * @throws {OpenAjax.hub.Error.BadParameters} if one of the parameters, e.g. the topic, is invalid
+ */
+OpenAjax.hub.ManagedHub.prototype.publishForClient = function( container, topic, data )
+{
+ this._assertConn();
+ this._publish( topic, data, container );
+}
+
+/**
+ * Destroy this ManagedHub
+ *
+ * 1. Sets state to DISCONNECTED. All subsequent attempts to add containers,
+ * publish or subscribe will throw the Disconnected error. We will
+ * continue to allow "cleanup" operations such as removeContainer
+ * and unsubscribe, as well as read-only operations such as
+ * isConnected
+ * 2. Remove all Containers associated with this ManagedHub
+ */
+OpenAjax.hub.ManagedHub.prototype.disconnect = function()
+{
+ this._active = false;
+ for (var c in this._containers) {
+ this.removeContainer( this._containers[c] );
+ }
+}
+
+/**
+ * Get a container belonging to this ManagedHub by its clientID, or null
+ * if this ManagedHub has no such container
+ *
+ * This function can be called even if the ManagedHub is not in a CONNECTED state.
+ *
+ * @param {String} containerId
+ * Arbitrary string ID associated with the container
+ *
+ * @returns container associated with given ID
+ * @type {OpenAjax.hub.Container}
+ */
+OpenAjax.hub.ManagedHub.prototype.getContainer = function( containerId )
+{
+ var container = this._containers[containerId];
+ return container ? container : null;
+}
+
+/**
+ * Returns an array listing all containers belonging to this ManagedHub.
+ * The order of the Containers in this array is arbitrary.
+ *
+ * This function can be called even if the ManagedHub is not in a CONNECTED state.
+ *
+ * @returns container array
+ * @type {OpenAjax.hub.Container[]}
+ */
+OpenAjax.hub.ManagedHub.prototype.listContainers = function()
+{
+ var res = [];
+ for (var c in this._containers) {
+ res.push(this._containers[c]);
+ }
+ return res;
+}
+
+/**
+ * Add a container to this ManagedHub.
+ *
+ * This function should only be called by a Container constructor.
+ *
+ * @param {OpenAjax.hub.Container} container
+ * A Container to be added to this ManagedHub
+ *
+ * @throws {OpenAjax.hub.Error.Duplicate} if there is already a Container
+ * in this ManagedHub whose clientId is the same as that of container
+ * @throws {OpenAjax.hub.Error.Disconnected} if this.isConnected() returns false
+ */
+OpenAjax.hub.ManagedHub.prototype.addContainer = function( container )
+{
+ this._assertConn();
+ var containerId = container.getClientID();
+ if ( this._containers[containerId] ) {
+ throw new Error(OpenAjax.hub.Error.Duplicate);
+ }
+ this._containers[containerId] = container;
+}
+
+/**
+ * Remove a container from this ManagedHub immediately
+ *
+ * This function can be called even if the ManagedHub is not in a CONNECTED state.
+ *
+ * @param {OpenAjax.hub.Container} container
+ * A Container to be removed from this ManagedHub
+ *
+ * @throws {OpenAjax.hub.Error.NoContainer} if no such container is found
+ */
+OpenAjax.hub.ManagedHub.prototype.removeContainer = function( container )
+{
+ var containerId = container.getClientID();
+ if ( ! this._containers[ containerId ] ) {
+ throw new Error(OpenAjax.hub.Error.NoContainer);
+ }
+ container.remove();
+ delete this._containers[ containerId ];
+}
+
+ /*** OpenAjax.hub.Hub interface implementation ***/
+
+/**
+ * Subscribe to a topic.
+ *
+ * This implementation of Hub.subscribe is synchronous. When subscribe
+ * is called:
+ *
+ * 1. The ManagedHub's onSubscribe callback is invoked. The
+ * container parameter is null, because the manager application,
+ * rather than a container, is subscribing.
+ * 2. If onSubscribe returns true, then the subscription is created.
+ * 3. The onComplete callback is invoked.
+ * 4. Then this function returns.
+ *
+ * @param {String} topic
+ * A valid topic string. MAY include wildcards.
+ * @param {Function} onData
+ * Callback function that is invoked whenever an event is
+ * published on the topic
+ * @param {Object} [scope]
+ * When onData callback or onComplete callback is invoked,
+ * the JavaScript "this" keyword refers to this scope object.
+ * If no scope is provided, default is window.
+ * @param {Function} [onComplete]
+ * Invoked to tell the client application whether the
+ * subscribe operation succeeded or failed.
+ * @param {*} [subscriberData]
+ * Client application provides this data, which is handed
+ * back to the client application in the subscriberData
+ * parameter of the onData and onComplete callback functions.
+ *
+ * @returns subscriptionID
+ * Identifier representing the subscription. This identifier is an
+ * arbitrary ID string that is unique within this Hub instance
+ * @type {String}
+ *
+ * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
+ * @throws {OpenAjax.hub.Error.BadParameters} if the topic is invalid (e.g. contains an empty token)
+ */
+OpenAjax.hub.ManagedHub.prototype.subscribe = function( topic, onData, scope, onComplete, subscriberData )
+{
+ this._assertConn();
+ this._assertSubTopic(topic);
+ if ( ! onData ) {
+ throw new Error( OpenAjax.hub.Error.BadParameters );
+ }
+
+ scope = scope || window;
+
+ // check subscribe permission
+ if ( ! this._invokeOnSubscribe( topic, null ) ) {
+ this._invokeOnComplete( onComplete, scope, null, false, OpenAjax.hub.Error.NotAllowed );
+ return;
+ }
+
+ // on publish event, check publish permissions
+ var that = this;
+ function publishCB( topic, data, sd, pcont ) {
+ if ( that._invokeOnPublish( topic, data, pcont, null ) ) {
+ try {
+ onData.call( scope, topic, data, subscriberData );
+ } catch( e ) {
+ OpenAjax.hub._debugger();
+ that._log( "caught error from onData callback to Hub.subscribe(): " + e.message );
+ }
+ }
+ }
+ var subID = this._subscribe( topic, publishCB, scope, subscriberData );
+ this._invokeOnComplete( onComplete, scope, subID, true );
+ return subID;
+}
+
+/**
+ * Publish an event on a topic
+ *
+ * This implementation of Hub.publish is synchronous. When publish
+ * is called:
+ *
+ * 1. The target subscriptions are identified.
+ * 2. For each target subscription, the ManagedHub's onPublish
+ * callback is invoked. Data is only delivered to a target
+ * subscription if the onPublish callback returns true.
+ * The pcont parameter of the onPublish callback is null.
+ * This is because the ManagedHub, rather than a container,
+ * is publishing the data.
+ *
+ * @param {String} topic
+ * A valid topic string. MUST NOT include wildcards.
+ * @param {*} data
+ * Valid publishable data. To be portable across different
+ * Container implementations, this value SHOULD be serializable
+ * as JSON.
+ *
+ * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
+ * @throws {OpenAjax.hub.Error.BadParameters} if the topic cannot be published (e.g. contains
+ * wildcards or empty tokens) or if the data cannot be published (e.g. cannot be serialized as JSON)
+ */
+OpenAjax.hub.ManagedHub.prototype.publish = function( topic, data )
+{
+ this._assertConn();
+ this._assertPubTopic(topic);
+ this._publish( topic, data, null );
+}
+
+/**
+ * Unsubscribe from a subscription
+ *
+ * This implementation of Hub.unsubscribe is synchronous. When unsubscribe
+ * is called:
+ *
+ * 1. The subscription is destroyed.
+ * 2. The ManagedHub's onUnsubscribe callback is invoked, if there is one.
+ * 3. The onComplete callback is invoked.
+ * 4. Then this function returns.
+ *
+ * @param {String} subscriptionID
+ * A subscriptionID returned by Hub.subscribe()
+ * @param {Function} [onComplete]
+ * Callback function invoked when unsubscribe completes
+ * @param {Object} [scope]
+ * When onComplete callback function is invoked, the JavaScript "this"
+ * keyword refers to this scope object.
+ * If no scope is provided, default is window.
+ *
+ * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
+ * @throws {OpenAjax.hub.Error.NoSubscription} if no such subscription is found
+ */
+OpenAjax.hub.ManagedHub.prototype.unsubscribe = function( subscriptionID, onComplete, scope )
+{
+ this._assertConn();
+ if ( ! subscriptionID ) {
+ throw new Error( OpenAjax.hub.Error.BadParameters );
+ }
+ this._unsubscribe( subscriptionID );
+ this._invokeOnUnsubscribe( null, subscriptionID );
+ this._invokeOnComplete( onComplete, scope, subscriptionID, true );
+}
+
+/**
+ * Returns true if disconnect() has NOT been called on this ManagedHub,
+ * else returns false
+ *
+ * @returns Boolean
+ * @type {Boolean}
+ */
+OpenAjax.hub.ManagedHub.prototype.isConnected = function()
+{
+ return this._active;
+}
+
+/**
+* Returns the scope associated with this Hub instance and which will be used
+* with callback functions.
+*
+* This function can be called even if the Hub is not in a CONNECTED state.
+*
+* @returns scope object
+* @type {Object}
+ */
+OpenAjax.hub.ManagedHub.prototype.getScope = function()
+{
+ return this._scope;
+}
+
+/**
+ * Returns the subscriberData parameter that was provided when
+ * Hub.subscribe was called.
+ *
+ * @param subscriberID
+ * The subscriberID of a subscription
+ *
+ * @returns subscriberData
+ * @type {*}
+ *
+ * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
+ * @throws {OpenAjax.hub.Error.NoSubscription} if there is no such subscription
+ */
+OpenAjax.hub.ManagedHub.prototype.getSubscriberData = function( subscriberID )
+{
+ this._assertConn();
+ var path = subscriberID.split(".");
+ var sid = path.pop();
+ var sub = this._getSubscriptionObject( this._subscriptions, path, 0, sid );
+ if ( sub )
+ return sub.data;
+ throw new Error( OpenAjax.hub.Error.NoSubscription );
+}
+
+/**
+ * Returns the scope associated with a specified subscription. This scope will
+ * be used when invoking the 'onData' callback supplied to Hub.subscribe().
+ *
+ * @param subscriberID
+ * The subscriberID of a subscription
+ *
+ * @returns scope
+ * @type {*}
+ *
+ * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
+ * @throws {OpenAjax.hub.Error.NoSubscription} if there is no such subscription
+ */
+OpenAjax.hub.ManagedHub.prototype.getSubscriberScope = function( subscriberID )
+{
+ this._assertConn();
+ var path = subscriberID.split(".");
+ var sid = path.pop();
+ var sub = this._getSubscriptionObject( this._subscriptions, path, 0, sid );
+ if ( sub )
+ return sub.scope;
+ throw new Error( OpenAjax.hub.Error.NoSubscription );
+}
+
+/**
+ * Returns the params object associated with this Hub instance.
+ * Allows mix-in code to access parameters passed into constructor that created
+ * this Hub instance.
+ *
+ * @returns params the params object associated with this Hub instance
+ * @type {Object}
+ */
+OpenAjax.hub.ManagedHub.prototype.getParameters = function()
+{
+ return this._p;
+}
+
+
+/* PRIVATE FUNCTIONS */
+
+/**
+ * Send a message to a container's client.
+ * This is an OAH subscriber's data callback. It is private to ManagedHub
+ * and serves as an adapter between the OAH 1.0 API and Container.sendToClient.
+ *
+ * @param {String} topic Topic on which data was published
+ * @param {Object} data Data to be delivered to the client
+ * @param {Object} sd Object containing properties
+ * c: container to which data must be sent
+ * sid: subscription ID within that container
+ * @param {Object} pcont Publishing container, or null if this data was
+ * published by the manager
+ */
+OpenAjax.hub.ManagedHub.prototype._sendToClient = function(topic, data, sd, pcont)
+{
+ if (!this.isConnected()) {
+ return;
+ }
+ if ( this._invokeOnPublish( topic, data, pcont, sd.c ) ) {
+ sd.c.sendToClient( topic, data, sd.sid );
+ }
+}
+
+OpenAjax.hub.ManagedHub.prototype._assertConn = function()
+{
+ if (!this.isConnected()) {
+ throw new Error(OpenAjax.hub.Error.Disconnected);
+ }
+}
+
+OpenAjax.hub.ManagedHub.prototype._assertPubTopic = function(topic)
+{
+ if ( !topic || topic === "" || (topic.indexOf("*") != -1) ||
+ (topic.indexOf("..") != -1) || (topic.charAt(0) == ".") ||
+ (topic.charAt(topic.length-1) == "."))
+ {
+ throw new Error(OpenAjax.hub.Error.BadParameters);
+ }
+}
+
+OpenAjax.hub.ManagedHub.prototype._assertSubTopic = function(topic)
+{
+ if ( ! topic ) {
+ throw new Error(OpenAjax.hub.Error.BadParameters);
+ }
+ var path = topic.split(".");
+ var len = path.length;
+ for (var i = 0; i < len; i++) {
+ var p = path[i];
+ if ((p === "") ||
+ ((p.indexOf("*") != -1) && (p != "*") && (p != "**"))) {
+ throw new Error(OpenAjax.hub.Error.BadParameters);
+ }
+ if ((p == "**") && (i < len - 1)) {
+ throw new Error(OpenAjax.hub.Error.BadParameters);
+ }
+ }
+}
+
+OpenAjax.hub.ManagedHub.prototype._invokeOnComplete = function( func, scope, item, success, errorCode )
+{
+ if ( func ) { // onComplete is optional
+ try {
+ scope = scope || window;
+ func.call( scope, item, success, errorCode );
+ } catch( e ) {
+ OpenAjax.hub._debugger();
+ this._log( "caught error from onComplete callback: " + e.message );
+ }
+ }
+}
+
+OpenAjax.hub.ManagedHub.prototype._invokeOnPublish = function( topic, data, pcont, scont )
+{
+ try {
+ return this._p.onPublish.call( this._scope, topic, data, pcont, scont );
+ } catch( e ) {
+ OpenAjax.hub._debugger();
+ this._log( "caught error from onPublish callback to constructor: " + e.message );
+ }
+ return false;
+}
+
+OpenAjax.hub.ManagedHub.prototype._invokeOnSubscribe = function( topic, container )
+{
+ try {
+ return this._p.onSubscribe.call( this._scope, topic, container );
+ } catch( e ) {
+ OpenAjax.hub._debugger();
+ this._log( "caught error from onSubscribe callback to constructor: " + e.message );
+ }
+ return false;
+}
+
+OpenAjax.hub.ManagedHub.prototype._invokeOnUnsubscribe = function( container, managerSubID )
+{
+ if ( this._onUnsubscribe ) {
+ var topic = managerSubID.slice( 0, managerSubID.lastIndexOf(".") );
+ try {
+ this._onUnsubscribe.call( this._scope, topic, container );
+ } catch( e ) {
+ OpenAjax.hub._debugger();
+ this._log( "caught error from onUnsubscribe callback to constructor: " + e.message );
+ }
+ }
+}
+
+OpenAjax.hub.ManagedHub.prototype._subscribe = function( topic, onData, scope, subscriberData )
+{
+ var handle = topic + "." + this._seq;
+ var sub = { scope: scope, cb: onData, data: subscriberData, sid: this._seq++ };
+ var path = topic.split(".");
+ this._recursiveSubscribe( this._subscriptions, path, 0, sub );
+ return handle;
+}
+
+OpenAjax.hub.ManagedHub.prototype._recursiveSubscribe = function(tree, path, index, sub)
+{
+ var token = path[index];
+ if (index == path.length) {
+ sub.next = tree.s;
+ tree.s = sub;
+ } else {
+ if (typeof tree.c == "undefined") {
+ tree.c = {};
+ }
+ if (typeof tree.c[token] == "undefined") {
+ tree.c[token] = { c: {}, s: null };
+ this._recursiveSubscribe(tree.c[token], path, index + 1, sub);
+ } else {
+ this._recursiveSubscribe( tree.c[token], path, index + 1, sub);
+ }
+ }
+}
+
+OpenAjax.hub.ManagedHub.prototype._publish = function( topic, data, pcont )
+{
+ // if we are currently handling a publish event, then queue this request
+ // and handle later, one by one
+ if ( this._isPublishing ) {
+ this._pubQ.push( { t: topic, d: data, p: pcont } );
+ return;
+ }
+
+ this._safePublish( topic, data, pcont );
+
+ while ( this._pubQ.length > 0 ) {
+ var pub = this._pubQ.shift();
+ this._safePublish( pub.t, pub.d, pub.p );
+ }
+}
+
+OpenAjax.hub.ManagedHub.prototype._safePublish = function( topic, data, pcont )
+{
+ this._isPublishing = true;
+ var path = topic.split(".");
+ this._recursivePublish( this._subscriptions, path, 0, topic, data, pcont );
+ this._isPublishing = false;
+}
+
+OpenAjax.hub.ManagedHub.prototype._recursivePublish = function(tree, path, index, name, msg, pcont)
+{
+ if (typeof tree != "undefined") {
+ var node;
+ if (index == path.length) {
+ node = tree;
+ } else {
+ this._recursivePublish(tree.c[path[index]], path, index + 1, name, msg, pcont);
+ this._recursivePublish(tree.c["*"], path, index + 1, name, msg, pcont);
+ node = tree.c["**"];
+ }
+ if (typeof node != "undefined") {
+ var sub = node.s;
+ while ( sub ) {
+ var sc = sub.scope;
+ var cb = sub.cb;
+ var d = sub.data;
+ if (typeof cb == "string") {
+ // get a function object
+ cb = sc[cb];
+ }
+ cb.call(sc, name, msg, d, pcont);
+ sub = sub.next;
+ }
+ }
+ }
+}
+
+OpenAjax.hub.ManagedHub.prototype._unsubscribe = function( subscriptionID )
+{
+ var path = subscriptionID.split(".");
+ var sid = path.pop();
+ if ( ! this._recursiveUnsubscribe( this._subscriptions, path, 0, sid ) ) {
+ throw new Error( OpenAjax.hub.Error.NoSubscription );
+ }
+}
+
+/**
+ * @returns 'true' if properly unsubscribed; 'false' otherwise
+ */
+OpenAjax.hub.ManagedHub.prototype._recursiveUnsubscribe = function(tree, path, index, sid)
+{
+ if ( typeof tree == "undefined" ) {
+ return false;
+ }
+
+ if (index < path.length) {
+ var childNode = tree.c[path[index]];
+ if ( ! childNode ) {
+ return false;
+ }
+ this._recursiveUnsubscribe(childNode, path, index + 1, sid);
+ if ( ! childNode.s ) {
+ for (var x in childNode.c) {
+ return true;
+ }
+ delete tree.c[path[index]];
+ }
+ } else {
+ var sub = tree.s;
+ var sub_prev = null;
+ var found = false;
+ while ( sub ) {
+ if ( sid == sub.sid ) {
+ found = true;
+ if ( sub == tree.s ) {
+ tree.s = sub.next;
+ } else {
+ sub_prev.next = sub.next;
+ }
+ break;
+ }
+ sub_prev = sub;
+ sub = sub.next;
+ }
+ if ( ! found ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+OpenAjax.hub.ManagedHub.prototype._getSubscriptionObject = function( tree, path, index, sid )
+{
+ if (typeof tree != "undefined") {
+ if (index < path.length) {
+ var childNode = tree.c[path[index]];
+ return this._getSubscriptionObject(childNode, path, index + 1, sid);
+ }
+
+ var sub = tree.s;
+ while ( sub ) {
+ if ( sid == sub.sid ) {
+ return sub;
+ }
+ sub = sub.next;
+ }
+ }
+ return null;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Container
+ * @constructor
+ *
+ * Container represents an instance of a manager-side object that contains and
+ * communicates with a single client of the hub. The container might be an inline
+ * container, an iframe FIM container, or an iframe PostMessage container, or
+ * it might be an instance of some other implementation.
+ *
+ * @param {OpenAjax.hub.ManagedHub} hub
+ * Managed Hub instance
+ * @param {String} clientID
+ * A string ID that identifies a particular client of a Managed Hub. Unique
+ * within the context of the ManagedHub.
+ * @param {Object} params
+ * Parameters used to instantiate the Container.
+ * Once the constructor is called, the params object belongs exclusively to
+ * the Container. The caller MUST not modify it.
+ * Implementations of Container may specify additional properties
+ * for the params object, besides those identified below.
+ * The following params properties MUST be supported by all Container
+ * implementations:
+ * @param {Function} params.Container.onSecurityAlert
+ * Called when an attempted security breach is thwarted. Function is defined
+ * as follows: function(container, securityAlert)
+ * @param {Function} [params.Container.onConnect]
+ * Called when the client connects to the Managed Hub. Function is defined
+ * as follows: function(container)
+ * @param {Function} [params.Container.onDisconnect]
+ * Called when the client disconnects from the Managed Hub. Function is
+ * defined as follows: function(container)
+ * @param {Object} [params.Container.scope]
+ * Whenever one of the Container's callback functions is called, references
+ * to "this" in the callback will refer to the scope object. If no scope is
+ * provided, default is window.
+ * @param {Function} [params.Container.log]
+ * Optional logger function. Would be used to log to console.log or
+ * equivalent.
+ *
+ * @throws {OpenAjax.hub.Error.BadParameters} if required params are not
+ * present or null
+ * @throws {OpenAjax.hub.Error.Duplicate} if a Container with this clientID
+ * already exists in the given Managed Hub
+ * @throws {OpenAjax.hub.Error.Disconnected} if ManagedHub is not connected
+ */
+//OpenAjax.hub.Container = function( hub, clientID, params ) {}
+
+/**
+ * Send a message to the client inside this container. This function MUST only
+ * be called by ManagedHub.
+ *
+ * @param {String} topic
+ * The topic name for the published message
+ * @param {*} data
+ * The payload. Can be any JSON-serializable value.
+ * @param {String} containerSubscriptionId
+ * Container's ID for a subscription, from previous call to
+ * subscribeForClient()
+ */
+//OpenAjax.hub.Container.prototype.sendToClient = function( topic, data, containerSubscriptionId ) {}
+
+/**
+ * Shut down a container. remove does all of the following:
+ * - disconnects container from HubClient
+ * - unsubscribes from all of its existing subscriptions in the ManagedHub
+ *
+ * This function is only called by ManagedHub.removeContainer
+ * Calling this function does NOT cause the container's onDisconnect callback to
+ * be invoked.
+ */
+//OpenAjax.hub.Container.prototype.remove = function() {}
+
+/**
+ * Returns true if the given client is connected to the managed hub.
+ * Else returns false.
+ *
+ * @returns true if the client is connected to the managed hub
+ * @type boolean
+ */
+//OpenAjax.hub.Container.prototype.isConnected = function() {}
+
+/**
+ * Returns the clientID passed in when this Container was instantiated.
+ *
+ * @returns The clientID
+ * @type {String}
+ */
+//OpenAjax.hub.Container.prototype.getClientID = function() {}
+
+/**
+ * If DISCONNECTED:
+ * Returns null
+ * If CONNECTED:
+ * Returns the origin associated with the window containing the HubClient
+ * associated with this Container instance. The origin has the format
+ *
+ * [protocol]://[host]
+ *
+ * where:
+ *
+ * [protocol] is "http" or "https"
+ * [host] is the hostname of the partner page.
+ *
+ * @returns Partner's origin
+ * @type {String}
+ */
+//OpenAjax.hub.Container.prototype.getPartnerOrigin = function() {}
+
+/**
+ * Returns the params object associated with this Container instance.
+ *
+ * @returns params
+ * The params object associated with this Container instance
+ * @type {Object}
+ */
+//OpenAjax.hub.Container.prototype.getParameters = function() {}
+
+/**
+ * Returns the ManagedHub to which this Container belongs.
+ *
+ * @returns ManagedHub
+ * The ManagedHub object associated with this Container instance
+ * @type {OpenAjax.hub.ManagedHub}
+ */
+//OpenAjax.hub.Container.prototype.getHub = function() {}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/*
+ * Unmanaged Hub
+ */
+
+/**
+ * OpenAjax.hub._hub is the default ManagedHub instance that we use to
+ * provide OAH 1.0 behavior.
+ */
+OpenAjax.hub._hub = new OpenAjax.hub.ManagedHub({
+ onSubscribe: function(topic, ctnr) { return true; },
+ onPublish: function(topic, data, pcont, scont) { return true; }
+});
+
+/**
+ * Subscribe to a topic.
+ *
+ * @param {String} topic
+ * A valid topic string. MAY include wildcards.
+ * @param {Function|String} onData
+ * Callback function that is invoked whenever an event is published on the
+ * topic. If 'onData' is a string, then it represents the name of a
+ * function on the 'scope' object.
+ * @param {Object} [scope]
+ * When onData callback is invoked,
+ * the JavaScript "this" keyword refers to this scope object.
+ * If no scope is provided, default is window.
+ * @param {*} [subscriberData]
+ * Client application provides this data, which is handed
+ * back to the client application in the subscriberData
+ * parameter of the onData callback function.
+ *
+ * @returns {String} Identifier representing the subscription.
+ *
+ * @throws {OpenAjax.hub.Error.BadParameters} if the topic is invalid
+ * (e.g.contains an empty token)
+ */
+OpenAjax.hub.subscribe = function(topic, onData, scope, subscriberData)
+{
+ // resolve the 'onData' function if it is a string
+ if ( typeof onData === "string" ) {
+ scope = scope || window;
+ onData = scope[ onData ] || null;
+ }
+
+ return OpenAjax.hub._hub.subscribe( topic, onData, scope, null, subscriberData );
+}
+
+/**
+ * Unsubscribe from a subscription.
+ *
+ * @param {String} subscriptionID
+ * Subscription identifier returned by subscribe()
+ *
+ * @throws {OpenAjax.hub.Error.NoSubscription} if no such subscription is found
+ */
+OpenAjax.hub.unsubscribe = function(subscriptionID)
+{
+ return OpenAjax.hub._hub.unsubscribe( subscriptionID );
+}
+
+/**
+ * Publish an event on a topic.
+ *
+ * @param {String} topic
+ * A valid topic string. MUST NOT include wildcards.
+ * @param {*} data
+ * Valid publishable data.
+ *
+ * @throws {OpenAjax.hub.Error.BadParameters} if the topic cannot be published
+ * (e.g. contains wildcards or empty tokens)
+ */
+OpenAjax.hub.publish = function(topic, data)
+{
+ OpenAjax.hub._hub.publish(topic, data);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Register the OpenAjax Hub itself as a library.
+OpenAjax.hub.registerLibrary("OpenAjax", "http://openajax.org/hub", "2.0", {});
+
+} // !OpenAjax.hub
Added: shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/crypto.js
URL: http://svn.apache.org/viewvc/shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/crypto.js?rev=1004309&view=auto
==============================================================================
--- shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/crypto.js (added)
+++ shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/crypto.js Mon Oct 4 16:21:18 2010
@@ -0,0 +1,244 @@
+/*
+
+ Copyright 2006-2009 OpenAjax Alliance
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+// SMASH.CRYPTO
+//
+// Small library containing some minimal crypto functionality for a
+// - a hash-function: SHA-1 (see FIPS PUB 180-2 for definition)
+// BigEndianWord[5] <- smash.crypto.sha1( BigEndianWord[*] dataWA, int lenInBits)
+//
+// - a message authentication code (MAC): HMAC-SHA-1 (RFC2104/2202)
+// BigEndianWord[5] <- smash.crypto.hmac_sha1(
+// BigEndianWord[3-16] keyWA,
+// Ascii or Unicode string dataS,
+// int chrsz (8 for Asci/16 for Unicode)
+//
+// - pseudo-random number generator (PRNG): HMAC-SHA-1 in counter mode, following
+// Barak & Halevi, An architecture for robust pseudo-random generation and applications to /dev/random, CCS 2005
+// rngObj <- smash.crypto.newPRNG( String[>=12] seedS)
+// where rngObj has methods
+// addSeed(String seed)
+// BigEndianWord[len] <- nextRandomOctets(int len)
+// Base64-String[len] <- nextRandomB64Str(int len)
+// Note: HMAC-SHA1 in counter-mode does not provide forward-security on corruption.
+// However, the PRNG state is kept inside a closure. So if somebody can break the closure, he probably could
+// break a whole lot more and forward-security of the prng is not the highest of concerns anymore :-)
+
+if ( typeof OpenAjax._smash == 'undefined' ) { OpenAjax._smash = {}; }
+
+OpenAjax._smash.crypto = {
+
+ // Some utilities
+ // convert a string to an array of big-endian words
+ 'strToWA': function (/* Ascii or Unicode string */ str, /* int 8 for Asci/16 for Unicode */ chrsz){
+ var bin = Array();
+ var mask = (1 << chrsz) - 1;
+ for(var i = 0; i < str.length * chrsz; i += chrsz)
+ bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
+ return bin;
+ },
+
+
+ // MAC
+ 'hmac_sha1' : function(
+ /* BigEndianWord[3-16]*/ keyWA,
+ /* Ascii or Unicode string */ dataS,
+ /* int 8 for Asci/16 for Unicode */ chrsz)
+ {
+ // write our own hmac derived from paj's so we do not have to do constant key conversions and length checking ...
+ var ipad = Array(16), opad = Array(16);
+ for(var i = 0; i < 16; i++) {
+ ipad[i] = keyWA[i] ^ 0x36363636;
+ opad[i] = keyWA[i] ^ 0x5C5C5C5C;
+ }
+
+ var hash = this.sha1( ipad.concat(this.strToWA(dataS, chrsz)), 512 + dataS.length * chrsz);
+ return this.sha1( opad.concat(hash), 512 + 160);
+ },
+
+
+ // PRNG factory method
+ // see below 'addSeed', 'nextRandomOctets' & 'nextRandomB64Octets' for public methods of returnd prng object
+ 'newPRNG' : function (/* String[>=12] */ seedS) {
+ var that = this;
+
+ // parameter checking
+ // We cannot really verify entropy but obviously the string must have at least a minimal length to have enough entropy
+ // However, a 2^80 security seems ok, so we check only that at least 12 chars assuming somewhat random ASCII
+ if ( (typeof seedS != 'string') || (seedS.length < 12) ) {
+ alert("WARNING: Seed length too short ...");
+ }
+
+ // constants
+ var __refresh_keyWA = [ 0xA999, 0x3E36, 0x4706, 0x816A,
+ 0x2571, 0x7850, 0xC26C, 0x9CD0,
+ 0xBA3E, 0xD89D, 0x1233, 0x9525,
+ 0xff3C, 0x1A83, 0xD491, 0xFF15 ]; // some random key for refresh ...
+
+ // internal state
+ var _keyWA = []; // BigEndianWord[5]
+ var _cnt = 0; // int
+
+ function extract(seedS) {
+ return that.hmac_sha1(__refresh_keyWA, seedS, 8);
+ }
+
+ function refresh(seedS) {
+ // HMAC-SHA1 is not ideal, Rijndal 256bit block/key in CBC mode with fixed key might be better
+ // but to limit the primitives and given that we anyway have only limited entropy in practise
+ // this seems good enough
+ var uniformSeedWA = extract(seedS);
+ for(var i = 0; i < 5; i++) {
+ _keyWA[i] ^= uniformSeedWA[i];
+ }
+ }
+
+ // inital state seeding
+ refresh(seedS);
+
+ // public methods
+ return {
+ // Mix some additional seed into the PRNG state
+ 'addSeed' : function (/* String */ seed) {
+ // no parameter checking. Any added entropy should be fine ...
+ refresh(seed);
+ },
+
+
+ // Get an array of len random octets
+ 'nextRandomOctets' : /* BigEndianWord[len] <- */ function (/* int */ len) {
+ var randOctets = [];
+ while (len > 0) {
+ _cnt+=1;
+ var nextBlock = that.hmac_sha1(_keyWA, (_cnt).toString(16), 8);
+ for (i=0; (i < 20) & (len > 0); i++, len--) {
+ randOctets.push( (nextBlock[i>>2] >> (i % 4) ) % 256);
+ }
+ // Note: if len was not a multiple 20, some random octets are ignored here but who cares ..
+ }
+ return randOctets;
+ },
+
+
+ // Get a random string of Base64-like (see below) chars of length len
+ // Note: there is a slightly non-standard Base64 with no padding and '-' and '_' for '+' and '/', respectively
+ 'nextRandomB64Str' : /* Base64-String <- */ function (/* int */ len) {
+ var b64StrMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+
+ var randOctets = this.nextRandomOctets(len);
+ var randB64Str = '';
+ for (var i=0; i < len; i++) {
+ randB64Str += b64StrMap.charAt(randOctets[i] & 0x3F);
+ }
+ return randB64Str;
+ }
+
+ }
+ },
+
+
+ // Digest function:
+ // BigEndianWord[5] <- sha1( BigEndianWord[*] dataWA, int lenInBits)
+ 'sha1' : function(){
+ // Note: all Section references below refer to FIPS 180-2.
+
+ // private utility functions
+
+ // - 32bit addition with wrap-around
+ var add_wa = function (x, y){
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+ }
+
+ // - 32bit rotatate left
+ var rol = function(num, cnt) {
+ return (num << cnt) | (num >>> (32 - cnt));
+ }
+
+ // - round-dependent function f_t from Section 4.1.1
+ function sha1_ft(t, b, c, d) {
+ if(t < 20) return (b & c) | ((~b) & d);
+ if(t < 40) return b ^ c ^ d;
+ if(t < 60) return (b & c) | (b & d) | (c & d);
+ return b ^ c ^ d;
+ }
+
+ // - round-dependent SHA-1 constants from Section 4.2.1
+ function sha1_kt(t) {
+ return (t < 20) ? 1518500249 :
+ (t < 40) ? 1859775393 :
+ (t < 60) ? -1894007588 :
+ /* (t < 80) */ -899497514 ;
+ }
+
+ // main algorithm.
+ return function( /* BigEndianWord[*] */ dataWA, /* int */ lenInBits) {
+
+ // Section 6.1.1: Preprocessing
+ //-----------------------------
+ // 1. padding: (see also Section 5.1.1)
+ // - append one 1 followed by 0 bits filling up 448 bits of last (512bit) block
+ dataWA[lenInBits >> 5] |= 0x80 << (24 - lenInBits % 32);
+ // - encode length in bits in last 64 bits
+ // Note: we rely on javascript to zero file elements which are beyond last (partial) data-block
+ // but before this length encoding!
+ dataWA[((lenInBits + 64 >> 9) << 4) + 15] = lenInBits;
+
+ // 2. 512bit blocks (actual split done ondemand later)
+ var W = Array(80);
+
+ // 3. initial hash using SHA-1 constants on page 13
+ var H0 = 1732584193;
+ var H1 = -271733879;
+ var H2 = -1732584194;
+ var H3 = 271733878;
+ var H4 = -1009589776;
+
+ // 6.1.2 SHA-1 Hash Computation
+ for(var i = 0; i < dataWA.length; i += 16) {
+ // 1. Message schedule, done below
+ // 2. init working variables
+ var a = H0; var b = H1; var c = H2; var d = H3; var e = H4;
+
+ // 3. round-functions
+ for(var j = 0; j < 80; j++)
+ {
+ // postponed step 2
+ W[j] = ( (j < 16) ? dataWA[i+j] : rol(W[j-3] ^ W[j-8] ^ W[j-14] ^ W[j-16], 1));
+
+ var T = add_wa( add_wa( rol(a, 5), sha1_ft(j, b, c, d)),
+ add_wa( add_wa(e, W[j]), sha1_kt(j)) );
+ e = d;
+ d = c;
+ c = rol(b, 30);
+ b = a;
+ a = T;
+ }
+
+ // 4. intermediate hash
+ H0 = add_wa(a, H0);
+ H1 = add_wa(b, H1);
+ H2 = add_wa(c, H2);
+ H3 = add_wa(d, H3);
+ H4 = add_wa(e, H4);
+ }
+
+ return Array(H0, H1, H2, H3, H4);
+ }
+ }()
+
+};
Added: shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/feature.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/feature.xml?rev=1004309&view=auto
==============================================================================
--- shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/feature.xml (added)
+++ shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/feature.xml Mon Oct 4 16:21:18 2010
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations under the License.
+-->
+<feature>
+ <name>org.openajax.hub-2.0.5</name>
+ <dependency>rpc</dependency>
+ <gadget>
+ <script src="OpenAjax-mashup.js"/>
+ <script src="iframe.js"/>
+ <script src="crypto.js"/>
+ </gadget>
+ <container>
+ <script src="OpenAjax-mashup.js"/>
+ <script src="iframe.js"/>
+ <script src="crypto.js"/>
+ </container>
+</feature>