JBoss Community Archive (Read Only)

GateIn Portal 3.8

Portal API

The Portal API provides access to retrieving, creating and deleting Portal Sites and Portal Pages. It also provides full support for the navigation and nodes associated with a site, which can be very useful for e.g. creating custom navigation portlets. This section only gives some basic examples of the API usage. For full documentation of all features available, please refer to the Javadoc.

PortalRequest and Portal

The PortalRequest is the entry point to the API. It provides access to the Portal, and it also provides access to information associated with the current request (such as the logged in user and the page being requested).

The example below shows how to use the PortalRequest to obtain an instance of the Portal:

Portal portal = PortalRequest.getInstance().getPortal();

Site

A Site is comprised of a set of pages, navigation definitions, and can be assigned a unique skin. There are three different types of sites: standard sites, group spaces and user dashboards.

Retrieving Sites

A specific site can be retrieved by its SiteId. The SiteId is constructed by passing either the name for a standard site, the group for a group space or the user for a user dashboard. Alternatively it can be constructed by passing the SiteType and name.

Example of Retrieving Sites is Shown below:

Site standardSite = portal.getSite(new SiteId("classic"));
Site groupSpace = portal.getSite(new SiteId(new Group("platform", "administrators")));
Site userDashboard = portal.getSite(new SiteId(new User("john")));

It is also possible to query for sites using the SiteQuery. The SiteQuery supports filtering, sorting and pagination when querying for sites.

The example below finds standard sites that a user has access permissions to, limited to the 10 first results:

SiteQuery.Builder qb = new SiteQuery.Builder();

qb.withSiteTypes(SiteType.SITE).withPagination(0, 10).withFilter(new Filter<Site>() {
    public boolean accept(Site site) {
        return portal.hasPermission(user, site.getAccessPermission());
    }
});

List<Site> sites = portal.findSites(qb.build());

The default number of results to return is 15. Which means that if no pagination is set while building the query, the maximum number of results will be 15. So be sure to set the correct pagination while querying.

Creating a Site

To create a site, first create a new site through the Portal, then set the configuration for the site (such as localized display names and skin), and finally saved it using the Portal.

The example below creates a new standard site with the name mysite and a non-localized display name:

Site site = portal.createSite(new SiteId("foo"));
site.setDisplayName("My Site");
portal.saveSite(site);

The site is not visible (or persisted) until saveSite is invoked.

Setting Attributes for a Site

It is possible to change attributes for the site, supported attributes are:

  • sessionAlive - sets if a session is kept alive or not. Valid values are "onDemand", "always", and "never" with the default being "onDemand"

  • showPortletInfo - sets if the info bar is shown by default when adding applications to pages, the default is 'false'

The attributes are set by using the associated Key, the example below changes the sessionAlive attribute:

site.getAttributes().put(Site.AttributeKeys.SESSION_BEHAVIOR, "always");

Setting permissions for a site

Associated with a site is an access permission and an edit permission, which controls what users and groups are allowed to access and edit the site respectively.

The example below makes a site accessible by everyone, but only editable by users in the /platform/administrators group:

site.setAccessPermission(Permission.everyone());
site.setEditPermission(Permission.any("platform", "administrators"));

portal.saveSite(site);

The changed permissions do not take affect until saveSite is invoked.

Deleting a Site

A site is deleted by invoking removeSite on the Portal.

Navigation

A Navigation for a site is retrieved from the Portal and allows accessing the node tree that represents the navigation entries for the site. There is a special root node which is not directly part of the navigation, but it's the parent of the first level of navigation entries. As the root node is not meant to be displayed it doesn't have a display name.

The example below retrieves the Navigation for the classic site:

Navigation navigation = portal.getNavigation(new SiteId("classic"));

Retrieving Navigation Nodes

When retrieving navigation nodes, it is possible to either retrieve the root node, or a specific node in the hierarchy. It is also possible to control which if any of the children are loaded.

This example below shows a very simple navigation portlet that displays the top level of entries in the navigation menu:

public void doView(RenderRequest request, RenderResponse response) throws IOException {
    PrintWriter pw = response.getWriter();
    Navigation navigation = PortalRequest.getInstance().getNavigation();

    pw.print("<ul>");
    for (Node n : navigation.getRootNode(Nodes.visitChildren())) {
        pw.printf("<li><a href='%s'>%s</a></li>", n.getURI(), n.getDisplayName());
    }
    pw.print("</ul>");
}

To retrieve a specific node in the tree it's retrieved by specifying the NodePath to the node:

Node node = navigation.getNode(NodePath.path("home"));

