5.2. Tutorials

The tutorials contained in this chapter are targeted toward portlet developers. Although they are a good starting and reference point, it is highly recommend that portlet developers read and understand the JSR-286 Portlet Specification .

5.2.1. Deploying your first Portlet

5.2.1.1. Introduction

This section describes how to deploy a portlet in JBoss Portal. You will find the SimplestHelloWorld portlet in the jboss-epp-4.3/jboss-as/docs/portal/examples directory of your distribution.

5.2.1.2. Compiling

This example is using Maven to compile and build the web archive. If you don't have Maven already installed, you will find a version for your operating system here
To compile and package the application, go to the SimplestHelloWorld directory and type mvn package .
Once successfully packaged, the result should be available in: SimplestHelloWorld/target/SimplestHelloWorld-0.0.1.war . Simply copy that file into JBOSS_HOME/server/default/deploy , then start JBoss Application Server if it was not already started.
You should now see a new page called SimplestHelloWorld , with a window inside containing the portlet instance we have created, as seen below.
SimplestHelloWorldPortlet deployed on a new page.

5.2.1.3. Package Structure

Now that we have seen how to deploy an existing web application, let's have a look inside.
Like other Java Platform, Enterprise Edition (Java EE) applications, portlets are packaged in WAR files. A typical portlet WAR file can include servlets, resource bundles, images, HTML, JavaServer™ Pages ( JSP™ ), and other static or dynamic files. The following is an example of the directory structure of the HelloWorldPortlet portlet:
|-- SimplestHelloWorld-0.0.1.war
|   `-- WEB-INF
|       |-- classes
|       |   `-- org
|       |       `-- jboss
|       |           `-- portal
|       |               `-- portlet
|       |                   `-- samples
|       |                       `-- SimplestHelloWorldPortlet.class    1
|       |-- default-object.xml                                         2
|       |-- portlet-instances.xml                                      3
|       |-- portlet.xml                                                4
|       `-- web.xml                                                    5

1

The compiled Java class implementing javax.portlet.Portlet (through javax.portlet.GenericPortlet )

2

default-object.xml is an optional file, it is used to define the layout of the portal. It can be used to define the different portals, pages and windows. The same result can be obtained through the administration portal. Note that the definition of the layout is stored in database, this file is then used to populate the database during deployment which can be very useful during development.

3

portlet-instances.xml is also optional, it allows to create a portlet instance from the SimpleHelloWorld portlet definition. Creating instances can also be done through the administration portal. Note that the definition of instances is stored in database, this file is then used to populate the database during deployment which can be very useful during development. Having portlet-instances.xml and default-object.xml included in this package ensures that the portlet will appear directly on the portal by just deploying the web application.

4

This is the mandatory descriptor files for portlets. It is used during deployment..

5

This is the mandatory descriptor for web applications.

5.2.1.4. Portlet Class

Let us study the Java class in detail.
The following file is the SimplestHelloWorldPortlet/src/main/java/org/jboss/portal/portlet/samples/SimplestHelloWorldPortlet.java Java source.
package org.jboss.portal.portlet.samples;

import java.io.IOException;
import java.io.PrintWriter;

import javax.portlet.GenericPortlet;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

public class SimplestHelloWorldPortlet extends GenericPortlet         1
{
   public void doView(RenderRequest request, 
                       RenderResponse response) throws IOException    2
   {
      PrintWriter writer = response.getWriter();                      3
      writer.write("Hello World !");                                  4
      writer.close();                                                 5
   }
}

1

All portlets must implement the javax.portlet.Portlet interface. The portlet API provides a convenient implementation of this interface, in the form of the javax.portlet.GenericPortlet class, which among other things, implements the Portlet render method to dispatch to abstract mode-specific methods to make it easier to support the standard portlet modes. As well, it provides a default implementation for the processAction , init and destroy methods. It is recommended to extend GenericPortlet for most cases.

2

As we extend from GenericPortlet , and are only interested in supporting the view mode, only the doView method needs to be implemented, and the GenericPortlet render implementation calls our implementation when the view mode is requested.

3

Use the RenderResponse to obtain a writer to be used to produce content.

4

Write the markup to display.

5

Closing the writer.

Markup Fragments

Portlets are responsible for generating markup fragments, as they are included on a page and are surrounded by other portlets. In particular, this means that a portlet outputting HTML must not output any markup that cannot be found in a <body> element.

5.2.1.5. Application Descriptors

JBoss Portal requires certain descriptors to be included in a portlet WAR file. Some of these descriptors are defined by the Portlet Specification, and others are specific to JBoss Portal.
The following is an example of the SimplestHelloWorldPortlet/WEB-INF/portlet.xml file. This file must adhere to its definition in the JSR-286 Portlet Specification. You may define more than one portlet application in this file:
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd 
                                         http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
   version="2.0">
   <portlet>
      <portlet-name>SimplestHelloWorldPortlet</portlet-name>                                        1
      <portlet-class>                                                                               2
         org.jboss.portal.portlet.samples.SimplestHelloWorldPortlet
      </portlet-class>
      <supports>                                                                                    3
        <mime-type>text/html</mime-type>
      </supports>
      <portlet-info>                                                                                4
          <title>Simplest Hello World Portlet</title>
      </portlet-info>
   </portlet>
</portlet-app>

1

Define the portlet name. It does not have to be the class name.

2

The Fully Qualified Name (FQN) of your portlet class must be declared here.

3

