Difference between revisions of "Inter Portlet Subscription/Notification Mechanism (Client side)"

From Gcube Wiki
Jump to: navigation, search
(How to use PageBus GWT Wrapper with gCube Portlets)
 
(4 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
<!-- CATEGORIES -->
 +
[[Category:Developer's Guide]]
 +
<!-- END CATEGORIES -->
 
How to make portlets in the same page use a Subscription/Notification Mechanism client side.
 
How to make portlets in the same page use a Subscription/Notification Mechanism client side.
  
Line 16: Line 19:
 
==How to use PageBus GWT Wrapper with gCube Portlets==
 
==How to use PageBus GWT Wrapper with gCube Portlets==
  
'''Step 1st: Download the file needed [[Media:Pagesbus_Files.zip | Click here‎]]'''
+
'''Step 1st: Download the latest jars from ETICS. The '.gwt-jsonmaker.jar' and the 'tibcopagebus4gwt.jar' '''
  
Once you extract the .zip file it contains three files, two .jar and one .js.
 
  
 
'''Step 2nd: add the two jar files in the build path of your GWT application'''
 
'''Step 2nd: add the two jar files in the build path of your GWT application'''
Line 27: Line 29:
 
<module>
 
<module>
 
   ...
 
   ...
  <inherits name="net.eliasbalasis.tibcopagebus4gwt.tibcopagebus4gwt"/>
+
<inherits name="net.eliasbalasis.tibcopagebus4gwt.tibcopagebus4gwt" />
  <inherits name="org.jsonmaker.gwt.Gwt_jsonmaker" />
+
<inherits name="org.jsonmaker.gwt.Gwt_jsonmaker" />
 
   ...
 
   ...
 
   ...
 
   ...
Line 37: Line 39:
 
==Set up your D4Science Portlet to use tibcopagebus4gwt GWT Wrapper==
 
==Set up your D4Science Portlet to use tibcopagebus4gwt GWT Wrapper==
  
Copy the file pagebus.js, which is in the .zip downloaded before(from [[Media:Pagesbus_Files.zip | here‎]]) to your portlet war/js folder
+
Copy the file pagebus.js, which can be downloaded from here [[Media:Pagesbus_Files.zip | here‎]] to your portlet war/js folder
 
e.g. <myportletproject>/war/js/pagebus.js
 
e.g. <myportletproject>/war/js/pagebus.js
  
Line 64: Line 66:
 
==How to use tibcopagebus4gwt GWT Wrapper with D4Science Portlets==
 
==How to use tibcopagebus4gwt GWT Wrapper with D4Science Portlets==
  
The main class you are going to use is the PageBusAdapter class, which is in the '''tibcopagebus4gwt-1.0.8.jar''' you downloaded before (in the .zip)
+
The main class you are going to use is the PageBusAdapter class which is included in the 'tibcopagebus4gwt.jar'
  
 
Assume now that Portlets containing GWT modules desire to communicate with the rest of the Portlets on the page. This is a task for PageBusAdapter which exposes PageBus functions as a GWT widget. Assume that the information to be communicated is represented with the following Java classes:
 
Assume now that Portlets containing GWT modules desire to communicate with the rest of the Portlets on the page. This is a task for PageBusAdapter which exposes PageBus functions as a GWT widget. Assume that the information to be communicated is represented with the following Java classes:
Line 132: Line 134:
 
   ...
 
   ...
 
   // publish a message with Person bean data
 
   // publish a message with Person bean data
   pageBusAdapter.PageBusPublish("org.gcube.portlets....client.Person", person, (Jsonizer)GWT.create(PersonJsonizer.class));
+
   pageBusAdapter.PageBusPublish("net.eliasbalasis.tibcopagebus4gwt.testsubscriber.client.Person", person, (Jsonizer)GWT.create(PersonJsonizer.class));
 
   ...
 
   ...
  
Line 153: Line 155:
 
    
 
    
 
   //Subscribe to message and associate subsequent receptions with custom subscriber data
 
   //Subscribe to message and associate subsequent receptions with custom subscriber data
   pageBusAdapter.PageBusSubscribe("org.gcube.portlets....client.Person", null, null, subscriberData, (Jsonizer)GWT.create(SubscriberDataJsonizer.class));
+
   pageBusAdapter.PageBusSubscribe("net.eliasbalasis.tibcopagebus4gwt.testsubscriber.client.Person", null, null, subscriberData, (Jsonizer)GWT.create(SubscriberDataJsonizer.class));
  
  
Line 178: Line 180:
 
   ...
 
   ...
 
   //unsubscribe from message. future publications of message will not trigger callback
 
   //unsubscribe from message. future publications of message will not trigger callback
   pageBusAdapter.PageBusUnsubscribe("org.gcube.portlets....client.Person");
+
   pageBusAdapter.PageBusUnsubscribe("net.eliasbalasis.tibcopagebus4gwt.testsubscriber.client.Person");
 
   ...
 
   ...
 
   ...
 
   ...
 
</pre>
 
</pre>
 
'''Javadoc for tibcopagebus4gwt it is located into the tibcopagebus4gwt-1.0.8.jar (in the .zip file you downloaded before)'''
 

Latest revision as of 16:26, 23 September 2014

How to make portlets in the same page use a Subscription/Notification Mechanism client side.

Pre-development Actions

Subscription/Notification Mechanism makes use of TIBCO PageBus™ (http://www.tibco.com/devnet/pagebus/default.jsp) which is an event and message bus implemented in JavaScript that enables disparate Ajax elements in a Web page to broadcast and listen for events and messages published on topic names.

For the ones developing portlets with GWT Wrapper exists for this Library, http://code.google.com/p/tibcopagebus4gwt/


How does PageBus work?

PageBus uses publish and subscribe APIs to send events and messages between components rather than get bogged down in point to point integrations between components that lead to unwieldy and less manageable code.

Pagebus Diagram

This diagram shows three Ajax widgets communicating with each other via the PageBus. Each widget has a file defining its visuals, a file controlling its behavior including the publish and subscribe calls to the PageBus, and a file that gets data from a service on the Web.

How to use PageBus GWT Wrapper with gCube Portlets

Step 1st: Download the latest jars from ETICS. The '.gwt-jsonmaker.jar' and the 'tibcopagebus4gwt.jar'


Step 2nd: add the two jar files in the build path of your GWT application

Once they two jar files are in the build path edit your GWT Application configuration file (file.gwt.xml). Add the following:

<module>
   ...
	<inherits name="net.eliasbalasis.tibcopagebus4gwt.tibcopagebus4gwt" />
	<inherits name="org.jsonmaker.gwt.Gwt_jsonmaker" />
   ...
   ...
   ...
 </module>

Set up your D4Science Portlet to use tibcopagebus4gwt GWT Wrapper

Copy the file pagebus.js, which can be downloaded from here here‎ to your portlet war/js folder e.g. <myportletproject>/war/js/pagebus.js

Now you need now to add a little modification to the Liferay Portlet header, the file is located under: <myportletproject>/war/WEB-INF/liferay-portlet.xml

add the following under the portlet element

<portlet>

   ......
   <header-portlet-javascript>/js/pagebus.js</header-portlet-javascript>
   .....

</portlet>


now you just need to copy the following into the <head> of your jsp page loading your portlet.

	<script type="text/javascript">
	     if(window.parent.PageBus) {
		window.PageBus = window.parent.PageBus;
	     }
	</script>

You are ready to use tibcopagebus4gwt.

How to use tibcopagebus4gwt GWT Wrapper with D4Science Portlets

The main class you are going to use is the PageBusAdapter class which is included in the 'tibcopagebus4gwt.jar'

Assume now that Portlets containing GWT modules desire to communicate with the rest of the Portlets on the page. This is a task for PageBusAdapter which exposes PageBus functions as a GWT widget. Assume that the information to be communicated is represented with the following Java classes:

package org.gcube.portltes...;
 ...
 // a Person bean class.
 class Person {
   ...
   public String getName(){...}
   public void setName(String name){...}
   ...
   public int getAge(){...}
   public void setAge(int age){...}
   ...
 }
 
 class SubscriberData {
   ...
   public String getHeader(){...}
   public void setHeader(String header){...}
   ...
   public String getBody(){...}
   public void setBody(String header){...}
   ...
 }

as part of the publish and subscribe calls to the PageBus. Not only Person beans must be translated to JavaScript objects before being passed around to PageBus but also JavaScripts objects passed through PageBus by other widgets must be translated to Person beans before the GWT module can use them.

PageBusAdapter makes uses marshaller implementations created using the the gwt-jsonizer library to perform the translation. Here is the gwt-jsonizer marshaller implementation for the Person bean.

 interface PersonJsonizer extends Jsonizer{}
 interface SubscriberDataJsonizer extends Jsonizer{}

Now you may wonder where is the marshalling/unmarshalling code? It is automatically created by the gwt-jsonizer GWT compiler hook the first time a bean class is accessed. The requirements of the gwt-jsonizer marshaller are:

  • The bean must be compliant with Java Beans specification (getters, setters, default constructors etc.)
  • The bean marshaller definition must be named after the respective bean class name with the Jsonizer suffix
  • Each and every bean property must contain a hint to the marshaller in the form of javadoc annotations.
    • The following annotations are currently supported:
      • jsonizer.transient The property in not translatable
      • jsonizer.propName 'prop' This property is named 'prop' in JavaScript
      • jsonizer.required If the property doesn't exist in respetive JavaScript version an exception will be thrown


Here is how a GWT module using PageBus functions would send notification (publishing beans to subscribers)


 package ...;
 import org.gcube.portlets......myapplication;
 ...
 public class MyGWTModule { 

   final PageBusAdapter pageBusAdapter = new PageBusAdapter();
   ...
   ...
   //create the Person bean data
   Person person = new Person();
   person.setName("Mario Rossi");
   person.setAge(29);
   ...
   // publish a message with Person bean data
   pageBusAdapter.PageBusPublish("net.eliasbalasis.tibcopagebus4gwt.testsubscriber.client.Person", person, (Jsonizer)GWT.create(PersonJsonizer.class));
   ...


Here is how a GWT module using PageBus functions would Subscribe to message and associate subsequent receptions with custom subscriber data


package ...;
 import org.gcube.portlets......myapplication;
 ...
 public class MyGWTModule { 

   final PageBusAdapter pageBusAdapter = new PageBusAdapter();
   SubscriberData subscriberData = new SubscriberData();
   subscriberData.setHeader("myHeader");
   subscriberData.setBody("myHeader");
  
   //Subscribe to message and associate subsequent receptions with custom subscriber data
   pageBusAdapter.PageBusSubscribe("net.eliasbalasis.tibcopagebus4gwt.testsubscriber.client.Person", null, null, subscriberData, (Jsonizer)GWT.create(SubscriberDataJsonizer.class));


   // register listener
   pageBusAdapter.addPageBusSubscriptionCallbackListener(
     new PageBusListener() {
       public void onPageBusSubscriptionCallback(PageBusEvent event) {
         // translate JavaScript message contents and subscriber data to their Java equivalents
         Person message = (Person)event.getMessage((Jsonizer)GWT.create(PersonJsonizer.class));
         SubscriberData subscriberData = (SubscriberData)event.getSubscriberData((Jsonizer)GWT.create(SubscriberDataJsonizer.class));
         ...
         ...
         ...
       }
     }
   );


Here is how a GWT module using PageBus functions would UnSubscribe to message

   ...
   ...
   //unsubscribe from message. future publications of message will not trigger callback
   pageBusAdapter.PageBusUnsubscribe("net.eliasbalasis.tibcopagebus4gwt.testsubscriber.client.Person");
   ...
   ...