It is important to note that when you retrieve a node, it actually represents a tree of nodes and all operations (i.e. save, refresh) act on that entire tree. So if you retrieve the root node and it's children and make modifications to two children but only perform a save on one child, the other child will be saved since the save operation acts on the entire node tree.

NodeVisitor

When retrieving navigation nodes, especially if there is a large number of nodes it is important to limit how many levels of nodes are retrieved. This is controlled by using either one of the built in NodeVisitor from the Nodes class, or by implementing your own NodeVisitor. The Nodes class contains the following visitors:

  • visitAll - loads all nodes

  • visitChildren - loads the immediate children

  • visitNone - loads only the node

  • visitNodes(int) - loads a specified depth of descendants

The example below retrieves the root node and 2 levels of nodes:

Node rootNode = navigation.getRootNode(Nodes.visitNodes(2));

To find out if the children for a node is loaded use the isChildrenLoaded method. For example navigation.getRootNode(Nodes.visitChildren()).isChildrenLoaded() returns true while navigation.getRootNode(Nodes.visitNone()).isChildrenLoaded() returns false.

Filtering Navigation Nodes

Nodes support a filtering mechanism which makes it simple to display only nodes that have certain properties. For example when creating a navigation portlet it is common to only want to display visible nodes where the user has access to view the page:

Node filtered = node.filter().showDefault();

There is a number of methods available to control what nodes are displayed, and they all start with show. showDefault is a short-cut for showVisible().showHasAccess(PortalRequest.getInstance().getUser()).

It is also possible to add a custom filter. The example below displays uses a custom filter to only nodes with a display name that starts with "A":

Node filtered = root.filter().show(new Filter<Node>() {
    public boolean accept(Node node) {
        return node.getDisplayName().startsWith("A");
    }
});

Creating a Navigation Node

To create a node, first retrieve the parent node you want to add it to, and invoke the addChild method on the parent node. Then set the configuration for the node (such as the display name and the page it should link to) and finally save it using saveNode on Navigation.

The example below creates a node as a child of the home node:

Node home = navigation.getNode(NodePath.path("home"));
Node child = home.addChild("mynode");
child.setDisplayName("My Node");
child.setPageId(new PageId("classic", "mypage"));
navigation.saveNode(home);

The node is not visible (or persisted) until saveNode is invoked.

Navigation Node Visibility

Nodes can be visible, hidden or only visible at a specified publication date. By default a new node is visible.

A node can be hidden with node.setVisibility(false), or only shown until a specific date with node.setVisibility(PublicationDate.endingOn(date)) (it is also possible to set a starting date, or both). The changes to the node visiblity is not shown until saveNode is invoked on the Portal.

Localization

The display name for a node supports localization. The example below sets the display name for a node in English and French:

LocalizedString localizedString = node.getDisplayNames();
localizedString.setLocalizedValue(Locale.ENGLISH, "My node");
localizedString.setLocalizedValue(Locale.FRENCH, "Mon noeud");
node.setDisplayNames(localizedString);

navigation.saveNode(node);

Deleting a Navigation Node

A node is deleted by removing it from the parent node. The example below removes the child with the name mynode:

node.removeChild("mynode");
navigation.saveNode(node);

The node is not removed until saveNode is invoked.

Moving a Navigation Node

A node can be moved to a different parent, or it can be moved to a different index in the same parent. When moving to a different parent the new parent is required to be in the same tree.

The example belows moves a node from one parent to another:

root.getNode("parent1", "child").moveTo(root.getNode("parent2"));
navigation.saveNode(root);

Or to move a node to a different index in the same parent:

root.getNode("parent", "child").moveTo(0);
navigation.saveNode(root);

A more convinient way to sort children for a parent is to use the sort method on the parent, for example to sort the children of the root node by their display names:

root.sort(new Comparator<Node>() {
    public int compare(Node o1, Node o2) {
        return o1.getDisplayName().compareTo(o2.getDisplayName());
    }
});
navigation.saveNode(root);

As with creating a node, the changes are not visible (or persisted) until saveNode is invoked.

Page

Portal Page aggregates content from one or more Portlets - see Portlet Primer.

Retrieving Pages

A specific page can be retrieved by its PageId. The PageId is constructed by passing either the name for a standard site, the group for a group space or the user for a user dashboard, and the name of the page. Alternatively it can be constructed by passing the SiteId and name of the page.

Example of retrieving specific pages is shown below:

Page standardSitePage = portal.getPage("classic", "home");
Page groupSpacePage = portal.getSite(new Group("platform", "administrators"), "grouppage");
Page userDashboardPage = portal.getSite(new User("john", "johnspage"));

