<section title="Inter-Gadget Eventing" anchor="interGadgetEventing">
Â
  <t>The inter-gadget eventing feature, common known as "pub/sub", provides
  for loosely-coupled and asynchronous inter-gadget communication based
  on the <eref target="http://www.openajax.org/member/wiki/OpenAjax_Hub_2.0_Specification_Introduction">
  OpenAjax Hub 2.0</eref> specification.</t>
Â
  <t>The "pub/sub" feature provides:
   <list style="symbols">
    <t>An event hub, provided by the container and fully compliantÂ
    with OpenAjax Hub 2.0, that manages the subscription and publicationÂ
    of events,</t>
    <t>Methods for publishing and subscribing to events, and </t>
    <t>Mechanisms for declaratively specifying metadata within
    a gadget's XML definition relevant to publishing and subscribingÂ
    to events.</t>
   </list>
  </t>
Â
  <t>The process is straightforward:
   <list style="symbols">
    <t>First, a container that supports the "pub/sub" feature needs toÂ
    initialize the Hub and all default settings.</t>
    <t>Second, a container can bootstrap and simplify the connection ofÂ
    a gadget to the hub by registering an onLoad handler using theÂ
    gadgets.util.registerOnLoadHandler API. </t>
    <t>Third, once the Hub is initialized by the container, individual gadget's
    that declare support for the "pubsub-2" feature using either theÂ
    "Optional" or "Required" tag within the Gadget specificationsÂ
    "ModulePrefs" can use the provided JavaScript APIs to publishÂ
    events to the hub using "topics", or use the JavaScript APIs to
    subscribe to "topics" published by the Hub. When a gadget publishes
    and event to the Hub using a specific topic, all gadget's connectedÂ
    to that Hub and subscribed to the same topic will receive a copyÂ
    of the event.</t>
   </list>
  </t>
Â
  <t>A "topic" is a String value that conforms to the OpenAjax Hub 2.0Â
  specification's <eref target="http://www.openajax.org/member/wiki/OpenAjax_Hub_2.0_Specification_Topic_Names">Topic Name Rules</eref>.
  All topic names prefixed with "org.opensocial." are reserved for use by
  the OpenSocial specification. Developers MUST NOT use the "org.opensocial."
  prefix when defining their own topics.</t>
Â
  <section title="Initializing the Hub within the Container" anchor="ContainerExample">
Â
   <t>The following example illustrates a non-normative example how aÂ
   container could provide support for this feature.</t>
Â
   <list style="numbers">
    <t>Set default values:
     <artwork type="code">
// Create a pubsub settings object
gadgets.HubSettings = {};
Â
// Set default HubClient constructor params object
gadgets.HubSettings.params = {
 HubClient: {
  onSecurityAlert: function( alertSource, alertType ) {
   alert( "Gadget stopped attempted security breach: " + alertType );
   window.location.href = "about:blank"; // Forces container to see Frame Phish alert and probably close this gadget
  },
  scope: gadgetInstance
 } };
Â
// Set default onComplete function for HubClient.connect
gadgets.HubSettings.onConnected = function( hub, suc, err ) { };
      </artwork>
    </t>
    <t>
  Register an onLoad handler
  <t>An onLoad handler to actually create the HubClient and connect it
    to the ManagedHub. Delaying the HubClient creation and
    connection allows the gadget to override default values stored
    in gadgets.HubSettings. For example, IframeHubClient
    supports params properties such as seed, tokenLength and log,
    which are not set by default; and a gadget might need to
    override onSecurityAlert and/or scope, for which default values
    are provided. More importantly, the onComplete function for
    HubClient.connect usually sets up the gadget's subscriptions by
    calling gadgets.Hub.subscribe, or if the connection fails
    asynchronously, the onComplete function handles the error.</t>
      <artwork type="code">
// Register an onLoad handler
gadgets.util.registerOnLoadHandler( function() {
 try {
  // Create the HubClient.
  gadgets.Hub = new OpenAjax.hub.IframeHubClient( gadgets.HubSettings.params );
Â
  // Connect to the ManagedHub
  gadgets.Hub.connect( gadgets.HubSettings.onConnect );
Â
 } catch(e) {
  // TODO: error handling should be consistent with other OS gadget initialization error handling
 }
} );
      </artwork>
    </t>
   </list>
  </section>