The <supports> element declares all of the markup types that a portlet supports in the render method. This is accomplished via the <mime-type> element, which is required for every portlet. The declared MIME types must match the capability of the portlet. As well, it allows you to pair which modes and window states are supported for each markup type. All portlets must support the view portlet mode, so this does not have to be declared. Use the <mime-type> element to define which markup type your portlet supports, which in this example, is text/html . This section tells the portal that it only outputs HTML.

4

When rendered, the portlet's title is displayed as the header in the portlet window, unless it is overridden programmatically. In this example, the title would be Simplest Hello World Portlet .
The SimplestHelloWorldPortlet/WEB-INF/portlet-instances.xml file is a JBoss Portal specific descriptor, that allows you to create instances of portlets. The <portlet-ref> value must match the <portlet-name> value given in the SimplestHelloWorldPortlet/WEB-INF/portlet.xml file. The <instance-id> value can be named anything, but it must match the <instance-ref> value given in the *-object.xml file, which in this example, would be the SimplestHelloWorldPortlet/WEB-INF/default-object.xml file.
The following is an example of the SimplestHelloWorldPortlet/WEB-INF/portlet-instances.xml file:
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE deployments PUBLIC
   "-//JBoss Portal//DTD Portlet Instances 2.6//EN"
   "http://www.jboss.org/portlet/dtd/portlet-instances_2_6.dtd">
<deployments>
   <deployment>
      <instance>
         <instance-id>SimplestHelloWorldInstance</instance-id>
         <portlet-ref>SimplestHelloWorldPortlet</portlet-ref>
      </instance>
   </deployment>
</deployments>
The *-object.xml file is a JBoss Portal specific descriptor that allow users to define the structure of their portal instances, and create and configure their windows and pages. In the following example:
  • a portlet window is created.
  • specifies that the window displays the markup generated by the SimplestHelloWorldInstance portlet instance.
  • the window is assigned to the page that we are creating and called SimplestHelloWorld page.
  • the <region> element specifies where the window appears on the page.
The following is an example SimplestHelloWorldPortlet/WEB-INF/default-object.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE deployments PUBLIC
   "-//JBoss Portal//DTD Portal Object 2.6//EN"
   "http://www.jboss.org/portal/dtd/portal-object_2_6.dtd">
<deployments>
   <deployment>
      <parent-ref>default</parent-ref>                                 1
      <if-exists>overwrite</if-exists>                                 2
      <page>
         <page-name>SimplestHelloWorld</page-name>
         <window>
            <window-name>SimplestHelloWorldWindow</window-name>        34
            <instance-ref>SimplestHelloWorldInstance</instance-ref>    5
            <region>center</region>                                    6
            <height>0</height>                                         7
         </window>
      </page>
   </deployment>
</deployments>

1

Tells the portal where this portlet appears. In this case, default.default specifies that the portlet appears in the portal instance named default , and on the page named default .

2

Instructs the portal to overwrite or keep this object if it already exists. Accepted values are overwrite and keep . The overwrite option destroys the existing object, and creates a new one based on the content of the deployment. The keep option maintains the existing object deployment, or creates a new one if it does not exist.

3

Here we are creating a new page to put the new window on. We give that new page a name that will be by default used on the tab of the default theme.

4

A unique name given to the portlet window. This can be named anything.

5

The value of <instance-ref> must match the value of one of the <instance-id> elements found in the HelloWorldPortlet/WEB-INF/portlet-instances.xml file.

6

Specifies where the window appears within the page layout.

7

Specifies where the window appears within the page layout.
The following diagram illustrates the relationship between the portlet.xml , portlet-instances.xml , and default-object.xml descriptors:
JBoss Portal 2.6 introduced the notion of content-type , which is a generic mechanism to specify what content displayed by a given portlet window. The window section of the previous example, SimplestHelloWorldPortlet/WEB-INF/default-object.xml , can be re-written to take advantage of the new content framework. The following is an example deployment descriptor that uses the new content framework:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE deployments PUBLIC
   "-//JBoss Portal//DTD Portal Object 2.6//EN"
   "http://www.jboss.org/portal/dtd/portal-object_2_6.dtd">
<deployments>
   <deployment>
      <parent-ref>default.default</parent-ref>
      <if-exists>overwrite</if-exists>
      <window>
         <window-name>SimplestHelloWorldWindow</window-name>
         <content>
            <content-type>portlet</content-type>
            <content-uri>SimplestHelloWorldInstance</content-uri>
         </content>
         <region>center</region>
         <height>1</height>
      </window>
   </deployment>
</deployments>
This declaration is equivalent to the previous SimplestHelloWorldPortlet/WEB-INF/default-object.xml example. Use <content-type> to specify the content to display. In this example, the content being displayed by the SimplestHelloWorldWindow is a portlet . The <content-uri> element specifies which content to display, which in this example, is the SimplestHelloWorldInstance :
<content>
   <content-type>portlet</content-type>
   <content-uri>SimplestHelloWorldInstance</content-uri>
</content>
To display certain content or a file, use the cms content-type, with the <content-uri> element being the path to the file in the CMS. This behavior is pluggable: you can plug in almost any type of content.
Beware of context-path change
If the context-path change the portal may not be able to find a reference on your portlets anymore. For that reason it's recommended to add the following descriptor WEB-INF/jboss-portlet.xml which is not mandatory:
<!DOCTYPE portlet-app PUBLIC
 "-//JBoss Portal//DTD JBoss Portlet 2.6//EN"
 "http://www.jboss.org/portal/dtd/jboss-portlet_2_6.dtd">

<portlet-app>
   <app-id>SimplestHelloWorld</app-id>
</portlet-app>