It is also possible to query for pages using the PageQuery. The PageQuery supports filtering, sorting and pagination when querying for pages.

The example below finds pages with a display name that starts with "A":

PageQuery.Builder qb = new PageQuery.Builder();

qb.withSiteType(SiteType.SITE).withFilter(new Filter<Page>() {
    public boolean accept(Page page) {
        return page.getDisplayName().startsWith("A");
    }
});

List<Page> pages = portal.findPages(qb.build());

Creating a Page

To create a page, first create a new page through the Portal, then set the configuration for the page (such as localized display names), and finally saved it using the Portal.

The example below creates a new page in the classic site with the name mypage and a non-localized display name:

Page page = portal.createPage(new PageId("classic", "mypage"));
page.setDisplayName("My Page");
portal.savePage(page);

The page is not visible (or persisted) until portal.savePage is invoked.

Setting Permissions for a Page

Associated with a page is an access permission and an edit permission, which controls what users and groups are allowed to access and edit the page respectively.

The example below makes a page accessible to everyone, but only editable by users in the /platform/administrators group:

page.setAccessPermission(Permission.everyone());
page.setEditPermission(Permission.any("platform", "administrators"));

portal.savePage(page);

The changed permissions do not take affect until savePage is invoked.

Page Composition

This feature is experimental. Please send us feedback using #gatein IRC channel at freenode.net or GateIn Portal forums.

Since GateIn Portal 3.8, child objects such as Applications and Containers can be added to a Page. Both Applications and Containers represent blocks of content visually present in the page.

There are three types of applications as defined in ApplicationType: Portlet, WSRP Portlet and Gadget.

Containers main responsibility is to provide a template that renders its children in the user interface. The Portal API provides Container with two basic templates: one for rendering children in rows and one for rendering children in columns. Refer to the example below to learn how to access them. Children of a Container can be other Containers or Applications.

A basic Page containing just a single Application can be composed as follows:

PageBuilder pageBuilder = portal.newPageBuilder();
Application calculator = portal.getApplicationRegistry().getApplication("Gadgets/Calculator");
Page page = pageBuilder.child(calculator).siteName("classic").siteType("portal").name("awesome").build();

Here is a more complex example using two column containers nested in a row container:

PageBuilder pageBuilder = portal.newPageBuilder();
ApplicationRegistry appRegistry = portal.getApplicationRegistry();
Page page = pageBuilder
        .newRowsBuilder()
            .newColumnsBuilder()
                .child(appRegistry.getApplication("Gadgets/Calculator"))
                .child(appRegistry.getApplication("Gadgets/rssAggregator"))
            .buildToParentBuilder()

            .newColumnsBuilder()
                .child(appRegistry.getApplication("Gadgets/Calendar"))
                .child(appRegistry.getApplication("Gadgets/Todo"))
            .buildToParentBuilder()

        .buildToTopBuilder()
        .siteName("classic")
        .siteType("portal")
        .name("awesome_" + UUID.randomUUID().toString())
        .displayName("Awesome page")
        .showMaxWindow(false)
        .accessPermission(Permission.everyone())
        .editPermission(Permission.any("platform", "administrators"))
        .moveAppsPermission(Permission.everyone())
        .moveContainersPermission(Permission.everyone())
        .build();

Note that the PageBuilder.build() method returns a Page object, which can be used as an argument for Portal.savePage() method to persist the Page. More information can be found in Javadocs.

Note that it is not strictly required to add children to a Page. You can store a Page without content and eventually add some children later using UI or the API.

Deleting a Page

A page is deleted by invoking removePage on the Portal.

Application

This feature is experimental. Please send us feedback using #gatein IRC channel at freenode.net or GateIn Portal forums.

An Application is a read-only representation of a Gadget, Portlet or WSRP, as seen on the Web UI under the "Application Registry" and can be used when composing pages. A list of all Applications can be obtained as follows:

ApplicationRegistry registry = portal.getApplicationRegistry();
List<Application> applications = registry.getApplications();

If the ID of an Application is already known, due to previous interactions with users, then the following code can be used:

ApplicationRegistry registry = portal.getApplicationRegistry();
Application gadgetRss = registry.getApplication(applicationIdFromPreviousInteraction);

OAuth Provider API

The interface OAuthProvider is a part of our public API. It is the entry point to perform operations on OAuth providers (social networks).

Please refer to OAuth section for details about the configuration of GateIn Portal which is necessare to use OAuth providers (Facebook, Google, Twitter) for authentication of users. Once a user is logged in (or his account is linked with OAuth provider), his access token is saved in GateIn Portal IDM database as a part of his User Profile. Then it is possible to retrieve his OAuth access token via OAuthProvider interface and run its operations. It is also possible to revoke or validate existing access tokens or send request to obtain new access tokens with more scopes (privileges).