Â
  <section title="Gadget Examples" anchor="GadgetExample">
Â
   <t>The following illustrates a non-normative example of a gadget thatÂ
   subscribes to a topic published by the Hub.</t>
Â
   <t>Note that, by default, all of the necessary defaults parameters
   on the underlying HubClient connected for the gadget were initialized
   when the gadget was loaded. If the gadget developer wishes to override theÂ
   default parameters to the HubClient constructor, it can do so byÂ
   setting values on gadgets.HubSettings as illustrated in the example.</t>
Â
   <figure><artwork type="code">
 <Module>
  <ModulePrefs title="Sample PubSub Subscriber" height="250">
   <Require feature="pubsub-2">
    <Param name="topics"><![CDATA[Â
     <Topic title="Random Number"Â
      name="org.apache.shindig.random-number"
      description="Subscribes to random number generator."Â
      type="number"
      subscribe="true"/>
     ]]></Param>
   </Require>
  </ModulePrefs>
  <Content type="html"><![CDATA[
   <script>
var subId;
Â
// Example of setting a parameter to the HubClient used by pubsub-2 feature.
gadgets.HubSettings.params.HubClient.onSecurityAlert = function(alertSource, alertType) {
 alert("SECURITY ERROR!");
 window.location.href = "about:blank";
};
Â
function callback(topic, data, subscriberData) {
 document.getElementById("output").innerHTML =
  "message : " + gadgets.util.escapeString(data + "") + "<br/>" +
  "received at: " + (new Date()).toString();
}
Â
function subscribe() {
 subId = gadgets.Hub.subscribe("org.apache.shindig.random-number", callback);
}
Â
function unsubscribe() {
 gadgets.Hub.unsubscribe(subId);
 document.getElementById("output").innerHTML = "";
}
   </script>
   <div>
    <input type="button" value="Subscribe" onclick="subscribe()"/>
    <input type="button" value="Unsubscribe" onclick="unsubscribe()"/>
   </div>
   <div id="output"></div>
  ]]></Content>
 </Module>
  </artwork></figure>
Â
   <t>Similarly, below is a non-normative example of a gadget thatÂ
   publishes events to the Hub:</t>
Â
   <figure><artwork>
 <Module>
  <ModulePrefs title="Sample PubSub Publisher" height="250">
   <Require feature="pubsub-2">
    <Param name="topics">
     <![CDATA[Â
      <Topic title="Random Number"Â
       name="org.apache.shindig.random-number"
       description="Publishes a random number."Â
       type="number"
       publish="true" />
    ]]></Param>
   </Require>
  </ModulePrefs>
  <Content type="html"><![CDATA[
   <script>
function publish() {
 var message = Math.random();
 gadgets.Hub.publish("org.apache.shindig.random-number", message);
 document.getElementById("output").innerHTML = message;
}
   </script>
   <div>
    <input type="button" value="Publish a random number" onclick="publish()"/>
   </div>
   <div id="output"></div>
  ]]></Content>
 </Module>
   </artwork></figure>
Â
  </section>
