In this chapter, we present how you can use data from social networks such as Google+, Facebook and Twitter in your portlets. Naturally, the kind of data accessible via public APIs varies among the providers. The title of this chapter Using Data from is thought to suggest that it is possible to read data from social networks, however, as you will see below, it is also possible to write some data in case of Facebook.
This section cites code from Social Portlets example project from the Quickstarts Collection. There is a portlet for showing last few statuses from your Facebook Wall, portlet for showing list of your circles (and who is in) on Google+ or portlet for showing your user account details from Twitter.
Firstly, you may want to read Starting a Portlet Project, Standard Portlet Development (JSR 286) and CDI Portlet Development before you proceed.
Secondly, you need to configure your GateIn Portal with particular OAuth provider as described in OAuth documentation.
Finally, the given portal user needs to have the OAuth access token saved as part of his User Profile in GateIn Portal. To retrieve access token the user needs either:
Authenticate or register into GateIn Portal with particular OAuth provider (social network), or
Link his account with OAuth Provider - this can be done through the dedicated tab of User Info screen in GateIn Portal UI or it also can be achieved programmatically from portlets.
Once the user has an OAuth access token saved in his GateIn Portal profile, it can be used to call various operations in the particular social network.
To retrieve the access token of the current user, we are leveraging OAuthProvider API. In Social Portlets Quickstart, there is OAuthProviderFilter portlet filter. Its main task is to retrieve access token of the current user for a given social network and save this access token into the RequestContext bean. Alternative flows result in one of the following messages:
OAuth provider is not enabled in portal configuration
User is not logged
User's access token does not exists
User's access token is invalid or expired
These messages are presented by error.jsp or token.jsp. Note that in case that the access token is unavailable or invalid, the token.jsp will show a link, which can be followed by the user to link his GateIn Portal account with the given social network. Once linked, user will gain the access token.
The message when access token is not available
The configuration of OAuthPortletFilter in portlet.xml looks like this:Code Snippet error: Unable to retrieve the URL: https://github.com/gatein/gatein-portal-quickstart/raw/master/social-portlets/src/main/webapp/WEB-INF/portlet.xml status code: 404.
The mapping looks like this:Code Snippet error: Unable to retrieve the URL: https://github.com/gatein/gatein-portal-quickstart/raw/master/social-portlets/src/main/webapp/WEB-INF/portlet.xml status code: 404.
The above listing says that all portlets with the name starting with "Facebook" are handled by this filter. There is a similar configuration and mapping there also for Google+ and Twitter.
All portlets in Social Portlets Quickstart extend the AbstractSocialPortlet. It is a subclass of the standard portlet API's GenericPortlet. It contains some basic functionality and helper methods useful for all social portlets. One of them is handling the action to redirect to the Social login:Code Snippet error: Unable to retrieve the URL: https://github.com/gatein/gatein-portal-quickstart/raw/master/social-portlets/src/main/java/org/gatein/security/oauth/portlet/AbstractSocialPortlet.java status code: 404.
If customScope is null GateIn Portal will ask just for scopes configured in configuration.properties. Otherwise, the GateIn Portal will ask for this scope in addition to scopes from configuration.properties. This allows portlets to ask for more scopes then just scopes from configuration.properties.
Example: In configuration.properties, Facebook is enabled only with the default scope email as decribed Facebook integration docs. But in FacebookStatusUpdatePortlet, we want to be able to publish messages on Facebook Wall. For this purpose, an access token with scope publish_message will be necessary. Therefore, before the user will be able to publish a message on his Facebook Wall, the portlet will inform him that the present scope is insufficient and ask him to widen the scope as shown below
Message when access token doesn't have sufficient scope
Following the link will start a new OAuth2 flow: the user will be redirected to Facebook and where he will be asked to permit the publish_message scope. After that, the user will be able to publish messages. Hence, portlets can ask for wider scope on demand in cases when they really need it.
Note that we use CDI to store the access token. The RequestContext class is annotated as @RequestScoped. Therefore, each portlet contains only logic specific to its purpose and it does not need to care for retrieving the access token.
There are three portlets to demonstrate a basic integration with Facebook:
FacebookUserInfoPortlet – a simple portlet showing some details of the the current user's profile on Facebook, such as first name, last name, username, e-mail and the picture of the user.
FacebookFriendsPortlet – this is a more advanced portlet showing friends of the current user and their pictures. It also supports pagination (only 10 friends are on screen, but you can switch to different page size to see more friends). When clicking a friend, the portlet displays the last few status messages from the given friend's Facebook Wall.
FacebookStatusUpdatePortlet – Portlet, which is able to publish messages to the Wall of the current user.
All 3 portlets leverage the 3rd party library RestFB, which provides the capability to send requests to Facebook Graph API and convert JSON responses to plain Java objects (POJOs). To decouple logic from the UI and handle error situations, we prepared a helper class FacebookClientWrapper. It offers a bunch of methods to retrieve objects from Facebook Graph API and it converts them to POJOs or beans defined by us. Those can then be dispatched by PortletRequestDispatcher to JSP pages which handle the HTML markup rendering.
Our portlets are using just a small subset of Facebook Graph API. You are free to use the whole spectrum of Graph API operations in your own portlets. The complete documentation of Graph API is available on Facebook Developers.
There are three example portlets for showing integration with Google+:
GoogleUserInfoPortlet – a simple portlet which shows some details about the current user from Google+, such as first name, last name, e-mail and the picture of the user. See https://developers.google.com/accounts/docs/OAuth2WebServer#callinganapi for more details.
GoogleFriendsPortlet – a simple portlet for displaying Google+ friends and their photos. It supports pagination (only 10 friends are displayed on screen each time). See https://developers.google.com/+/api/latest/people/list for details.
GoogleActivitiesPortlet – a simple portlet for displaying latest activities from Google+ Stream (the same thing is called "Wall" on Facebook) of the current user. See https://developers.google.com/+/api/latest/activities/list for details.
Those portlets leverage Google SDK libraries. GoogleUserInfoPortlet leverages Google OAuth2 API library and it uses an Oauth2 object to call the operation. GoogleFriendsPortlet and GoogleActivitiesPortlet leverage Google+ API library and they use Plus object to call the operations. Portlets have available access token and they obtain needed object via call to oauthProvider.getAuthorizedAPIObject as described in OAuth section of Portal API.
There is only one simple portlet for Twitter: TwitterPortlet. It shows some details about the current user, such as his picture, his last tweet, number of followers, etc.
TwitterPortlet leverages Twitter4J library to interact with Twitter. Given that the access token is available, the portlet demonstrates how to obtain the Twitter client object from Twitter4J library through calling oauthProvider.getAuthorizedAPIObject() as described in OAuth section of the Portal API documentation.
In pom.xml file of our Social Portlets Quickstart, we need to declare dependencies on JSR 286 portlet API, GateIn Portal API and CDI API:Code Snippet error: Unable to retrieve the URL: https://github.com/gatein/gatein-portal-quickstart/raw/master/social-portlets/pom.xml status code: 404.
We also need to declare dependencies on 3rd party libraries to be able to access the public APIs of Facebook, Twitter and Google+:Code Snippet error: Unable to retrieve the URL: https://github.com/gatein/gatein-portal-quickstart/raw/master/social-portlets/pom.xml status code: 404.
You may have noticed that com.restfb dependency is not declared as provided. This is because this library is not used by GateIn Portal itself, and therefore it is not bundled therein as well. We need to provide it in our WAR ourselves. Dependencies on Twitter4J and Google API libraries are provided by GateIn Portal and there is no need to package them inside our portlet WAR.
This file is specific for JBoss AS7 and JBoss EAP. In this file, dependencies on JBoss AS7/EAP modules are declared which are required by our portlet application.Code Snippet error: Unable to retrieve the URL: https://github.com/gatein/gatein-portal-quickstart/raw/master/social-portlets/src/main/webapp/WEB-INF/jboss-deployment-structure.xml status code: 404.
Modules org.twitter4j and com.google.apis are part of GateIn Portal JBoss AS7 packaging and they contain the 3rd party libraries from Google+ and Twitter.
The presence of beans.xml file activates CDI for the application. There is nothing useful in it.Code Snippet error: Unable to retrieve the URL: https://github.com/gatein/gatein-portal-quickstart/raw/master/social-portlets/src/main/webapp/WEB-INF/beans.xml status code: 404.
It contains declaration of all social portlets. Very important is also declaration of OAuthPortletFilter and it's filter mapping, which is described here.
It just contains the <display-name>.
Declaration of CSS files used by our portlets. For more information, please refer to Skinning the portal#Create New Portlet skins.
After having understood the parts relevant to you from the above, it is time to build and deploy the project, import the portlets and add some of them to a page so that you can test their functionality.