Except for the next two sections, where we present some basic use of the the OAuthProvider API, there is also a standalone code example called Social Portlets Quickstart in our Quickstarts Collection.

Retrieve an Instance of OAuthProvider

First, you need to retrieve the appropriate instance of OAuthProvider from Portal:

Portal portal = PortalRequest.getInstance().getPortal();
OAuthProvider facebookProvider = portal.getOAuthProvider(OAuthProvider.FACEBOOK)

Currently GateIn Portal supports three OAuth providers:

OAuthProvider Operations

The following snippet shows some basic use of OAuthProvider API:

// Retrieve instance of Google OAuth provider
OAuthProvider googleProvider = PortalRequest.getInstance().getPortal().getOAuthProvider(OAuthProvider.GOOGLE);

// Check if Google was enabled in configuration.properties
if (googleProvider == null) {
    renderResp.getWriter().println("Authentication with Google not available. See OAuth section in Reference Guide for how to enable it");
    return;
}

// Retrieve the key and display name of the social network
String key = googleProvider.getKey();
String friendlyName = googleProvider.getFriendlyName();
renderResp.getWriter().println(friendlyName + " is enabled");

// Retrieve access token of the current user
AccessToken accessToken = googleProvider.loadAccessToken(renderReq.getRemoteUser());

// Check if access token is available. It's the case when this user was registered/authenticated into portal
// through Google+ or if he linked his account with Google+
if (accessToken == null) {
    renderResp.getWriter().println("Your account is not linked with Google+. You can link it in 'Social network' tab of " +
        "user settings or you can authenticate through Google into portal");
    return;
}

// Check if access token is valid and refresh it if necessary
try {
    accessToken = googleProvider.validateTokenAndUpdateScopes(accessToken);
} catch (OAuthApiException oauthException) {
    if (oauthException.getExceptionCode().equals(OAuthApiExceptionCode.ACCESS_TOKEN_ERROR)) {
        renderResp.getWriter().println("Your access token is invalid or has been revoked");
    } else if (oauthException.getExceptionCode().equals(OAuthApiExceptionCode.IO_ERROR)) {
        renderResp.getWriter().println("Network error during the communication with Google");
    }
}

// Check all available scopes
String availableScopes = accessToken.getAvailableScopes();

// Check if we have scope to call Google+ operations
if (!availableScopes.contains("https://www.googleapis.com/auth/plus.login")) {
    // Redirect to Google+ and ask for plus.login scope
    googleProvider.startOAuthWorkflow("https://www.googleapis.com/auth/plus.login");
    return;
}

// Obtain Google API object to call Google plus API operations
Plus service = googleProvider.getAuthorizedSocialApiObject(accessToken, Plus.class);

// Retrieve activities from Google+ wall of user
ActivityFeed activityFeed = service.activities().list("me", "public").execute();
for (Activity activity : activityFeed.getItems()) {
    renderResp.getWriter().println(activity.getTitle());
}

// Revoke the access token. It won't be possible to run any operations with it anymore.
// And your application will be cleared from Google applications of current user on page https://plus.google.com/apps
googleProvider.revokeToken(accessToken);

// Remove the token from the UserProfile of the current user
googleProvider.removeAccessToken(request.getRemoteUser());

Access to Provider-Specific Operations

Method oauthProvider.getAuthorizedSocialApiObject() is useful for obtaining access to provider-specific operations. This method usually returns objects from a 3rd party library. Those objects are always initialized with access token of the current user and can be used to retrieve data from the related social network.

  • Google - there are two supported types usable as arguments of this method:

    • com.google.api.services.plus.Plus - Google Plus API class, which can be used to call operations on Google Plus - see GoogleActivitiesPortlet and GoogleFriendsPortlet in our Social Portlets Quickstart.

    • com.google.api.services.oauth2.Oauth2 - Oauth2 class, which provides operations related to user, such as obtaining his Google user profile details or obtaining information about his access token - see GoogleUserInfoPortlet in our Social Portlets Quickstart.

  • Twitter - there is only one supported type for Twitter: twitter4j.Twitter. An instance of this class can be used e.g. to retrieve user details, number of his tweets, number of his friends, his last tweets, etc. - see TwitterPortlet in our Social Portlets Quickstart.

  • Facebook - there is no supported type for Facebook. In our Social Portlets Quickstart, we are using the 3rd party library RestFB directly to perform operations against Facebook.

JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-10 13:19:24 UTC, last content change 2014-04-11 08:19:28 UTC.