Â
  <section title="gadgets.Hub" anchor="gadgets.Hub">
   <section title="Method Details">
    <section title="publish" anchor="publish">
     <t>publish(topic, payload)</t>
     <t>Description: The publish method conforms to the semantics of the
     OA Hub. The OAHub embraces the notion that pubsub is anonymous and
     does not automatically include any information about the
     identification of the publishing gadget with the message. The
     following is an excerpt from their documentation.</t>
     <t>Parameters:
      <texttable align="left">
       <ttcol>Name</ttcol>
       <ttcol>Type</ttcol>
       <ttcol>Description</ttcol>
       <c>topic</c>
       <c>String</c>
       <c>A string that conforms to the rules defined above and by the
       OA Hub to name the channel that the payload will be deliverd on.
       Wildcards are NOT permitted.</c>
       <c>payload</c>
       <c>*</c>
       <c>It is permissible to publish any object. The payload MUST
       be serializable to JSON.</c>
      </texttable>
     </t>
     <t>See the <eref target="http://www.openajax.org/member/wiki/OpenAjax_Hub_2.0_Specification_Managed_Hub_APIs#OpenAjax.hub.Hub.prototype.publish">OpenAjax Hub 2.0 documentation</eref> for more information.</t>
     <section title="subscribe" anchor="subscribe">
      <t>subscribe(topic, callback [,scope [,onCompleteCallback [,subscriberData]]])</t>
      <t>Description: The subscribe method is used to indicate to the
      hub the topic from which the gadget is interested in receiving
      information. When information is published on the topic, the hub
      will invoke the callback method on the gadget. Since a gadget may
      have multiple subscriptions on the same topic, the subscribe
      method returns an opaque identifier that is used to uniquely
      identify the subscription. This identifier is used to unsubscribe
      to the topic. It is gadget developer's responsibility to manage
      this identifier.</t>
      <t>Parameters:
       <texttable align="left">
        <ttcol>Name</ttcol>
        <ttcol>Type</ttcol>
        <ttcol>Description</ttcol>
        <c>topic</c>
        <c>String</c>
        <c>A string that conforms to the rules defined above and by the OA Hub
        to name the channel that the payload will be deliverd on. Wildcards
        MAY be used.</c>
        <c>callback</c>
        <c>String</c>
        <c>A callback function to be executed when the tab is selected. The
        callback function will not be called until after the existing
        callstack has completed execution.</c>
        <c>scope</c>
        <c>object</c>
        <c>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.</c>
        <c>onCompleteCallback</c>
        <c>function</c>
        <c>Function invoked to tell the client application whether the
        subscribe operation succeeded or failed.</c>
        <c>subscriberData</c>
        <c>*</c>
        <c>Client application provides this data, which is handed back to the
        client application in the subscriberData parameter of the onData
        callback function.</c>
       </texttable>
      </t>
      <t>Returns:
       <texttable align="left">
        <ttcol>Type</ttcol>
        <ttcol>Description</ttcol>
        <c>String</c>
        <c>An opaque subscription identifier. This identifier is an arbitrary
        ID string that is unique within this Hub instance</c>
       </texttable>
      </t>
      <t>See the <eref target="http://www.openajax.org/member/wiki/OpenAjax_Hub_2.0_Specification_Managed_Hub_APIs#OpenAjax.hub.Hub.prototype.subscribe">OpenAjax Hub documentation</eref> for
      more information</t>
     </section>
     <section title="unsubscribe" anchor="unsubscribe">
      <t>unsubscribe(subscriptionId)</t>
      <t>Description: This method is used to remove a subuscription for a
      gadget from the hub. The unsubscribe function immediately throws an
      exception if there is no subscription with the specified subscription
      ID. Otherwise, unsubscribe immediately deactivates the subscription.
      </t>
      <t>Parameters:
       <texttable align="left">
        <ttcol>Name</ttcol>
        <ttcol>Type</ttcol>
        <ttcol>Description</ttcol>
        <c>subscriptionId</c>
        <c>String</c>
        <c>The subscriptionId is the opaque string that is returned from the
          subscribe(...) method.</c>
       </texttable>
      </t>
      <t>See the <eref target="http://www.openajax.org/member/wiki/OpenAjax_Hub_2.0_Specification_Managed_Hub_APIs#OpenAjax.hub.Hub.prototype.unsubscribe">OpenAjax Hub documentation</eref> for
      more information.</t>
     </section>
    </section>
    <section title="Other Methods" anchor="OtherMethods">
     <t>The 'gadgets.Hub' object is an instance of IframeHubClient and supports some additional methods.
     Please see the <eref target="http://www.openajax.org/member/wiki/OpenAjax_Hub_2.0_Specification_Managed_Hub_APIs#OpenAjax.hub.IframeHubClient">OpenAjax Hub documentation</eref> for more information.</t>
    </section>
   </section>
  </section>
Â
  <section title="Wiring Metadata">
Â
   <t>As illustrated by the previous example gadgets, the "pub/sub" featureÂ
   provides a means of allowing gadget developers to declaratively describe
   the topics their gadget's support directly within the feature declaration
   within the "ModulePrefs" element.</t>
Â
   <figure><preamble>For example:</preamble>
   <artwork>
 <Module>
  <ModulePrefs title="Sample PubSub Publisher" height="250">
   <Require feature="pubsub-2">
    <Param name="topics">
     <![CDATA[Â
      <Topic title="Random Number"Â
       name="org.apache.shindig.random-number"
       description="Publishes a random number."Â
       type="number"
       publish="true" />
    ]]></Param>
   </Require>
  </ModulePrefs>
  ...
 </Module>
   </artwork></figure>
Â
   <t>When gadgets use the <Topic> element, containers are able
   to "wire" gadgets together either automatically or via a user interface
   that allows a user to connect gadgets that publish events to a given
   topic to gadgets that subscribe to those events.</t>
Â
   <t>The <Topic> element has the following attributes:</t>
   <texttable align="left">
     <ttcol>Attribute</ttcol>
     <ttcol>Type</ttcol>
     <ttcol>Usage</ttcol>
     <ttcol>Description</ttcol>
     <c>name</c>
     <c>String</c>
     <c>Required</c>
     <c>
     The dot-delimited topic name, e.g. "org.example.randomNumber". This
     name follows the rules defined in the <eref target="http://www.openajax.org/member/wiki/OpenAjax_Metadata_1.0_Specification_Widget_Metadata#topic_element_name_attribute">OpenAjax Widget Metadata
     specification</eref>. Developers of gadgets MAY allow the @name attribute to be ovveridden using user preference variables. See <xref target="usingVariablesForNameAttribute">Using Varuables for @name</xref></c>
Â
     <c>type</c>
     <c>String</c>
     <c>Optional</c>
     <c>Type name for the event's payload data. When not specificed, any
     type wil be allowed. See <xref target="EventDataTypes">Event Data Types</xref>.</c>
Â
     <c>title</c>
     <c>String</c>
     <c>Optional</c>
     <c>Title for this type of event that is appropriate for a non-technical reader. When not specified, the value of the "name" attribute will be used.</c>
Â
     <c>publish</c>
     <c>boolean</c>
     <c>Optional</c>
     <c>Indicates if the gadget publishes events on this topic. The default value is "false".</c>
Â
     <c>subscribe</c>
     <c>boolean</c>
     <c>Optional</c>
     <c>Indicates if the gadget subscribes to events that are published on this topic. The default value is "false".</c>
Â
     <c>description</c>
     <c>String</c>
     <c>Optional</c>
     <c>
     The textual description of the gadget's publish or subscribe
     endpoint.
     This can be used as an indication of the gadget's behavior.
     Consider a gadget that subscribes to a topic "com.example.address".
     The description migh read, "When this gadget receives an event on the com.example.address
     topic, it displays mass transit options within 10km of the address received as the event payload."</c>
Â
     <c>aboutUrl</c>
     <c>String</c>
     <c>Optional</c>
     <c>
     A URL pointing to a resource that provides more extensive
     descriptive information than can be provided in the description
     attribute.</c>
   </texttable>
Â
   <section title="Using Variables for @name" anchor="usingVariablesForNameAttribute">
    <t>In the absence of a specific standard for events within a given
    domain, it is inevitable that different groups of developers,
    working in different niches on similar problems, will use different
    topic naming schemes for what is essentially the same event. While
    some developers in a domain may eventually consolidate around a
    standard set of topic names, it's also inevitable that installed
    bases, legacy implementations, politics, requirement to integrate
    with third party gadgets from other domains, schedule constraints
    and other factors will ensure that once a topic space becomes
    balkanized, it will remain that way for a long time.</t>
    <t>It is important that the specification offer a mechanism that allows
    developers to bridge simple mismatches between gadgets. It is
    important that gadget developers use this mechanism where possible.
    This will maximize the reusability of gadgets -- a major goal.</t>
Â
    <figure><preamble>The following is an example showing the use ofÂ
    variable substituion in the definition of the @name attribute.</preamble>
    <artwork xml:space="preserve">
 <Require feature="pubsub-2">
  <Param name="topics"><![CDATA[
    <Topic title="Selected Location" name="__UP_location__"
       description="The currently selected location" type="http://nsgs.gov/geo#Place"
       publish="false" subscribe="true" aboutUrl="http://nsgs.gov">
   </Topic>
   <!-- etc. for other topics -->
  ]]></Param>
 </Require>
     </artwork></figure>
   </section>
Â
   <section title="Event Data Types" anchor="EventDataTypes">
    <t>The OpenAjax Hub has a predefined set of identifiers that are usedÂ
    to indicate the data type. Tooling and runtime container code can useÂ
    this to infer information about the messages being published
    as well as the parameters a gadget expects to receive when it
    subscribes to a topic.</t>
    <t>The data types provided by the OpenAjax Hub are "built in". These
    are referred to as the OpenAjax common types, and they require no
    namespace qualifier. When a type other than an OpenAjax common type
    is used, it MUST contain a namesake qualifier. The namespace should
    conform to reverse DNS rules. The namespace org.opensocial.* MUST NOT be
    used and is reserved for types defined by this specification,Â
    e.g. social data types.</t>
Â
    <texttable align="left">
     <ttcol>Type Name</ttcol>
     <ttcol>Comments</ttcol>
     <c>string</c>
     <c>ECMAScipt string</c>
     <c>number</c>
     <c>ECMAScipt number </c>
     <c>boolean</c>
     <c>ECMAScipt boolean </c>
     <c>array</c>
     <c>ECMAScipt array, e.g. [ 1, 1, 2, 3, 5, 8 ]. The element type/s are not specified when the generic "array" type is used.</c>
     <c>object *</c>
     <c>ECMAScipt object, e.g. { foo: "bar", baz: "boo" }. The specifics of the object are not specified when the generic "object" type is used.</c>
     <c>null *</c>
     <c>ECMAScipt null</c>
     <c>length *</c>
     <c>Any CSS length value <span style="color:red"> Howard 2009.11.10: CSS version?</span></c>
     <c>color *</c>
     <c>Any CSS color value</c>
     <c>id</c>
     <c>ID value - probably not useful for OpenSocial Gadgets, but might as well keep the two specs in sync</c>
     <c>class *</c>
     <c>zero of more CSS class names, separated by spaces</c>
     <c>style *</c>
     <c>a string that could be used as value for a 'style' attribute</c>
     <c>url</c>
     <c>A URL <span style="color:red"> Howard 2009.11.09: Do we want "uri" also?</span></c>
     <c>html</c>
     <c>A fragment of HTML markup.</c>
     <c>countrycode *</c>
     <c>A string that represents an [http://www.iso.org/iso/country_codes/iso_3166_code_lists.htm A3 ISO 3166 country code].</c>
     <c>languagecode *</c>
     <c>A string that represents an [http://www.loc.gov/standards/iso639-2/php/code_list.php ISO 639-2 language code].</c>
     <c>email</c>
     <c>A string that represents an e-mail address.</c>
     <c>person</c>
     <c>A string that holds a person's name.</c>
     <c>postalcode</c>
     <c>A string that represents a postal code.</c>
     <c>phone</c>
     <c>A string that represents a phone number.</c>
     <c>date *</c>
     <c>A string that represents a date. MUST be expressed using the "Date Time String Format" defined in the [http://www.ecmascript.org/docs/tc39-2009-043.pdf ECMAScript5 specification] using one of the date-only forms. For example: "2009-12-15"</c>
     <c>time *</c>
     <c>A string that represents a time of day. MUST be expressed using the "Date Time String Format" defined in the [http://www.ecmascript.org/docs/tc39-2009-043.pdf ECMAScript5 specification] using one of the time-only forms. For example: "18:45:00Z" or "10:26:24-05:00"</c>
     <c>timestamp *</c>
     <c>A string that represents a date and time of day. MUST be expressed using the "Date Time String Format" defined in the [http://www.ecmascript.org/docs/tc39-2009-043.pdf ECMAScript5 specification]. For example: "2009-12-15:18:45.000Z"</c>
     <c>duration *</c>
     <c>A string that represents a duration. MUST have format "PYYYY-DDDThh:mm:ss.fff". For example, "P0400-152T20:45:33.123" means "400 years, 152 days, 20 hours, 45 minutes, 33.123 seconds, while "P0003-000T01:56:22.000" means "3 years, 1 hour, 56 minutes and 22.000 seconds." (Must use this one variant defined in the ISO 8601 standard). </c>
     <c>*</c>
     <c>Asterisk, or missing type attribute, means "any datatype"</c>
    </texttable>
   </section>
  </section>
 </section>