JBoss Portal 2.4

Reference Guide

Thomas Heute

Roy Russo

Boleslaw Dawidowicz

Release 2.4 "Devil"

July 2006


Table of Contents

JBoss Portal - Overview
Feature List
Target Audience
Acknowledgements
1. System Requirements
1.1. Minimum System Requirements
1.2. Supported Operating Systems
1.3. JBoss Application Server
1.4. Database
1.5. Source building
2. Installation
2.1. Installing from Bundled Download
2.1.1. Installing the Bundle
2.2. Installing from Binary Download
2.2.1. Setting up your environment
2.2.1.1. Getting the Binary
2.2.1.2. Application Server Setup
2.2.1.3. Database Setup
2.2.1.4. DataSource Configuration
2.2.2. Deploying JBoss Portal
2.3. Installing from Sources
2.3.1. Getting the Sources
2.3.2. Setting up your environment
2.3.2.1. Application Server Setup
2.3.2.2. Operating System Environment Setting
2.3.2.3. Database Setup
2.3.2.4. DataSource Configuration
2.3.3. Building/Deploying from Sources
3. Customizing your installation
3.1. Changing the port
3.2. Changing the context path
3.3. Forcing the DB dialect
3.3.1. DB Dialect settings for the portal core
3.3.2. DB Dialect settings for the CMS component
4. Upgrading 2.2 - 2.4
4.1. Migrating the Database
4.1.1. Database Requirements/Preparation
4.1.2. DataSource Requirements/Preparation
4.1.3. Obtaining the Migration Application
4.1.3.1. Downloading binary
4.1.3.2. Building from source
4.1.4. Deploying the Migration Application
4.1.5. Running the Migration Application
4.1.6. Final steps
4.2. Migrating Portlet Descriptors
4.2.1. Car Demo Portlet example
4.2.2. Updating Car Demo Portlet descriptors
5. Portlet Primer
5.1. JSR 168 Overview
5.1.1. Portal Pages
5.1.2. Rendering Modes
5.1.3. Window States
5.1.4. Section Status
5.2. Tutorials
5.2.1. Deploying your first portlet
5.2.1.1. Introduction
5.2.1.2. Package Structure
5.2.1.3. The Portlet Class
5.2.1.4. The Application Descriptors
5.2.1.5. Building your portlet
5.2.1.6. Deploying your portlet
5.2.2. A Simple JSP Portlet
5.2.2.1. Introduction
5.2.2.2. Package Structure
5.2.2.3. The Portlet Class
5.2.2.4. The Application Descriptors
5.2.2.5. JSP files and the portlet taglib
5.2.2.6. Building your portlet
5.2.2.7. Deploying your portlet
5.2.3. A Simple JSF Portlet
5.2.3.1. Introduction
5.2.3.2. Package Structure
5.2.3.3. The Application Descriptors
5.2.3.4. The JSP files
5.2.3.5. Building your portlet
5.2.3.6. Deploying your portlet
6. XML Descriptors
6.1. Portlet Descriptors
6.1.1. *-object.xml
6.1.2. portlet-instances.xml
6.1.3. jboss-portlet.xml
6.1.3.1. Injecting Header Content
6.1.3.2. Injecting Services in the portlet context
6.1.3.3. Portlet Session Replication in a Clustered Environment
6.1.4. portlet.xml
6.2. JBoss Portal Descriptors
6.2.1. Datasource Descriptor (portal-*-ds.xml)
6.2.1.1. Obtaining Datasource Descriptors Binary releases
6.2.1.2. Building Datasource Descriptors from Source
6.2.2. Portlet Debugging (jboss-portal.sar/conf/config.xml)
6.3. Descriptor Examples
6.3.1. Defining a new portal page
6.3.2. Defining a new portal instance
7. Portal urls
7.1. Introduction
7.2. Acessing a portal
7.3. Accessing a page
7.4. Accessing CMS Content
8. Clustering Configuration
8.1. Introduction
8.2. Considerations
8.3. JBoss Portal Clustered Services
8.3.1. Portal Session Replication
8.3.2. Hibernate clustering
8.3.3. Identity clustering
8.3.4. CMS clustering
8.4. Setup
8.5. Portlet Session Replication
8.5.1. JBoss Portal configuration
8.5.2. Portlet configuration
8.5.3. Limitations
9. Web Services for Remote Portlets (WSRP)
9.1. Introduction
9.2. Deploying JBoss Portal's WSRP services
9.3. Making a portlet remotable
9.4. Accessing JBoss Portal's WSRP Producer from a remote Consumer
9.5. Consuming remote WSRP portlets in JBoss Portal
9.5.1. Overview
9.5.2. Required configuration information
9.5.3. Optional configuration
9.5.4. Examples
10. Security
10.1. Securing Portal Objects
11. CMS Portlet
11.1. Introduction
11.2. Features
11.3. CMS Configuration
11.3.1. Welcome page
11.3.2. Service Configuration
11.3.2.1. Tuning Jackrabbit
11.3.2.2. Changing the url under which the content should be accessible
11.3.3. Configuring the Content Store Location
11.3.3.1. 100% Filesystem Storage
11.3.3.2. 100% Database Storage
11.3.3.3. Mixed Storage
11.4. Localization Support
11.5. CMS Service
11.5.1. CMS Interceptors
11.5.2. CMS Cache
12. Layouts and Themes
12.1. Overview
12.2. Layouts
12.2.1. How to define a Layout
12.2.2. How to use a Layout
12.2.2.1. Declarative use
12.2.2.2. Programatic use
12.2.3. Where to place the Descriptor files
12.2.4. How to connect a Layout to a Layout Strategy
12.2.5. Layout JSP-tags
12.3. Layout Strategy
12.3.1. What is a Layout Strategy
12.3.2. How can I use a Layout Strategy
12.3.2.1. Define a Strategy
12.3.2.2. Specify the Strategy to use
12.3.3. Linking the Strategy and the Layout
12.4. RenderSets
12.4.1. What is a RenderSet
12.4.2. How is a RenderSet defined
12.4.3. How to specify what RenderSet to use
12.5. Themes
12.5.1. What is a Theme
12.5.2. How to define a Theme
12.5.3. How to use a Theme
12.5.4. How to write your own Theme
12.6. Other Theme Functionalities and Features
12.6.1. Content Rewriting and Header Content Injection
12.6.2. Declarative CSS Style injection
12.6.3. Disabling Portlet Decoration
12.7. Theme Style Guide (based on the Industrial theme)
12.7.1. Overview
12.7.2. Main Screen Shot
12.7.3. List of CSS Selectors
13. Troubleshooting and FAQ
13.1. Troubleshooting and FAQ

Release 2.4 "Devil"

July 2006

JBoss Portal - Overview

Many IT organizations look to achieve a competitive advantage for the enterprise by improving business productivity and reducing costs. Today's top enterprises are realizing this goal by deploying enterprise portals within their IT infrastructure. Enterprise portals simplify access to information by providing a single source of interaction with corporate information. Although today?s packaged portal frameworks help enterprises launch portals more quickly, only JBoss Portal can deliver the benefits of a zero-cost open source license combined with a flexible and scalable underlying platform.

JBoss Portal provides an open source and standards-based environment for hosting and serving a portal's Web interface, publishing and managing its content, and customizing its experience. It is entirely standards-based and supports the JSR-168 portlet specification, which allows you to easily plug-in standards-compliant portlets to meet your specific portal needs. JBoss Portal is available through the business-friendly LGPL open source license and is supported by JBoss Inc. Professional Support and Consulting . JBoss support services are available to assist you in designing, developing, deploying, and ultimately managing your portal environment. JBoss Portal is currently developed by JBoss, Inc. developers, Novell developers, and community contributors.

The JBoss Portal framework and architecture includes the portal container and supports a wide range of features including standard portlets, single sign-on, clustering and internationalization. Portal themes and layouts are configurable. Fine-grained security administration down to portlet permissions rounds out the security model. JBoss Portal includes a rich content management system and message board support.

JBoss Portal Resources:

The JBoss Portal team encourages you to use this guide to install and configure JBoss Portal. If you encounter any configuration issues or simply want to take part in our community, we would love to hear from you in our forums.

Feature List

The following list details features found in this document's related release. For a technical view of our features, view the Project Roadmap and Task List .

Technology and Architecture

  • JEMS: Leverages the power of JBoss Enterprise Middleware Services : JBoss Application Server, JBoss Cache, JGroups, and Hibernate.
  • DB Agnostic: Will work with any RDBMS supported by Hibernate
  • SSO/LDAP: Leverages Tomcat and JBoss single sign on (SSO) solutions.
  • JAAS Authentication: Custom authentication via JAAS login modules.
  • Cacheing: Utilizes render-view caching for improved performance.
  • Clusterable: Cluster support allows for portal state to be clustered for all portal instances.
  • Hot-Deployment: Leverages JBoss dynamic auto deployment features.
  • SAR Installer: Browser-based installer makes installation and initial configuration a breeze.

Supported Standards

  • Portlet Specification and API 1.0 (JSR-168)
  • Content Repository for Java Technology API (JSR-170)
  • Java Server Faces 1.2 (JSR-252)
  • Java Management Extension (JMX) 1.2
  • Web Services for Remote Portlets (WSRP) 1.0 Base Level
  • Full J2EE 1.4 compliance when used with JBoss AS

Portal and Portal Container

  • Multiple Portal Instances: Ability to have multiple Portal instances running inside of one Portal container.
  • IPC Inter-Portlet Communication API enables portlets to create links to other objects such as a page, portal or window .
  • Dynamicity The ability for administrators and users to create and destroy objects such as portlets, pages, portals, themes, and layouts at runtime.
  • Internationalization: Ability to use internationalization resource files for every portlet.
  • Pluggable services: Authentication performed by the servlet container and JAAS make it possible to swap the authentication scheme.
  • Page-based Architecture: Allows for the grouping/division of portlets on a per-page basis.
  • Existing Framework support: Portlets utilizing Struts, Spring MVC, Sun JSF-RI, AJAX, or MyFaces are supported.

Web Services for Remote Portlets

  • WSRP Consumer
    • Support for WSRP Base level (support for service description and markup interfaces)
    • Ability to easily consume portlets from remote producers
    • Seamless integration of WSRP portlets in portal
    • Support for simple registration schemes
    • Simple caching of markup and metadata
  • WSRP Producer
    • Support for WSRP Base level (support for service description and markup interfaces)
    • Local portlets can easily be exposed remotely to WSRP consumers
    • Includes a local WSRP producer to easily test WSRP in Portal ('self' portlet provider)

Themes and Layouts

  • Easily swappable themes/layouts: New themes and layouts containing images can be deployed in WAR archives.
  • Flexible API: Theme and Layout API are designed to separate the business layer from the presentation layer.
  • Per-page layout strategy: Different layouts can be assigned to different pages.

User and Group Functionality

  • User registration/validation: Configurable registration parameters allow for user email validation before activation.
  • User login: Makes use of servlet container authentication.
  • Create/Edit Users: Ability for administrators to create/edit user profiles.
  • Create/Edit Roles: Ability for administrators create/edit roles.
  • Role Assignment: Ability for administrators to assign users to roles.

Permissions Management

  • Extendable permissions API: Allows custom portlets permissions based on role definition.
  • Administrative interface: Allows for permissions assignments to roles at any time for any deployed portlet, page, or portal instance.

Content Management System

  • JCR-compliant: The CMS is powered by Apache Jackrabbit, an open source implementation of the Java Content Repository API.
  • DB or Filesystem store support: Configurable content store to either a filesystem or RDBMS.
  • External Blob Support: Configurable content store allowing large blobs to reside on filesystem and content node references/properties to reside in RDBMS.
  • Versioning support: All content edited/created is autoversioned with a history of edits that can be viewed at any time.
  • Content Serving Search-engine-friendly URLS: http://yourdomain/portal/content/index.html (Does not apply to portlet actions.)
  • No long portal URLS: Serve binaries with simple urls. (http://domain/files/products.pdf)
  • Multiple HTML Portlet instance support: Allows for extra instances of static content from the CMS to be served under separate windows.
  • Directory Support: create, move, delete, copy, and upload entire directory trees.
  • File Functions: create, move, copy, upload, and delete files.
  • Embedded directory-browser: When copying, moving, deleting, or creating files, administrators can simply navigate the directory tree to find the collection they want to perform the action on.
  • Ease-of-use architecture: All actions to be performed on files and folder are one mouse-click away.
  • Full-featured HTML editor: HTML Editor contains WYSIWYG mode, preview functionality, and HTML source editting mode. HTML commands support tables, fonts, zooming, image and url linking, flash movie support, bulleted and numbered list, and dozens more.
  • Editor style-sheet support: WYSIWYG editor displays current Portal style-sheet, for easy choosing of classes.
  • Internationalization Support: Content can be attributed to a specific locale and then served to the user based on his/her browser settings.

Message Boards

  • Instant reply: Instant reply feature, makes for one-click replies to posts.
  • Post quoting: Quote an existing topic and poster within a reply.
  • Flood control: Prevents abuse of multiple posts withing a set configurable time-frame.
  • Category creation: Create a category that contains forums within it.
  • Forum creation: Create a forum and assign it to a specific category.
  • Forum modification: Edit, move, delete forums.
  • Forum and category reordering: Reorder categories and forums in the order you would like them to appear on the page.

Target Audience

Portlet developers, Portal administrators, and those wishing to implement/extend the JBoss Portal framework.

For end-user documentation, please download our User Guide from our documentation page .

Acknowledgements

We would like to thank all the developers that participate in the JBoss Portal project effort.

Specifically,

  1. Thomas Heute, for his help on the first-ever version of JBoss Portal and the corresponding documentation. ;-)
  2. Remy for his help with Tomcat configuration.
  3. Mark Fernandes and Paul Tamaro from Novell, for their hard work in supplying the portal project with usable and attractive themes and layouts.
  4. Kev "kevs3d" Roast for supplying us with two working portlets that integrate existing frameworks in to the portal: Sun JSF-RI and Spring MVC Portlet.
  5. Swarn "sdhaliwal" Dhaliwal for supplying us with the Struts-Bridge, that will allow for existing struts applications to work with the Portal.
  6. Julien Viet for creating a scalable and flexible architecture... and putting up with all of my crazy ideas.

Contributions of any kind are always welcome, you can contribute by providing ideas, filling bug reports, producing some code, designing a theme, writing some documentation, etc... To report a bug please use our Jira system .

Chapter 1. System Requirements

Thomas Heute

Roy Russo

A list of tested versions or reported as working by users, before reporting a problem please make sure that you are using a compatible version.

If you successfully installed JBoss Portal on versions not listed here please let us know so we can add it here.

1.1. Minimum System Requirements

  • JDK 1.4 or higher (1.4.2 is recommended)
  • 512 MB RAM
  • 50 MB hard disk space
  • 400 MHz CPU

1.2. Supported Operating Systems

JBoss Portal is 100% pure Java and therefore interoperable with most operating systems capable of running a Java Virtual Machine (JVM); including Windows, UNIX, and Linux.

1.3. JBoss Application Server

JBoss Portal only works with JBoss Application Server.

Warning

Currently we recommend using JBoss AS 4.0.4.GA, or greater. Previous versions of JBoss Application Server are not supported with JBoss Portal 2.4

1.4. Database

JBoss Portal is Database-Agnostic.

Note

JBoss Portal employs Hibernate as an interface to RDBMS. Most RDBMS supported by Hibernate will work with JBoss Portal.

The following list, outlines known-to-be-working database vendor and version combinations:

  • MySQL 4.x.x (along with the connector 3.0.16)
  • MySQL 5 ( known issue )
  • PostgreSQL 8.x
  • HypersonicSQL
  • Derby
  • Oracle 9 and 10g
  • MSSQL
  • MaxDB

1.5. Source building

The source building mechanism works on Windows, Linux, MacOS X and any 'Unix like' operating system.

Chapter 2. Installation

There are 3 different methods to getting JBoss Portal up and running. The one you choose is up to you, but all result in your being able to run/deploy the best Portal application in the world. ;-)

Note

As of JBoss Portal 2.4-CR1, we have made available pre-configured clustered versions. They are available from the download page , in the same 3 flavors as the non-clustered version. The installation difference, being that they must be deployed in the all configuration in JBoss AS. Read Chapter 8, Clustering Configuration for more details on how to customize your clustered install, once deployed.

2.1. Installing from Bundled Download

This is the easiest and fastest way to get JBoss Portal installed and running. The reason, is that the download bundle contains JBoss Application Server, and JBoss Portal uses the embedded Hypersonic Database.

2.1.1. Installing the Bundle

  • Get the Bundle: The download bundle is available from our download page . Bundles are noted with the 'JBoss Portal + AS' naming convention.

  • Extract the bundle: Extract the zip archive to a directory of your choosing. In windows, we recommend, C:\jboss-X.X.X

  • Start the Server: Go to JBOSS_INSTALL_DIRECTORY/bin and execute run.bat (run.sh, if Linux)

Note

During the first boot (ever), SQL errors in the log, like the one below, can be safely ignored. They are thrown when the portal checks for the existence of the initial tables, before it creates them for you.
16:43:39,234 WARN [JDBCExceptionReporter] SQL Error: -22, SQLState: S0002
16:43:39,234 ERROR [JDBCExceptionReporter] Table not found in statement ...

Point your browser to http://localhost:8080/portal , and you should see the Portal HomePage. You can now login using one of the two default accounts: user/user or admin/admin .

2.2. Installing from Binary Download

The binary download package typically consists of the jboss-portal.sar , documentation (which you are already reading), and a set of preconfigured datasource descriptors that allow JBoss Portal to communicate with a database.

This installation method is preferred by those who already have JBoss Application Server installed.

2.2.1. Setting up your environment

2.2.1.1. Getting the Binary

The binary download is available from our download page .

Once downloaded and extracted, the folder hierarchy should look like this:

We will be using files contained in this download in the further sections, so please download and extract it first.

2.2.1.2. Application Server Setup

Of course you will need to install JBoss Application Server prior to installing JBoss portal, if you didn't do so yet, please install JBoss 4.0.4+ from here .

Warning

Make sure to download the JBoss AS Zip version. DO NOT ATTEMPT to deploy JBoss Portal on the installer version of JBoss AS! We are currently working on aligning the Application installer with JBoss Portal.

2.2.1.3. Database Setup

You will need a database for JBoss Portal to function, you can use any database supported by Hibernate.

  1. Create a new Database: For example purposes we call this new database jbossportal

  2. Grant access rights for a user to your database: You must make sure the user has access to this new DB, as JBoss Portal will need to create the tables and modify data within them.

  3. Deploy your JDBC connector: You must make available a JDBC connector for JBoss Portal to communicate with your database. The connector lib should be placed in JBOSS_INSTALL_DIRECTORY/server/default/lib/*

2.2.1.4. DataSource Configuration

The JBoss Portal download you extracted in Section 2.2.1.1, “Getting the Binary” contains pre-configured datasource descriptors, you can use for most popular RDBMS under the setup directory.

At this point, you should configure the one that suits you best with your Database and JDBC driver.

<?xml version="1.0" encoding="UTF-8"?>
<datasources>
  <local-tx-datasource>
    <jndi-name>PortalDS</jndi-name>
    <connection-url>jdbc:postgresql:jbossportal</connection-url>
    <driver-class>org.postgresql.Driver</driver-class>
    <user-name>portal</user-name>
    <password>portalpassword</password>
  </local-tx-datasource>
</datasources>
                  

Please verify that the username, password, url, and driver-class are correct for your flavor of DB. You can deploy the datasource file by itself to test, in advance.

2.2.2. Deploying JBoss Portal

  1. Deploy: Copy the datasource descriptor file (*-ds.xml) you modified above AND the jboss-portal.sar from the download folder to JBOSS_INSTALL_DIRECTORY/server/default/deploy/.

  2. Start the Server: Go to JBOSS_INSTALL_DIRECTORY/bin and execute run.bat (run.sh, if Linux)

Note

During the first boot (ever), SQL errors in the log, like the one below, can be safely ignored. They are thrown when the portal checks for the existence of the initial tables, before it creates them for you.
16:43:39,234 WARN [JDBCExceptionReporter] SQL Error: -22, SQLState: S0002
16:43:39,234 ERROR [JDBCExceptionReporter] Table not found in statement ...

Point your browser to http://localhost:8080/portal , and you should see the Portal HomePage. You can now login using one of the two default accounts: user/user or admin/admin .

2.3. Installing from Sources

2.3.1. Getting the Sources

There are two ways for you to obtain the JBoss Portal source files:

  • From our download page

  • From CVS, running the following command:

                            cvs -d :pserver:anonymous@anoncvs.forge.jboss.com:/cvsroot/jboss co jboss-portal-2.4
                         

After checking out of CVS or extracting the Source zip, your directory structure should look like this:

2.3.2. Setting up your environment

2.3.2.1. Application Server Setup

Of course you will need to install JBoss Application Server prior to installing JBoss portal, if you didn't do so yet, please install JBoss 4.0.4+ from here .

Warning

Make sure to download the JBoss AS Zip version. DO NOT ATTEMPT to deploy JBoss Portal on the installer version of JBoss AS! We are currently working on aligning the Application installer with JBoss Portal.

2.3.2.2. Operating System Environment Setting

For the build targets to work, you must first set the JBOSS_HOME environment variable in your operating system, to the root directory of the JBoss Application Server installation.

In Windows, this is accomplished by going to Start > Settings > Control Panel > System > Advanced > Environment Variables . Now under the System Variables section, click New . You will be setting the JBOSS_HOME environment variable to the location of your JBoss Application Server installation:

On a Unix-like Operating System, you would accomplish this by typing:

export JBOSS_HOME=/path/to/your/jboss/directory

2.3.2.3. Database Setup

You will need a database for JBoss Portal to function, you can use any database supported by Hibernate.

  1. Create a new Database: For example purposes we call this new database jbossportal

  2. Grant access rights for a user to your database: You must make sure the user has access to this new DB, as JBoss Portal will need to create the tables and modify data within them.

  3. Deploy your JDBC connector: You must make available a JDBC connector for JBoss Portal to communicate with your database. The connector lib should be placed in JBOSS_HOME/server/default/lib/*

2.3.2.4. DataSource Configuration

You will need a valid datasource descriptor, for JBoss Portal to communicate with your database. Having obtained the sources and having set your JBOSS_HOME environment variable ( Section 2.3.2.2, “Operating System Environment Setting” ), you can now have the JBoss Portal build system generate preconfigured datasources for you.

Navigate to JBOSS_PORTAL_HOME_DIRECTORY/core and type:

build datasource

Once complete, the datasource build should produce the following directory and file structure:

At this point, you should configure the one that suits you best with your Database and JDBC driver.

<?xml version="1.0" encoding="UTF-8"?>
<datasources>
  <local-tx-datasource>
    <jndi-name>PortalDS</jndi-name>
    <connection-url>jdbc:postgresql:jbossportal</connection-url>
    <driver-class>org.postgresql.Driver</driver-class>
    <user-name>portal</user-name>
    <password>portalpassword</password>
  </local-tx-datasource>
</datasources>
                  

Please verify that the username, password, url, and driver-class are correct for your flavor of DB.

Now copy your datasource descriptor to JBOSS_HOME/server/default/deploy

2.3.3. Building/Deploying from Sources

To build and deploy the JBoss Portal service, go to JBOSS_PORTAL_HOME_DIRECTORY/build and type:

build deploy

Note

To build the clustered version, you will need to go to JBOSS_PORTAL_HOME_DIRECTORY/build and type:
build main
Then, go to JBOSS_PORTAL_HOME_DIRECTORY/core and type:
build deploy-ha
This will copy the jboss-portal-ha.sar to your all configuration for you.

At the end of the build process, the jboss-portal.sar is copied to JBOSS_HOME/server/default/deploy :

Please verify that your JBOSS_HOME/server/default/deploy directory, contains both necessary files before starting JBoss Application Server.

Start the Server: Go to JBOSS_HOME/bin and execute run.bat (run.sh, if Linux)

Note

During the first boot (ever), SQL errors in the log, like the one below, can be safely ignored. They are thrown when the portal checks for the existence of the initial tables, before it creates them for you.
16:43:39,234 WARN [JDBCExceptionReporter] SQL Error: -22, SQLState: S0002
16:43:39,234 ERROR [JDBCExceptionReporter] Table not found in statement ...

Point your browser to http://localhost:8080/portal , and you should see the Portal HomePage. You can now login using one of the two default accounts: user/user or admin/admin .

Chapter 3. Customizing your installation

Thomas Heute

This section is intended to describe some customization features available in JBoss Portal. If it is not covered here, please view the FAQ chapter at the end of this document or the descriptor chapter ( Section 6.2, “JBoss Portal Descriptors” ) for further documentation on configuration and tuning JBoss Portal.

3.1. Changing the port

It is common to have a server running on the port 80 instead of the default port 8080.

It might be easier to use port forwarding than to change the port manually. Since port forwarding is not always possible, below are the instructions to change the port number manually.

To change it, you need to edit the file $JBOSS_HOME/server/default/deploy/jbossweb-tomcat50.sar/server.xml and change the port value of the HTTP Connector. You can also change the value of the SSL port, by default it is set to 8443. Remember to uncomment the following when you have configured it:

            
      <!-- SSL/TLS Connector configuration using the admin devl guide keystore
      <Connector port="8443" address="${jboss.bind.address}"
           maxThreads="100" strategy="ms" maxHttpHeaderSize="8192"
           emptySessionPath="true"
           scheme="https" secure="true" clientAuth="false"
           keystoreFile="${jboss.server.home.dir}/conf/chap8.keystore"
           keystorePass="rmi+ssl" sslProtocol = "TLS" />
      -->
            
         

You also need to change the port number in the following files for WSRP:

  • jboss-portal.sar/portal-wsrp.sar/default-wsrp.xml
  • jboss-portal.sar/portal-wsrp-client.jar/META-INF/jboss-client.xml (for the producer with the self id.
  • jbossws.sar/META-INF/jboss-service.xml as indicated in JBoss WS' URL rewriting FAQ
  • http-invoker.sar/META-INF/jboss-service.xml

Now you can restart JBoss and use the new port that you defined. On systems like Linux, you need privileges to be able to run a server on a port lower than 1000, starting JBoss on the port 80 as a regular user will not work, for testing you can log as root but is not recommended if the server is public as it could be a security breach in your system.

3.2. Changing the context path

By default, the "main" page of JBoss portal will be accessible at http://localhost:8080/portal/index.html . You may want to change that either to a different name or to http://localhost:8080/index.html .

Note

By default, Tomcat holds on to the root context '/'. Some users have mentioned that you also need to remove the $JBOSS_HOME\server\default\deploy\jbossweb-tomcat55.sar\ROOT.war for the below changes to take effect on restart.

You can accomplish this, with either a deployed jboss-portal.sar or before you build from source:

  • Binary method:

    1. Open JBOSS_INSTALL_DIRECTORY/server/default/deploy/jboss-portal.sar/portal-server.war/WEB-INF/jboss-web.xml

      <?xml version="1.0"?>
      <jboss-web>
         <security-domain>java:jaas/portal</security-domain>
         <context-root>/portal</context-root>
         <replication-config>
            <replication-trigger>SET_AND_GET</replication-trigger>
            <replication-type>SYNC</replication-type>
         </replication-config>
         <resource-ref>
            <res-ref-name>jdbc/PortalDS</res-ref-name>
            <jndi-name>java:PortalDS</jndi-name>
         </resource-ref>
      </jboss-web>

    2. Edit the context-root element to whatever you desire.

      <context-root>/</context-root>

  • Source method: Edit the file $PORTAL_HOME/build/local.properties (You can copy the file $PORTAL_HOME/build/etc/local.properties-example and modify it for your own settings.) and change portal.web.context-root to anything you want.

    Now clean the project (ant clean) then build JBoss portal (ant) and redeploy it for the context path changes to take effect. For build instructions, please see: Section 2.3, “Installing from Sources”

3.3. Forcing the DB dialect

If you encounter that the Hibernate dialect is not working properly and would like to override the default behaviour, follow the instructions contained in this section:

Note

Under most common circumstances, the auto-detect feature should work fine.

3.3.1. DB Dialect settings for the portal core

Modify jboss-portal.sar/conf/hibernate/[module]/hibernate.cfg.xml . A list of supported dialects for Hibernate3, can be found here .

               <?xml version='1.0' encoding='utf-8'?>
               <!DOCTYPE hibernate-configuration PUBLIC
               "-//Hibernate/Hibernate Configuration DTD//EN"
               "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
               <hibernate-configuration>
               <session-factory>
               <property name="connection.datasource">java:PortalDS</property>
               <property name="show_sql">false</property>
               <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
               <property name="cache.use_query_cache">true</property>
               
               <!-- Force the dialect instead of using autodetection -->
               <!--
               <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
               -->
               
               <!-- Mapping files -->
               <mapping resource="conf/hibernate/user/domain.hbm.xml"/>
               </session-factory>
               </hibernate-configuration>               
               

3.3.2. DB Dialect settings for the CMS component

Modify jboss-portal.sar/portal-cms.sar/conf/hibernate/cms/hibernate.cfg.xml . A list of supported dialects for Hibernate3, can be found here .

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
   <session-factory>
      <property name="connection.datasource">java:@portal.datasource.name@</property>
      <property name="show_sql">@portal.sql.show@</property>
      <property name="cache.use_second_level_cache">false</property>
      <property name="cache.use_query_cache">true</property>

      <!-- Force the dialect instead of using autodetection -->
      <!--
      <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
      -->

      <!-- Mapping files -->
      <mapping resource="conf/hibernate/cms/domain.hbm.xml"/>
   </session-factory>
</hibernate-configuration>

Chapter 4. Upgrading 2.2 - 2.4

This chapter addresses migration issues from version 2.2 to 2.4 of JBoss Portal.

4.1. Migrating the Database

JBoss Portal 2.4 comes with dedicated web application for database migration. This application will migrate your existing JBoss Portal 2.2 database data to a new one, for use with JBoss Portal 2.4.

Warning

This migration process should be performed before JBoss Portal 2.4 deployment. Follow the exact steps below, in order, or ugly scary things may happen!

4.1.1. Database Requirements/Preparation

You will need two database instances for this migration process to function:

  • Source JBP 2.2 database from which we migrate portal data. (You should already have this!)

  • Destination JBP 2.4 database to which we migrate portal data.

Before you begin the process you must create a separate database to which the data will be migrated. Note that the Migration Application performs a Hibernate SchemaExport which drops and recreates tables - It is recommended that you backup your database before starting!

For our example, we have two databases... the existing one for JBoss Portal 2.2, and the new (empty) one for JBoss Portal 2.4:

  • JBoss Portal 2.2 DB: jbossportal22

  • JBoss Portal 2.4 DB: jbossportal24

We will use the above database naming, as examples in the next chapter on configuring the datasource.

4.1.2. DataSource Requirements/Preparation

The Migration Application will need access to both databases, while its running. For this reason, we need to make available both JBoss Application Server datasource files.

  1. You should have an existing JBoss Portal 2.2 datasource, portal-ds.xml or portal-*-ds.xml file that looks like this:

                      
                   <?xml version="1.0" encoding="UTF-8"?>
                   <datasources>
                      <local-tx-datasource>
                         <jndi-name>PortalDS</jndi-name>
                         <connection-url>jdbc:mysql://localhost:3306/jbossportal22?useServerPrepStmts=false</connection-url>
                         <driver-class>org.gjt.mm.mysql.Driver</driver-class>
                         <user-name>portal</user-name>
                         <password>portalpassword</password>
                      </local-tx-datasource>
                   </datasources>
                
                   
  2. Now, you will need to create a second datasource for the destination database. In our example we will create, portal-migration-ds.xml file that looks like this:

                      
                   <?xml version="1.0" encoding="UTF-8"?>
                   <datasources>
                      <local-tx-datasource>
                         <jndi-name>PortalDS_2_4</jndi-name>
                         <connection-url>jdbc:mysql://localhost:3306/jbossportal24?useServerPrepStmts=false</connection-url>
                         <driver-class>org.gjt.mm.mysql.Driver</driver-class>
                         <user-name>portal</user-name>
                         <password>portalpassword</password>
                      </local-tx-datasource>
                   </datasources>
                
                   

4.1.3. Obtaining the Migration Application

The JBoss Portal Migration Application can be obtained either as a ready to deploy web application or in source form.

4.1.3.1. Downloading binary

You can find a prepared binary at:

  • Download section of JBoss Portal project page

4.1.3.2. Building from source

You can obtain portal sources from either:

  • Download section of JBoss Portal project page

  • CVS by running following command:

                         
                            cvs -d :pserver:anonymous@anoncvs.forge.jboss.com:/cvsroot/jboss co jboss-portal-2.4
                         
                      

Using the second method you will always have all latest updates from portal 2.4 cvs branch

After downloading the sources you need to build the Migration Application. Before you start be sure you have JBOSS_HOME environment variable set pointing to JBoss Application Server directory. Migration Application archive can be build using following commands:

               
                  cd jboss-portal-2.4
                  cd build
                  ./build.sh
                  cd ..
                  cd migration
                  ./build.sh
               
            

Deployable web application archive can be found at jboss-portal-2.4/migration/output/lib/portal-migration.war

You can also deploy it automatically by executing:

               
                  cd jboss-portal-2.4
                  cd migration
                  ./build.sh deploy
               
            

4.1.4. Deploying the Migration Application

The steps below will guide you through deploying and running the migration application:

  1. Shut down JBoss Application Server

  2. Undeploy/Remove JBoss Portal 2.2 (JBOSS_HOME/server/default/deploy/jboss-portal.sar)

  3. Delete JBOSS_HOME/server/default/data/portal/cms (This directory will be created for you, once again, when JBoss Portal 2.4 initializes.

  4. Deploy the two necessary datasource descriptors, from Section 4.1.2, “DataSource Requirements/Preparation” to JBOSS_HOME/server/default/deploy/*

  5. Deploy the Migration Application, you obtained from Section 4.1.3, “Obtaining the Migration Application” to JBOSS_HOME/server/default/deploy/portal-migration.war

  6. Start JBoss Application Server

4.1.5. Running the Migration Application

  1. After deploying Migration Application you can access it at http://localhost:8080/portal-migration . It is password protected so you need to specify:

    • User: admin

    • Password: simplePassword

    Note

    The Password can be changed in portal-migration.war/WEB-INF/classes/users.properties file. Remember to always change the password to a less trivial one, or undeploy the war file after the migration process.

  2. If you logged in successfully you should access this page:

  3. At Step 2: 2.4 Database Connectivity Check you need to provide datasouce name that points to JBoss Portal 2.4 database (the destination one)

  4. Step 3: Create Tables

  5. If both connections were valid and database schema was created successfully you can follow with the migration process. It is separated into following parts:

    • CMS Data Migration - migrates portal CMS tables content

    • User/Role Data Migrate - migrates portal user, roles and relations beetween them

    • Portal Object Data Migrate - migrates whole portal objects structure. This means nodes like portals, pages and windows.

    • Portal Portlet Instance Data Migrate - migrates all portlet instances presented in portal. For each portlet instance its preferences are also persisted. Next, all already migrated users are iterated and user preferences related to portlet instance are migrated

    • Portal Security Data Migrate - migrates security data for portal objects and portlet instances.

    Which should lead to a successfull end :)

Note

If any error occured during the migration process you will be provided with specific information and asked to retry that step
Always check the Application Server console output or logs after migration to track possible errors.

4.1.6. Final steps

After running the Migration Application you need to perform some additional steps to finish the process:

  1. Shutdown JBoss Application Server

  2. Undeploy JBoss Portal 2.2 (jboss-portal.sar)

  3. Undeploy the JBoss Portal 2.2 datasource descriptor

  4. Delete JBOSS_HOME/server/default/data/portal/cms (This directory will be created for you, once again, when JBoss Portal 2.4 initializes.

  5. Edit your 2.4 datasource file and modify the jndi name: <jndi-name>PortalDS</jndi-name>

  6. Deploy JBoss Portal 2.4.

  7. Start JBoss Application Server

4.2. Migrating Portlet Descriptors

Since 2.2 version of JBoss Portal data from portlet descriptor files are persisted in database. There is special <if-exists/> tag that describes what should portal do when he process descriptor and found data for such portlet application already in database. Therefore after database migration portal will use persisted data.

There are some differences beetween 2.2 and 2.4 descriptors. portlet-instances.xml file was reintroduced because of WSRP implementation caused portal architecture changes. Altough to avoid confusion legacy descriptors support was implemented in 2.4 so all 2.2 compiliant portlets should work out of box.

Even if your 2.2 portlets deployed successfully in 2.4 you should update their descriptors. Legacy descriptors support will expire in 2.6 and you will need to use new format to achive more complex targets.

4.2.1. Car Demo Portlet example

Let's show descriptor changes using Car Demo portlet example which is a presentation of JSF portlet. It can be obtained at PortletSwap . In 2.2 prepared version it has such descriptor:

  • cardemo-object.xml

                      
                      <?xml version="1.0" encoding="UTF-8"?>
                      <deployments>
                         <deployment>
                            <if-exists>overwrite</if-exists>
                            <parent-ref>default</parent-ref>
                            <page>
                               <page-name>samples</page-name>
                               <window>
                                  <window-name>CarDemoWindow</window-name>
                                  <instance-ref>CarDemoPortletInstance</instance-ref>
                                  <region>center</region>
                                  <height>0</height>
                               </window>
                            </page>
                         </deployment>
                         <deployment>
                            <if-exists>overwrite</if-exists>
                            <instance>
                               <instance-name>CarDemoPortletInstance</instance-name>
                               <component-ref>cardemo.CarDemoPortlet</component-ref>
                            </instance>
                         </deployment>
                      </deployments>
                      
                   

Note that as we said before you can successfully deploy it on JBoss Portal 2.4. But because such descriptor format is 2.2 specific you will end with a warning on JBoss Application Server console output:

            
            INFO  [PortletAppDeployment] These instances have been found in -object.xml, you should put them in the file
            c:\jboss-4.0.4.GA\server\default\.\deploy\cardemo.war\WEB-INF/portlet-instances.xml
            INFO  [PortletAppDeployment] <?xml version="1.0" encoding="utf-8" standalone="yes"?>
            <deployments>
               <deployment>
                  <instance>
                     <instance-id>CarDemoPortletInstance</instance-id>
                     <portlet-ref>CarDemoPortlet</portlet-ref>
                  </instance>
               </deployment>
            </deployments>
            
         

So all you need to do is to follow suggestion you got in the warning message :)

4.2.2. Updating Car Demo Portlet descriptors

To have descriptors in our example portlet 2.4 valid you need to follow few simple steps:

  • In cardemo-object.xml file comment out whole <deployment>...</deployment> tag which contains <instance>...</instance> .

  • Copy the text you just commented out and put it in newly created portlet-instances.xml file.

  • Edit and change portlet-instances.xml file using following rules:

    Surround whole file content with </deployments> tag.

    Replace </instance-name> tag with </instance-id> one

    Replace </component-ref> tag with </portlet-ref> one

So after updates your portlet descriptors should look like this:

  • cardemo-object.xml

                      
                      <?xml version="1.0" encoding="UTF-8"?>
                      <deployments>
                         <deployment>
                            <if-exists>overwrite</if-exists>
                            <parent-ref>default</parent-ref>
                            <page>
                               <page-name>samples</page-name>
                               <window>
                                  <window-name>CarDemoWindow</window-name>
                                  <instance-ref>CarDemoPortletInstance</instance-ref>
                                  <region>center</region>
                                  <height>0</height>
                               </window>
                            </page>
                         </deployment>
                      </deployments>
                      
                   
  • portlet-instances.xml

                      
                      <?xml version="1.0" encoding="utf-8" standalone="yes"?>
                      <deployments>
                         <deployment>
                            <instance>
                               <instance-id>CarDemoPortletInstance</instance-id>
                               <portlet-ref>CarDemoPortlet</portlet-ref>
                            </instance>
                         </deployment>
                      </deployments>
                      
                   

Chapter 5. Portlet Primer

Roy Russo

5.1. JSR 168 Overview

The JSR 168 specification aims at defining porlets that can be used by any JSR168 portlet container also called portals. There are different portals out there with commercial and non-commercial licences. In this chapter we will briefly describe such portlets but for more details you should read the specifications available on the web.

Note

This section is a brief overview of the JSR 168 Portlet Specification , and it does not cover the topics in great detail. We strongly encourage portlet developers to read the Specification that can be found here .

As of today, JBoss portal is fully JSR168 1.0 compliant, that means that any JSR168 portlet will behave as it should inside the portal.

5.1.1. Portal Pages

A portal can be seen as pages with different areas and inside areas, different windows and each window having one portlet.

5.1.2. Rendering Modes

A porlet can have different view modes, three modes are defined by the specification but a portal can extend those modes. The 3 modes are:

  • VIEW - Generates markup reflecting the current state of the portlet.
  • EDIT - Should allow a user to customize the behaviour of the portlet.
  • HELP - Should provide some information to the user as to how to use the portlet.

5.1.3. Window States

Window states are an indicator of how much page real-estate a portlet should consume on any given page. There are 3 states defined by the specification:

  • NORMAL - A portlet shares this page with other portlets.
  • MINIMIZED - A portlet may show very little information or none at all.
  • MAXIMIZED - A portlet may be the only portlet displayed on this page.

5.1.4. Section Status

This overview of the portlet specification, is a work in progress. Check back for more in-depth analsis of the specification, but please read on for real-world cases of how to leverage the specification.

5.2. Tutorials

The tutorials contained in this chapter are targetted toward portlet developers. Although they are a good starting and reference point, we do heavily recommend that portlet developers read and understand the Portlet Specification (JSR-168) . We also recommend, using our JBoss Portal User Forums for user-to-user help, when needed.

5.2.1. Deploying your first portlet

5.2.1.1. Introduction

This section will introduce the reader to deploying his first portlet in JBoss Portal. It requires you download the HelloWorldPortlet from PortletSwap.com, using this link .

5.2.1.2. Package Structure

Portlets are packaged in war files, just like other JEE applications. A typical portlet war file can also include servlets, resource bundles, images, html, jsps, and other static or dynamic files you would commonly include.

5.2.1.3. The Portlet Class

Included in the download bundle you should have one java source file: HelloWorldPortlet\src\main\org\jboss\portlet\hello\HelloWorldPortlet.java , and it should contain the following:

                  package org.jboss.portlet.hello;

import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.UnavailableException;
import java.io.IOException;
import java.io.PrintWriter;

public class HelloWorldPortlet extends GenericPortlet
{
   protected void doView(RenderRequest rRequest, RenderResponse rResponse) throws PortletException, IOException, UnavailableException
   {
      rResponse.setContentType("text/html");
      PrintWriter writer = rResponse.getWriter();
      writer.write("Hello World!");
      writer.close();
   }
}
               

Now lets dissect our simplest of portlets:

  • public class HelloWorldPortlet extends GenericPortlet

    All Portlets MUST implement the javax.portlet.GenericPortlet Interface.

  • protected void doView(RenderRequest rRequest, RenderResponse rResponse) throws
                               PortletException, IOException, UnavailableException

    In this case, our doView will be called when the portlet is asked to render output in VIEW Mode.

  • rResponse.setContentType("text/html");

    Just like in the servlet-world, you must declare what content-type the portlet will be responding in.

  • PrintWriter writer = rResponse.getWriter();
    writer.write("Hello World!");
    writer.close();

    Here we output the text Hello World! in our portlet window.

    Note

    Portlets are responsible for generating markup fragments, as they are included on a page and surrounded by other portlets.

5.2.1.4. The Application Descriptors

JBoss Portal requires certain descriptors be included in your portlet war, for different reasons. Some of these descriptors are defined by the Portlet Specification, and some are specific to JBoss Portal.

Now lets explain what each of these does:

  • portlet.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
                 version="1.0">
       <portlet>
          <portlet-name>HelloWorldPortlet</portlet-name>
          <portlet-class>org.jboss.portlet.hello.HelloWorldPortlet</portlet-class>
          <supports>
             <mime-type>text/html</mime-type>
             <portlet-mode>VIEW</portlet-mode>
          </supports>
          <portlet-info>
             <title>HelloWorld Portlet</title>
          </portlet-info>
       </portlet>
    </portlet-app>

    This file must adhere to its definition in the Portlet Specification. You may define more than one portlet application in this file.

    • <portlet-name>HelloWorldPortlet</portlet-name>

      Define your portlet name. It does not have to be the Class name.

    • <portlet-class>org.jboss.portlet.hello.HelloWorldPortlet</portlet-class>

      The FQN of your portlet class must be declared here.

    • <supports>
         <mime-type>text/html</mime-type>
         <portlet-mode>VIEW</portlet-mode>
      </supports>

      The supports attributes allow you to declare extra vital information about the portlet. In this case, we are letting the portal know that it will be outputting text/html and only support a VIEW mode.

      Note

      A content-type must be declared here for every portlet, and it must match with how the portlet is programmatically responding. Likewise, a portlet mode must be declared here and have a corresponding method in its class. In our case, the VIEW mode will map to the doView() in our class.

    • <portlet-info>
         <title>HelloWorld Portlet</title>
      </portlet-info>
      

      The portlet's title will be displayed as the header in the portlet window, when rendered, unless it is overridden programatically.

  • portlet-instances.xml

    <deployments>
       <deployment>
          <instance>
             <instance-id>HelloWorldPortletInstance</instance-id>
             <portlet-ref>HelloWorldPortlet</portlet-ref>
          </instance>
       </deployment>
    </deployments>

    This is a JBoss Portal specific descriptor that allows you create an instance of a portlet. The portlet-ref value must match the portlet-name value given in the packaged portlet.xml . The instance-id value can be named anything, but it must match the instance-ref value given in the *-object.xml file we will explore below.

  • helloworld-object.xml

    <deployments>
       <deployment>
          <if-exists>overwrite</if-exists>
          <parent-ref>default.default</parent-ref>
          <window>
             <window-name>HelloWorldPortletWindow</window-name>
             <instance-ref>HelloWorldPortletInstance</instance-ref>
             <region>center</region>
             <height>1</height>
          </window>
       </deployment>
    </deployments>

    The *-object.xml is responsible for creating/configuring windows, pages, and even portal instances. In our example, we are creating a portlet window, assigning it to a page, and specifying where it should appear on that page. This is a specific descriptor to JBoss Portal.

    • <if-exists>overwrite</if-exists>

      Instructs the portal to overwrite or keep this object if it already exists. Possible values are overwrite or keep . Overwrite will destroy the existing object and create a new one based on the content of the deployment. Keep will maintain the existing objct deployment or create a new one if it does not yet exist.

    • <parent-ref>default.default</parent-ref>

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

    •                                     <window-name>HelloWorldPortletWindow</window-name>

      Can be named anything.

    •                                     <instance-ref>HelloWorldPortletInstance</instance-ref>

      The value of instance-ref must match the value of instance-id found in the portlet-instances.xml .

    • <region>center</region>
      <height>1</height>

      Specify the layout region and order this window will be found on the portal page.

To illustrate the relationship between the descriptors , we have provided this simple diagram

5.2.1.5. Building your portlet

If you have downloaded the sample, you can execute the build.xml with ANT or inside your IDE. Executing the deploy target will compile all src files and produce a helloworldportlet.war under HelloWorldPortlet\helloworldportlet.war.

If you want to create an expanded war directory, after executing the above deploy target, you should execute the explode target.

The above target will produce the following:

This will deflate the helloworldportlet.war, and allow you to deploy it as an expanded directory. It will work just the same, with some additional benefits noted below:

The advantage to expanded war deployments is that you can modify xml descriptors, resource files jsp/jsf pages easily during development. Simply touch the web.xml to have JBoss Application Server hot-deploy the web appllication on a live-running server instance

5.2.1.6. Deploying your portlet

Deploying a portlet is as simple as copying/moving the helloworldportlet.war in to the server deploy directory. Doing this on a running instance of the portal and application server, will trigger a hot-deploy :

18:25:56,366 INFO  [Server] JBoss (MX MicroKernel) [4.0.3SP1 (build: CVSTag=JBoss_4_0_3_SP1 date=200510231054)] Started in 1m:3s:688ms
18:26:21,147 INFO  [TomcatDeployer] deploy, ctxPath=/helloworldportlet, warUrl=.../tmp/deploy/tmp35219helloworldportlet-exp.war/
               

Pointing your browser to http://localhost:8080/portal/ , should yield a view of our HelloWorldPortlet:

5.2.2. A Simple JSP Portlet

5.2.2.1. Introduction

This section will introduce the reader to deploying a simple JSP portlet in JBoss Portal. It requires you download the HelloWorldJSPPortlet from PortletSwap.com, using this link .

This portlet will introduce you to using JSPs for view rendering and the portlet taglib for generating links.

5.2.2.2. Package Structure

Portlets are packaged in war files, just like other JEE applications. A typical portlet war file can also include servlets, resource bundles, images, html, jsps, and other static or dynamic files you would commonly include.

5.2.2.3. The Portlet Class

Included in the download bundle you should have one java source file: HelloWorldPortlet\src\main\org\jboss\portlet\hello\HelloWorldJSPPortlet.java , and it should contain the following:

                  
package org.jboss.portlet.hello;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.UnavailableException;
import java.io.IOException;

public class HelloWorldJSPPortlet extends GenericPortlet
{
   protected void doView(RenderRequest rRequest, RenderResponse rResponse) throws PortletException, IOException, UnavailableException
   {
      rResponse.setContentType("text/html");

      String sYourName = (String) rRequest.getParameter("yourname");

      if(sYourName != null)
      {
         rRequest.setAttribute("yourname", sYourName);
         PortletRequestDispatcher prd = getPortletContext().getRequestDispatcher("/WEB-INF/jsp/view2.jsp");
         prd.include(rRequest, rResponse);
      }
      else
      {
         PortletRequestDispatcher prd = getPortletContext().getRequestDispatcher("/WEB-INF/jsp/view.jsp");
         prd.include(rRequest, rResponse);
      }
   }

   public void processAction(ActionRequest aRequest, ActionResponse aResponse) throws PortletException, IOException, UnavailableException
   {
      String sYourname = (String) aRequest.getParameter("yourname");

      // do something

      aResponse.setRenderParameter("yourname", sYourname);
   }

   protected void doHelp(RenderRequest rRequest, RenderResponse rResponse) throws PortletException, IOException, UnavailableException
   {
      rResponse.setContentType("text/html");
      PortletRequestDispatcher prd = getPortletContext().getRequestDispatcher("/WEB-INF/jsp/help.jsp");
      prd.include(rRequest, rResponse);
   }

   protected void doEdit(RenderRequest rRequest, RenderResponse rResponse) throws PortletException, IOException, UnavailableException
   {
      rResponse.setContentType("text/html");
      PortletRequestDispatcher prd = getPortletContext().getRequestDispatcher("/WEB-INF/jsp/edit.jsp");
      prd.include(rRequest, rResponse);
   }
}
               

Now lets look at some of our methods:

  •                            
                               protected void doHelp
    
                               AND
    
                               protected void doEdit
                            

    Support for these Modes must be declared in the portlet.xml. They will be triggered when a user clicks on the respective icons in the portlet window titlebar, or through generated links within the portlet.

  • public void processAction(ActionRequest aRequest, ActionResponse aResponse) throws PortletException, IOException, UnavailableException
    {
       String sYourname = (String) aRequest.getParameter("yourname");
    
       // do something
    
       aResponse.setRenderParameter("yourname", sYourname);
    }
                            

    This method will be triggered upon clicking on an ActionURL from our view.jsp. It will retrieve yourname from the HTML form, and pass it along as a renderParameter to the doView().

  • rResponse.setContentType("text/html");

    Just like in the servlet-world, you must declare what content-type the portlet will be responding in.

  • protected void doView(RenderRequest rRequest, RenderResponse rResponse) throws PortletException, IOException, UnavailableException
    

    In this case, our doView, is responsible for dispatching to the appropriate jsp view.jsp or view2.jsp , depending on the existence of the yourname parameter passed in from the processAction .

5.2.2.4. The Application Descriptors

JBoss Portal requires certain descriptors be included in your portlet war, for different reasons. Some of these descriptors are defined by the Portlet Specification, and some are specific to JBoss Portal. For brevity, we only discuss the portlet.xml descriptor here. For discussion on the other descriptors, please view Section 5.2.1.4, “The Application Descriptors” or the chapter on descriptors: Section 6.1, “Portlet Descriptors” .

  • portlet.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
                 version="1.0">
       <portlet>
          <portlet-name>HelloWorldJSPPortlet</portlet-name>
          <portlet-class>org.jboss.portlet.hello.HelloWorldJSPPortlet</portlet-class>
          <supports>
             <mime-type>text/html</mime-type>
             <portlet-mode>VIEW</portlet-mode>
             <portlet-mode>EDIT</portlet-mode>
             <portlet-mode>HELP</portlet-mode>
          </supports>
          <portlet-info>
             <title>HelloWorld JSP Portlet</title>
          </portlet-info>
       </portlet>
    </portlet-app>

    This file must adhere to its definition in the Portlet Specification. You may define more than one portlet application in this file.

    Note

    This sample portlet supports 3 view modes: VIEW, EDIT, and HELP. The supported modes must be declared in the portlet.xml using the portlet-mode tag. .

5.2.2.5. JSP files and the portlet taglib

Of importance in this tutorial are the two view jsps. The first, allows the user to input his name, which is then posted to the processAction method in our portlet class, set as a renderParameter , then the render method is invoked (in our case its the doView , which then dispatches to our view2.jsp .

Now lets have a look at our view.jsp :

<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>

<portlet:defineObjects/>

<div align="center">
   This is a simple HelloWorld JSP Portlet. Type in a name and it will dispatch to the view2.jsp to print out your name.
   <br/>

   <form action="<portlet:actionURL><portlet:param name="page" value="mainview"/></portlet:actionURL>"
         method="POST">
      Name:<br/>
      <input type="text" name="yourname"/>
   </form>
   <br/>
   You can also link to other pages, using a renderURL, like <a
      href="<portlet:renderURL><portlet:param name="yourname" value="Roy Russo"></portlet:param></portlet:renderURL>">this</a>.
</div>

  •                            <%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>

    Define the portlet taglib. You do not need to bundle the portlet taglib, JBoss Portal will handle that for you.

  • <portlet:defineObjects/>

    Calling defineObjects creates implicit objects in this jsp, that you can access, like: renderRequest, actionRequest, portletConfig .

  •                            <form action="<portlet:actionURL><portlet:param name="page" value="mainview"/></portlet:actionURL>" method="POST">

    We create an HTML form, but generate the URL it will post to, using the portlet tag library. In this case, notice how we are creating an actionURL , which will activate out processAction method, passing in any input parameters in the form.

  • <a href="<portlet:renderURL><portlet:param name="yourname" value="Roy Russo"></portlet:param></portlet:renderURL>">

    Likewise, we are able to create a link to our doView , by simply creating it with a renderURL , that passes in our yourname parameter.

5.2.2.6. Building your portlet

If you have downloaded the sample, you can execute the build.xml with ANT or inside your IDE. Executing the deploy target will compile all src files and produce a helloworldportlet.war under HelloWorldPortlet\helloworldjspportlet.war.

If you want to create an expanded war directory, after executing the above deploy target, you should execute the explode target.

The above target will produce the following:

This will deflate the helloworldjspportlet.war, and allow you to deploy it as an expanded directory. It will work just the same, with some additional benefits noted below:

The advantage to expanded war deployments is that you can modify xml descriptors, resource files jsp/jsf pages easily during development. Simply touch the web.xml to have JBoss Application Server hot-deploy the web appllication on a live-running server instance

5.2.2.7. Deploying your portlet

Deploying a portlet is as simple as copying/moving the helloworldjspportlet.war in to the server deploy directory. Doing this on a running instance of the portal and application server, will trigger a hot-deploy :

15:54:34,234 INFO  [Server] JBoss (MX MicroKernel) [4.0.4.CR2 (build: CVSTag=JBoss_4_0_4_CR2 date=200603311500)] Started in 1m:9s:766ms
15:55:04,062 INFO  [TomcatDeployer] deploy, ctxPath=/helloworldjspportlet, warUrl=.../tmp/deploy/tmp57782helloworldjspportlet-exp.war/
               

Pointing your browser to http://localhost:8080/portal/ , should yield a view of our HelloWorldPortlet:

5.2.3. A Simple JSF Portlet

5.2.3.1. Introduction

This section will introduce the reader to deploying a simple JSF portlet in JBoss Portal. It requires you download the HelloWorldJSFPortlet from PortletSwap.com, using this link .

This portlet will introduce you to leveraging the JSF framework in portlet development.

5.2.3.2. Package Structure

Portlets are packaged in war files, just like other JEE applications. A typical portlet war file can also include servlets, resource bundles, images, html, jsps, and other static or dynamic files you would commonly include.

Like a typical JSF application, we also package our faces-config.xml that defines our managed-beans, converters, validators, navigation rules, etc...

Note

When deploying on JBoss Application Seever, you do not need to package the myfaces libraries with your portlet application. JBoss AS already bundles these libraries by default under JBOSS_HOME/server/default/deploy/jbossweb-tomcat55.sar/jsf-libs/

5.2.3.3. The Application Descriptors

JBoss Portal requires certain descriptors be included in your portlet war, for different reasons. Some of these descriptors are defined by the Portlet Specification, and some are specific to JBoss Portal. For brevity, we only discuss the portlet.xml and faces-config.xml descriptors here. For discussion on the other descriptors, please view Section 5.2.1.4, “The Application Descriptors” or the chapter on descriptors: Section 6.1, “Portlet Descriptors” .

  • portlet.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
                 version="1.0">
       <portlet>
          <portlet-name>HelloWorldJSFPortlet</portlet-name>
          <portlet-class>org.apache.myfaces.portlet.MyFacesGenericPortlet</portlet-class>
          <init-param>
             <name>default-view</name>
             <value>/WEB-INF/jsp/index.jsp</value>
          </init-param>
          <supports>
             <mime-type>text/html</mime-type>
             <portlet-mode>VIEW</portlet-mode>
          </supports>
          <portlet-info>
             <title>HelloWorld JSF Portlet</title>
          </portlet-info>
       </portlet>
    </portlet-app>

    This file must adhere to its definition in the Portlet Specification. You may define more than one portlet application in this file. Now lets look at the portions that deal with our use of JSF:

    • Here we define our portlet class, as we normally would. However, note the use of the MyFacesGenericPortlet. In this case, we will allow the MyFacesGenericPortlet to handle all requests/responses from our users:

      <portlet-class>org.apache.myfaces.portlet.MyFacesGenericPortlet</portlet-class>

      Note

      If you wanted to add more functionality to your JSF portlet, not included in the MyFacesGenericPortlet, you could sublass it and create your own Class.

    • We need to initialize the portlet with a default view page for it to render, much like a welcome page:

      <init-param>
         <name>default-view</name>
         <value>/WEB-INF/jsp/index.jsp</value>
      </init-param>

  • faces-config.xml

    <?xml version="1.0"?>
    <!DOCTYPE faces-config PUBLIC
       "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
       "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
    <faces-config>
       <managed-bean>
          <description>Basic UserBean</description>
          <managed-bean-name>user</managed-bean-name>
          <managed-bean-class>org.jboss.portlet.hello.bean.User</managed-bean-class>
          <managed-bean-scope>session</managed-bean-scope>
       </managed-bean>
       <navigation-rule>
          <navigation-case>
             <from-outcome>done</from-outcome>
             <to-view-id>/WEB-INF/jsp/result.jsp</to-view-id>
          </navigation-case>
       </navigation-rule>
    </faces-config>

    There is nothing special about the faces-config.xml included here. This application would work just as well outside of a portlet as it would inside a portlet container. In the above lines, we define a basic User Bean and a navigation rule to handle the submittal of the original form on the index.jsp.

5.2.3.4. The JSP files

5.2.3.5. Building your portlet

If you have downloaded the sample, you can execute the build.xml with ANT or inside your IDE. Executing the deploy target will compile all src files and produce a helloworldjsfportlet.war under HelloWorldJSFPortlet\helloworldjsfportlet.war.

If you want to create an expanded war directory, after executing the above deploy target, you should execute the explode target.

The above target will produce the following:

This will deflate the helloworldjsfportlet.war, and allow you to deploy it as an expanded directory. It will work just the same, with some additional benefits noted below:

The advantage to expanded war deployments is that you can modify xml descriptors, resource files jsp/jsf pages easily during development. Simply touch the web.xml to have JBoss Application Server hot-deploy the web application on a live-running server instance

5.2.3.6. Deploying your portlet

Deploying a portlet is as simple as copying/moving the helloworldjsfportlet.war in to the server deploy directory. Doing this on a running instance of the portal and application server, will trigger a hot-deploy :

22:30:03,093 INFO  [TomcatDeployer] deploy, ctxPath=/helloworldjsfportlet, warUrl=.../tmp/deploy/tmp5571helloworldjsfportlet-exp.war/
22:30:03,312 INFO  [FacesConfigurator] Reading standard config org/apache/myfaces/resource/standard-faces-config.xml
22:30:03,390 INFO  [FacesConfigurator] Reading config jar:file:/C:/jboss-4.0.4.CR2/server/default/tmp/deploy/tmp5504jboss-portal.sar-contents/lib/jsf-facelets.jar!/META-INF/faces-config.xml
22:30:03,406 INFO  [FacesConfigurator] Reading config jar:file:/C:/jboss-4.0.4.CR2/server/default/tmp/deploy/tmp5504jboss-portal.sar-contents/lib/tomahawk.jar!/META-INF/faces-config.xml
22:30:03,468 INFO  [FacesConfigurator] Reading config /WEB-INF/faces-config.xml
22:30:03,484 ERROR [LocaleUtils] Locale name null or empty, ignoring
22:30:03,640 INFO  [MyFacesGenericPortlet] PortletContext 'C:\jboss-4.0.4.CR2\server\default\.\tmp\deploy\tmp5571helloworldjsfportlet-exp.war\' initialized.

Pointing your browser to http://localhost:8080/portal/ , should yield a view of our HelloWorldJSFPortlet:

Chapter 6. XML Descriptors

Roy Russo

6.1. Portlet Descriptors

To define your portal objects (portals, pages, portlet instances, windows, and portlets), you will be using the descriptors found in this section. This section seeks to describe these descriptors. It is recommended you also look at Section 5.2, “Tutorials” and Section 6.3, “Descriptor Examples” for samples on how they are used within a portlet application.

6.1.1. *-object.xml

The *-object.xml file is used to define: portal instances, pages, windows, window layout. Additionally, you can also specify the themes and layouts used for specific portal instances, pages, and windows. The description below, only defines a portlet window being added to the default page in the default portal. For advanced functionality, using this descriptor, please read Section 6.3, “Descriptor Examples” .

<?xml version="1.0" encoding="UTF-8"?>
<deployments>
   <deployment>
      <if-exists>overwrite</if-exists>
      <parent-ref>default.default</parent-ref>
      <window>
         <window-name>HelloWorldJSPPortletWindow</window-name>
         <instance-ref>HelloWorldJSPPortletInstance</instance-ref>
         <region>center</region>
         <height>1</height>
      </window>
   </deployment>
</deployments>

  • <deployments>...</deployments>

    The deployments tag, encapsulates the entire document. You may specify more than one deployment within this tag.

  • <deployment>...</deployment>

    The deployment tag is used to specify object deployments: portals, pages, windows, etc...

  • <if-exists>...</if-exists>

    Possible values are overwrite or keep . Overwrite will destroy the existing object in the database and create a new one, based on the content of the deployment. Keep will maintain the existing object deployment or create a new one if it does not yet exist.

  • <parent-ref>...</parent-ref>

    The parent-ref tag specifies where a particulare object will exist within the portal object tree. In our example, above, we are defining a window and assigning it to default.default , interpreted, this means the window will appear in the default portal and the default page within it.

  • <window>...</window>

    Used to define a portlet window. You will then need to assign to this window, a portlet instance and assign it to a layout region.

  • <window-name>...</window-name>

    A unique name given to this portlet window.

  • <instance-ref>...</instance-ref>

    The portlet instance that this window will represent. It must correspond to the value of instance-id , assigned in your portlet-instances.xml

  • <region>...</region><height>...</height>

    The values are used to specify where this window will appear within the page layout. Region often depends on regions defined in your layout. Height can be any number between 0-X.

The example *-object.xml, above, makes reference to items found in other descriptor files. To help with this topic, we have included a sample image that depicts the relationship:

6.1.2. portlet-instances.xml

This is a JBoss Portal specific descriptor that allows a developer to instantiate one-or-many instances of one-or-many portlets. The benefit of using this technique, is to allow one portlet to be instantiated several times with different preference parameters.

Note

Is this descriptor mandatory? Technically, no, as you can deploy your portlet without this descriptor AND without the *-object.xml and then use the management portlet to create instances, assign the instances to windows, and then assign the windows to pages.

Our example, below, has us instantiating two separate instances of the NewsPortlet with different preference parameters, one instance will draw a feed for RedHat announcements and the other from McDonalds announcements.

<?xml version="1.0" standalone="yes"?>
<deployments>
   <deployment>
      <instance>
         <instance-id>NewsPortletInstance2</instance-id>
         <portlet-ref>NewsPortlet</portlet-ref>
         <preferences>
            <preference>
               <name>expires</name>
               <value>180</value>
            </preference>
            <preference>
               <name>RssXml</name>
               <value>http://finance.yahoo.com/rss/headline?s=rhat</value>
            </preference>
         </preferences>
         <security-constraint>
            <policy-permission>
               <unchecked/>
               <action-name>view</action-name>
            </policy-permission>
         </security-constraint>
      </instance>
   </deployment>
   <deployment>
      <instance>
         <instance-id>NewsPortletInstance2</instance-id>
         <portlet-ref>NewsPortlet</portlet-ref>
         <preferences>
            <preference>
               <name>expires</name>
               <value>180</value>
            </preference>
            <preference>
               <name>RssXml</name>
               <value>http://finance.yahoo.com/rss/headline?s=mcd</value>
            </preference>
         </preferences>
         <security-constraint>
            <policy-permission>
               <unchecked/>
               <action-name>view</action-name>
            </policy-permission>
         </security-constraint>
      </instance>
   </deployment>
</deployments>

  • <deployments>...</deployments>

    The deployments tag, encapsulates the entire document. You may specify more than one portlet instance deployment, within this tag.

  • <deployment><instance>...</instance></deployment>

    The deployment , and embedded instance tags are used to specify one portlet instance.

  • <instance-id>...</instance-id>

    A unique name given to this instance of the portlet. It must correspond to the value of instance-ref , assigned to the window in your *-object.xml .

  • <portlet-ref>...</portlet-ref>

    The portlet that this instance will represent. It must correspond to the value of portlet-name , assigned in your portlet.xml .

  •                         <preferences><preference>...</preference></preferences>

    Preferences for this portlet instance are defined here, as type String, in a key-value pair style. It is also possible to specify preferences as type String[], as in:

    <preferences>
       <preference>
          <name>fruit</name>
          <value>apple</value>
          <value>orange</value>
          <value>kiwi</value>
       </preference>
    </preferences>
    

  • <security-constraint>
       <policy-permission>
          <unchecked/>
          <action-name>viewrecursive</action-name>
       </policy-permission>
    </security-constraint>

    The security contraint portion is worth taking a look at, in an isolated fashion. It allows you to secure a specific portlet instance based on a user's role.

    Role definition: You must define a role that this security constraint will apply to. Possible values are:

    • <unchecked/> Anyone can view this page.
    • <role-name>SOMEROLE</role-name> Access to this page is limited to the defined role.

    Access Rights: You must define the access rights given to the role defined. Possible values are:

    • view Users can view the page.
    • viewrecursive Users can view the page and child pages.
    • personalize Users are able to view AND personalize the page.
    • personalizerecursive Users are able to view AND personalize the page AND its child pages.

The example portlet-instances.xml, above, makes reference to items found in other descriptor files. To help with this topic, we have included a sample image that depicts the relationship:

6.1.3. jboss-portlet.xml

This descriptor is not mandatory, but is useful when having to add JBoss-Specific contexts to your portlet descriptor. It would normally be packaged inside your portlet war, alongside the other descriptors in this section.

6.1.3.1. Injecting Header Content

<portlet-app>
   <portlet>
      <portlet-name>ManagementPortlet</portlet-name>
      <header-content>
         <link rel="stylesheet" type="text/css" href="/images/management/management.css" title="" media="screen"/>
      </header-content>
   </portlet>
</portlet-app>

The above example will inject a specific style sheet link in the top of the portal page, allowing this portlet to leverage its specific style selectors.

6.1.3.2. Injecting Services in the portlet context

<portlet-app>
   <service>
      <service-name>UserModule</service-name>
      <service-class>org.jboss.portal.identity.UserModule</service-class>
      <service-ref>:service=Module,type=User</service-ref>
   </service>
</portlet-app>

Injects the UserModule service in to the portlet context, allowing a portlet to then leverage the service. For example:

UserModule userModule = (UserModule) getPortletContext().getAttribute("UserModule");
String userId = request.getParameters().getParameter("userid");
User user = userModule.findUserById(userId);

6.1.3.3. Portlet Session Replication in a Clustered Environment

See Section 8.5, “Portlet Session Replication”

6.1.4. portlet.xml

This is the standard portlet descriptor covered by the JSR-168 Specification. It is advisable that developers read the specification items covering proper use of this descriptor, as it is only covered here briefly. For example purposes, we use an editted version of our JBoss Portal UserPortlet definition. Normally, you would package this descriptor in your portlet war.

<?xml version="1.0" encoding="UTF-8"?>
<portlet-app
      xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
      version="1.0">
   <portlet>
      <description>Portlet providing user login/logout and profile management</description>
      <portlet-name>UserPortlet</portlet-name>
      <display-name>User Portlet</display-name>
      <portlet-class>org.jboss.portal.core.portlet.user.UserPortlet</portlet-class>
      <init-param>
         <description>Whether we should use ssl on login and throughout the Portal. 1=yes;0=no</description>
         <name>useSSL</name>
         <value>0</value>
      </init-param>
      <supports>
         <mime-type>text/html</mime-type>
         <portlet-mode>VIEW</portlet-mode>
      </supports>
      <supported-locale>en</supported-locale>
      <supported-locale>fr</supported-locale>
      <supported-locale>es</supported-locale>
      <resource-bundle>Resource</resource-bundle>
      <portlet-info>
         <title>User portlet</title>
      </portlet-info>
   </portlet>
</portlet-app>

  • <portlet-app>...</portlet-app>

    The portlet-app tag, encapsulates the entire document. You may specify more than one portlet, within this tag.

  • <portlet>...</portlet>

    The portlet tag is used to define one portlet that is deployed withing this archive.

  • <description>...</description>

    A verbal description of tis portlet's function.

  • <portlet-name>...</portlet-name>

    The name of this portlet, usually the class name

  • <portlet-class>...</portlet-class>

    The fully-qualified-name of this portlet class.

  •                         <init-param><name>...</name><value>...</value></init-param>

    Using the init-param tag, you can specify initialization parameters to create initial state inside your portlet class. Normally, they would be used in the portlet's init() method. You can specify more than one init-param.

  • <supports>...</supports>

    Here, you would advertise the supported mime-type and supported portlet-modes for this portlet.

  • <supported-locale>...</supported-locale>

    Here, you would advertise the supported locales for this portlet. You can specify many.

  • <resource-bundle>...</resource-bundle>

    The resource bundle that will back the locales specified.

  • <portlet-info><title>...</title></portlet-info>

    The portlet title that will be displayed in the portlet window's title bar.

Note

This is a simple portlet.xml primer, and is not meant as a replacement for what is covered in the actual Portlet specification.

6.2. JBoss Portal Descriptors

6.2.1. Datasource Descriptor (portal-*-ds.xml)

JBoss Portal requires a Datasource descriptor to be deployed alongside the jboss-portal.sar for access to a database. This section does not explain what a Datasource Descriptor is, but does explain where to obtain some templates that you can configure for your own installation.

Note

For an in-depth introduction to datasources, you can view the JBoss AS documentation online here .

6.2.1.1. Obtaining Datasource Descriptors Binary releases

Several template datasource descriptors can be found in the binary and bundle distributions. They are commonly located under the setup directory:

The directory setup should contain the following files, that you can customize for your own Database/Connector:

6.2.1.2. Building Datasource Descriptors from Source

You will need a valid datasource descriptor, for JBoss Portal to communicate with your database. Having obtained the sources and having set your JBOSS_HOME environment variable ( Section 2.3.2.2, “Operating System Environment Setting” ), you can now have the JBoss Portal build system generate preconfigured datasources for you.

Navigate to JBOSS_PORTAL_HOME_DIRECTORY/core and type:

build datasource

Once complete, the datasource build should produce the following directory and file structure:

At this point, you should configure the one that suits you best with your Database and JDBC driver.

<?xml version="1.0" encoding="UTF-8"?>
<datasources>
  <local-tx-datasource>
    <jndi-name>PortalDS</jndi-name>
    <connection-url>jdbc:postgresql:jbossportal</connection-url>
    <driver-class>org.postgresql.Driver</driver-class>
    <user-name>portal</user-name>
    <password>portalpassword</password>
  </local-tx-datasource>
</datasources>
                  

Please verify that the username, password, url, and driver-class are correct for your flavor of DB.

6.2.2. Portlet Debugging (jboss-portal.sar/conf/config.xml)

By default, JBoss Portal ships with all errors set to display. You can fine-tune this behaviour by modifying the file, jboss-portal.sar/conf/config.xml :

<properties>
   <!-- When a window has restrictedaccess : show or hide values are permitted -->
   <entry key="core.render.window_access_denied">show</entry>
   <!-- When a window is unavailable : show or hide values are permitted -->
   <entry key="core.render.window_unavailable">show</entry>
   <!-- When a window produces an error : show, hide or message_only values are permitted -->
   <entry key="core.render.window_error">message_only</entry>
   <!-- When a window produces an internal error : show, hide are permitted -->
   <entry key="core.render.window_internal_error">show</entry>
   <!-- When a window is not found : show or hide values are permitted -->
   <entry key="core.render.window_not_found">show</entry>
</properties>

Either show or hide are allowed as flags in these elements. Depending on the setting and actual error, either an error message is deployed or a full stack trace within the portlet window. Additionally, the core.render.window_error property supports the message_only value. This value will only display the error message whereas show will display the full stack trace if it is available.

6.3. Descriptor Examples

6.3.1. Defining a new portal page

This sample application and descriptor will create a new page, named MyPage in your portal. To illustrate our example, we have made available a portlet with a page descriptor that you can download here: HelloWorld Page .

Note

To use this example, simply extract the zip, and deploy the helloworldportalpage.war where your portal is running (hot-deployment supported).

Our sample includes a descriptor to define this new portal page, helloworld-object.xml , located under helloworldportalpage.war/WEB-INF/ , and it looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<deployments>
   <deployment>
      <if-exists>overwrite</if-exists>
      <parent-ref>default</parent-ref>
      <properties/>
      <page>
         <page-name>MyPage</page-name>
         <window>
            <window-name>HelloWorldPortletPageWindow</window-name>
            <instance-ref>HelloWorldPortletPageInstance</instance-ref>
            <region>center</region>
            <height>0</height>
         </window>
         <security-constraint>
            <policy-permission>
               <unchecked/>
               <action-name>viewrecursive</action-name>
            </policy-permission>
         </security-constraint>
      </page>
   </deployment>
</deployments>
            

A deployment file can be composed of a set of <deployments>. In our example file, above, we are defining a page, placing the portlet as a window on that page, and creating an instance of that portlet. You can then use the Management Portlet (bundled with JBoss Portal) to modify the instances of this portlet, reposition it, and so on...

  • <if-exists> Possible values are overwrite or keep . Overwrite will destroy the existing object and create a new one based on the content of the deployment. Keep will maintain the existing objct deployment or create a new one if it does not yet exist.
  • <parent-ref> Indicates whether the object should be hooked in to the portal tree.
  • <properties> Properties definition specific to this page, commonly used to define the specific theme and layout to use. If not defined, the default portal layouts/theme combination will be used.
  • <page> The start of a page definition.
  • <page-name> The name of the page.
  • <window> The start of a window definition.
  • <window-name> The name of the window.
  • <instance-ref> The instance reference used by this window. Should correspond with the <instance-name> variable.
  • <height> The vertical position of this window within the region defined in the layout.
  • <instance> The start of an instance definition. page.
  • <instance-name> Maps to the above <instance-ref> variable.
  • <component-ref> Takes the name of the application followed by the name of the portlet, as defined in the portlet.xml
  • <security-constraint>
       <policy-permission>
          <unchecked/>
          <action-name>viewrecursive</action-name>
       </policy-permission>
    </security-constraint>

    The security contraint portion is worth taking a look at, in an isolated fashion. It allows you to secure a specific page/portal based on a user's role.

    Role definition: You must define a role that this security constraint will apply to. Possible values are:

    • <unchecked/> Anyone can view this page.
    • <role-name>SOMEROLE</role-name> Access to this page is limited to the defined role.

    Access Rights: You must define the access rights given to the role defined. Possible values are:

    • view Users can view the page.
    • viewrecursive Users can view the page and child pages.
    • personalize Users are able to view AND personalize the page.
    • personalizerecursive Users are able to view AND personalize the page AND its child pages.

6.3.2. Defining a new portal instance

To illustrate our example, we have made available a portlet that you can download here: HelloPortal .

For our example we make available helloworld-object.xml located under helloworldportal.war/WEB-INF/ , and it looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<deployments>
   <deployment>
      <parent-ref/>
      <if-exists>overwrite</if-exists>
      <portal>
         <portal-name>HelloPortal</portal-name>
         <properties>
            <!-- Set the layout for the default portal -->
            <!-- see also portal-layouts.xml -->
            <property>
               <name>layout.id</name>
               <value>generic</value>
            </property>
            <!-- Set the theme for the default portal -->
            <!-- see also portal-themes.xml -->
            <property>
               <name>theme.id</name>
               <value>Nphalanx</value>
            </property>
            <!-- set the default render set name (used by the render tag in layouts) -->
            <!-- see also portal-renderSet.xml -->
            <property>
               <name>theme.renderSetId</name>
               <value>divRenderer</value>
            </property>
            <!-- set the default strategy name (used by the strategy interceptor) -->
            <!-- see also portal-strategies.xml -->
            <property>
               <name>layout.strategyId</name>
               <value>maximizedRegion</value>
            </property>
         </properties>
         <supported-modes>
            <mode>view</mode>
            <mode>edit</mode>
            <mode>help</mode>
         </supported-modes>
         <supported-window-states>
            <window-state>normal</window-state>
            <window-state>minimized</window-state>
            <window-state>maximized</window-state>
         </supported-window-states>
         <page>
            <page-name>default</page-name>
            <properties/>
            <window>
               <window-name>MyPortletWindow</window-name>
               <instance-ref>MyPortletInstance</instance-ref>
               <region>center</region>
               <height>0</height>
            </window>
            <security-constraint>
               <policy-permission>
                  <unchecked/>
                  <action-name>viewrecursive</action-name>
               </policy-permission>
            </security-constraint>
         </page>
         <security-constraint>
            <policy-permission>
               <unchecked/>
               <action-name>personalizerecursive</action-name>
            </policy-permission>
         </security-constraint>
      </portal>
   </deployment>
   <deployment>
      <if-exists>overwrite</if-exists>
      <parent-ref>HelloPortal</parent-ref>
      <page>
         <page-name>foobar</page-name>
         <window>
            <window-name>MyPortletWindow</window-name>
            <instance-ref>MyPortletInstance</instance-ref>
            <region>center</region>
            <height>0</height>
         </window>
         <security-constraint>
            <policy-permission>
               <unchecked/>
               <action-name>viewrecursive</action-name>
            </policy-permission>
         </security-constraint>
      </page>
   </deployment>
</deployments>
            

This example, when deployed, will register a new portal instance named HelloPortal with two pages in it. The portal instance can be accessed by navigating to: http://localhost:8080/portal/portal/HelloPortal for the default page, and http://localhost:8080/portal/portal/HelloPortal/foobar , for the second page created.

Note

You must define a page named default for any new portal instance to be accessible via a web browser.

Chapter 7. Portal urls

Julien Viet

Thomas Heute

Roy Russo

7.1. Introduction

Most of the time portals use very complicated urls, however it is possible to setup entry points in the portal that follow simple patterns.

Each portal container can contain multiple portals and within a given portal, windows are organized in pages, a page simply being a collection of windows associated to a name.

Before reading this chapter you must know how to define a page and a portal, you can refer to the chapter about XML descriptors to have a better understanding of those notions.

7.2. Acessing a portal

Each portal container can contains multiple portals, also there is one special portal which is the default portal, i.e the one used when no portal is specified in particular.

  • "/", will point to the default page of the default portal.
  • "/portal/portalname/" will point to the default page of the portal portalname

7.3. Accessing a page

It is possible to have multiple pages per portal. As for portal there is a default page for a given portal. Once the portal has been selected, then a page must be used and all the windows present in that page will be rendered. The page selection mechanism is the following.

  • "/portal/default/pageName" will render the pageName page.

7.4. Accessing CMS Content

The CMSPortlet delivers content transparently, without modifying the url displayed. However, if you wish to deliver binary content (gif, jpeg, pdf, zip, etc...), it is desirable to display this content outside of the confines of the portal.

  • "/content/default/images/jboss_logo.gif" will display the jboss_logo.gif outside of the portal. This is accomplished as the portal interprets any path beginning with /content as a request for CMS content. As long as the mime-type is not text/html or text/text, it will be rendered independant of the portal.

Chapter 8. Clustering Configuration

Roy Russo

This section covers configuring JBoss Portal to function in a clustered environment.

8.1. Introduction

JBoss Portal leverages various clustered services that are found in JBoss Application Server. This section briefly details how each is leveraged:

  • JBoss Cache: Used to replicate data among the different hibernate session factories that are deployed in each node of the cluster.

  • JBoss HA Singleton:

    1. Used to make the deployer a singleton on the cluster, in order to avoid concurrency issues when deploying the various *-object.xml files. Without that, each node would try to create the same objects in the database when it deploys an archive containing such descriptors.
    2. Used with JCR. The jackrabbit server is not able to run in a cluster by itself, therefore we make a singleton on the cluster. This provides HA-CMS, which is similar to the current HA JBossMQ provided in JBoss AS.

  • HA-JNDI: Used to replicate a proxy that will talk to the HA CMS on the cluster.

  • Http Session Replication: Used to replicate the portal and the portlet sessions.

  • JBoss SSO: Used to replicate the user identity, an authenticated user does not have to login again when failover occurs.

Note

JBoss Clustering details can be found in the Wiki or the clustering documentation.

8.2. Considerations

When you want to run JBoss Portal on a cluster there are a few things to keep in mind:

  • Deploy the portal under the all application server configuration as it contains the clustering services that JBoss Portal leverages.
  • All the portal instances have to use the same datasource : the database is used to store the portal persistent state like pages. If you don't use a shared database then you will have consitency problems.

8.3. JBoss Portal Clustered Services

8.3.1. Portal Session Replication

The portal associates with each user an http session in order to keep specific objects such as:

  • Navigational state : this is mainly the state of the different portlet windows that the user will manipulate during its interactions with the portal. For instance a maximized portlet window with specific render parameters.
  • WSRP objects : the WSRP protocol can require to provide specific cookies during interactions with a remote portlet.

Replicating the portal session ensures that this state will be kept in sync on the cluster, e.g he will see the portlet window he uses exactly the same on every node. The activation of the portal session replication is made through the configuration of the web application that is the main entry point of the portal. This setting is available in the file jboss-portal.sar/portal-server.war/WEB-INF/web.xml

<web-app>
   <description>JBoss Portal</description>
   <!-- Comment/Uncomment to enable portal session replication -->
   <distributable/>
   ...
</web-app>

8.3.2. Hibernate clustering

JBoss Portal leverages hibernate for its database access. In order to improve performances it uses the caching features provided by hibernate. On a cluster the cache needs to be replicated in order to avoid state inconsistencies. Hibernate is configured with JBoss Cache which performs that synchronization transparently. Therefore the different hibernate services must be configured to use JBoss Cache. The following hibernate configurations needs to use a replicated JBoss Cache :

  • jboss-portal.sar/conf/hibernate/user/hibernate.cfg.xml
  • jboss-portal.sar/conf/hibernate/instances/hibernate.cfg.xml
  • jboss-portal.sar/conf/hibernate/portal/hibernate.cfg.xml
  • jboss-portal.sar/conf/hibernate/portlet/hibernate.cfg.xml

The cache configuration should look like :

<!--
   | Uncomment in clustered mode : use transactional replicated cache
   -->
   <property name="cache.provider_class">org.jboss.portal.core.hibernate.JMXTreeCacheProvider</property>
   <property name="cache.object_name">portal:service=TreeCacheProvider,type=hibernate</property>

<!--
   | Comment in clustered mode
   <property name="cache.provider_configuration_file_resource_path">conf/hibernate/instance/ehcache.xml</property>
   <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
-->

Also we need to ensure that the cache is deployed by having in the file jboss-portal.sar/META-INF/jboss-service.xml the cache service uncommented :

<!--
   | Uncomment in clustered mode : replicated cache for hibernate
   -->
   <mbean
   code="org.jboss.cache.TreeCache"
   name="portal:service=TreeCache,type=hibernate">
   <depends>jboss:service=Naming</depends>
   <depends>jboss:service=TransactionManager</depends>
   <attribute name="TransactionManagerLookupClass">org.jboss.cache.JBossTransactionManagerLookup</attribute>
   <attribute name="IsolationLevel">REPEATABLE_READ</attribute>
   <attribute name="CacheMode">REPL_SYNC</attribute>
   <attribute name="ClusterName">portal.hibernate</attribute>
   </mbean>

   <mbean
   code="org.jboss.portal.core.hibernate.JBossTreeCacheProvider"
   name="portal:service=TreeCacheProvider,type=hibernate">
   <depends optional-attribute-name="CacheName">portal:service=TreeCache,type=hibernate</depends>
   </mbean>

More information can be found here.

8.3.3. Identity clustering

JBoss Portal leverages the servlet container authentication for its own authentication mechanism. When the user is authenticated on one particular node he will have to reauthenticate again if he use another node of the cluster (during a failover for instance). This is valid only for the FORM based authentication which is the default form of authentication that JBoss Portal uses. Fortunately JBoss provides transparent reauthentication of the user called JBoss clustered SSO. Its configuration is in the file $JBOSS_HOME/server/all/deploy/jbossweb-tomcat55.sar/server.xml and the clustered sso valve shall be uncommented

<Valve className="org.jboss.web.tomcat.tc5.sso.ClusteredSingleSignOn" />

More information can be found here.

8.3.4. CMS clustering

The CMS backend storage relies on the Apache Jackrabbit project. Jackrabbit does not support clustering out of the box. So the portal run the Jackrabbit servicey on one node of the cluster using the HA-Singleton technology. The file jboss-portal.sar/portal-cms.sar/META-INF/jboss-service.xml contains the configuration. We will not reproduce it in this documentation as the changes are quite complex and numerous. Access from all nodes of the cluster is provided by a proxy bound in HA-JNDI. In order to avoid any bottleneck JBoss Cache is leveraged to cache CMS content cluster wide.

8.4. Setup

We are going to outline how to setup a two node cluster on the same machine in order to test JBoss Portal HA. The only missing part from the full fledged setup is the addition of a load balancer in front of Tomcat. However a lot of documentation exist on the subject. A detailed step by step setup of Apache and mod_jk is available from the JBoss Wiki.

As we need two application servers running at the same time, we must avoid any conflict. For instance we will need Tomcat to bind its socket on two different ports otherwise a network conflict will occur. We will leverage the service binding manager this chapter of the JBoss AS documentation.

The first step is to copy the all configuration of JBoss into two separate configurations that we name ports-01 and ports-02 :

>cd $JBOSS_HOME/server
>cp -r all ports-01
>cp -r all ports-02

Edit the file $JBOSS_HOME/server/ports-01/conf/jboss-service.xml and uncomment the service binding manager :

<mbean code="org.jboss.services.binding.ServiceBindingManager"
   name="jboss.system:service=ServiceBindingManager">
   <attribute name="ServerName">ports-01</attribute>
   <attribute name="StoreURL">${jboss.home.url}/docs/examples/binding-manager/sample-bindings.xml</attribute>
   <attribute name="StoreFactoryClassName">org.jboss.services.binding.XMLServicesStoreFactory</attribute>
</mbean>

Edit the file $JBOSS_HOME/server/ports-02/conf/jboss-service.xml, uncomment the service binding manager and change the value ports-01 into ports-02:

<mbean code="org.jboss.services.binding.ServiceBindingManager"
   name="jboss.system:service=ServiceBindingManager">
   <attribute name="ServerName">node-02</attribute>
   <attribute name="StoreURL">${jboss.home.url}/docs/examples/binding-manager/sample-bindings.xml</attribute>
   <attribute name="StoreFactoryClassName">org.jboss.services.binding.XMLServicesStoreFactory</attribute>
</mbean>

Setup a database that will be shared by the two nodes and obviously we cannot use an embedded database. For instance using postgresql we would copy the file portal-postgresql-ds.xml into $JBOSS_HOME/server/ports-01/all and $JBOSS_HOME/server/ports-02/all.

Copy JBoss Portal HA to the deploy directory of the two configurations.

JBoss Cache Configuration Note : To improve CMS performance JBoss Cache is leveraged to cache the content cluster wide. We recommend that you use the following version of JBoss Cache for best performance:

  • JBoss Cache 1.4.0.SP1 and above
  • JGroups 2.2.7 or 2.2.8

When building from source the following command: {core}/build.xml deploy-ha automatically upgrades your JBoss Cache version.

Alternative: If upgrading your JBoss Cache version is not an option, the following configuration change is needed in the jboss-portal-ha.sar/portal-cms.sar/META-INF/jboss-service.xml. Replace the following configuration in the cms.pm.cache:service=TreeCache Mbean:

		  <!--
           		Configuring the PortalCMSCacheLoader
           		
           		CacheLoader configuration for 1.4.0
           -->           
           <attribute name="CacheLoaderConfiguration">
               <config>                
                   <passivation>false</passivation>
                   <preload></preload>
                   <shared>false</shared>
                   <cacheloader>
                       <class>org.jboss.portal.cms.hibernate.state.PortalCMSCacheLoader</class>
                       <properties></properties>
                       <async>false</async>
                       <fetchPersistentState>false</fetchPersistentState>
                       <ignoreModifications>false</ignoreModifications>
                   </cacheloader>
               </config>
           </attribute>
		
	  

with the following configuration:

		  <!--
           		Configuring the PortalCMSCacheLoader
           		
           		CacheLoader configuratoon for 1.2.4SP2
           --> 
           <attribute name="CacheLoaderClass">org.jboss.portal.cms.hibernate.state.PortalCMSCacheLoader</attribute>       
           <attribute name="CacheLoaderConfig" replace="false"></attribute>
           <attribute name="CacheLoaderPassivation">false</attribute>
           <attribute name="CacheLoaderPreload"></attribute>
           <attribute name="CacheLoaderShared">false</attribute>           
           <attribute name="CacheLoaderFetchTransientState">false</attribute>
           <attribute name="CacheLoaderFetchPersistentState">false</attribute>
           <attribute name="CacheLoaderAsynchronous">false</attribute>        
	

Finally we can start both servers, open two shells and execute :

>cd $JBOSS_HOME/bin
>./run.sh -c ports-01

>cd $JBOSS_HOME/bin
>./run.sh -c ports-02

8.5. Portlet Session Replication

Web containers offer the capability to replicate sessions of web applications. In the context of a portal using portlets the use case is different. The portal itself is a web application that benefits of web application session replication. We have to make the distinction between local or remote portlets :

  • Local portlets are web applications deployed in the same virtual machine as the portal web application. At runtime the access to a portlet is done using the mechanism of request dispatching. The portlet session is actually a mere wrapper of the underlying http session of the web application in which the portlet is deployed.
  • Remote portlets are accessed using a web service, we will not cover the replication in this chapter.

The servlet specification is very loose on the subject of replication and does not state anything about the replication of sessions during a dispatched request. JBoss Portal offers a portlet session replication mechanism that leverages the usage of the portal session instead which has several advantages

  • Replicate only the portlet that requires it.
  • Portal session replication is just web application replication and is very standard.

There are also some limitation such has you can only replicate portlet scoped attributes of a portlet session. It means that any attribute scoped using application scope are not replicated.

8.5.1. JBoss Portal configuration

The mandatory step to make JBoss Portal able to replicate portlet sessions is to configure the portal web application to be distributed which is explained in Section 8.3.1, “Portal Session Replication”

8.5.2. Portlet configuration

In order to activate portlet session replication you need to

  • Add in the /WEB-INF/web.xml file of your web application a specific listener class
  • Configure your portlet to be distributed in the /WEB-INF/jboss-portlet.xml file.

<web-app>
   ...
   <listener>
      <listener-class> org.jboss.portal.portlet.session.SessionListener </listener-class>
   </listener>
   ...
</web-app>

Example of web.xml file of your web application

<portlet-app>
   ...
   <portlet>
      <portlet-name>YourPortlet</portlet-name>
      ...
      <session-config>
         <distributed>true</distributed>
      </session-config>
      ...
   </portlet>
   ...
</portlet-app>

Configure YourPortlet to be replicated in jboss-portlet.xml

8.5.3. Limitations

As we noted above there are advantages as well as limitations to the clustering configuration

  • You can only replicate portlet scoped attributes of a portlet. The main reason of this is to keep consistency with the session state. If accessing a portlet would trigger replication of application scoped attribute during the rendering of a page then another portlet on the same page could use this attribute for generating its markup. Then the state seen by this second portlet would not be the same according to the order in which the portlets of this page are rendered.
  • Mutable objects need an explicit call to setAttribute(String name, Object value) on the portlet session object in order to trigger replication by the container.

public void processAction(ActionRequest req, ActionResponse resp) throws PortletException, IOException
{
   ...
   if ("addItem".equals(action))
   {
      PortletSession session = req.getPortletSession();
      ShoppingCart cart = (PortletSession)session.getAttribute("cart");
      cart.addItem(item);

      // Perform an explicit set in order to signal to the container that the object state has changed
      session.setAttribute("cart", cart);
   }
   ...
}

Configures YourPortlet to be replicated in jboss-portlet.xml

Chapter 9. Web Services for Remote Portlets (WSRP)

Julien Viet

9.1. Introduction

The Web Services for Remote Portlets specification defines a web service interface for accessing and interacting with interactive presentation-oriented web services. It has been produced through the efforts of the Web Services for Remote Portlets (WSRP) OASIS Technical Committee. It is based on the requirements gathered and on the concrete proposals made to the committee.

Scenarios that motivate WSRP functionality include:

  • Content hosts, such as portal servers, providing Portlets as presentation-oriented web services that can be used by aggregation engines.
  • Aggregating frameworks, including portal servers, consuming presentation-oriented web services offered by content providers and integrating them into the framework.

More information on WSRP can be found on the official website for WSRP. We suggest reading the primer for a good, albeit technical, overview of WSRP.

9.2. Deploying JBoss Portal's WSRP services

JBoss Portal provides a base level support of the WSRP 1.0 standard and offers both consumer and producer services. WSRP support is provided by the portal-wsrp.sar service archive, included in the main jboss-portal.sar service archive.

If you've obtained the source distribution of JBoss Portal, you need to build and deploy the WSRP service separately. Please follow the instructions on how to install JBoss Portal from the sources. Once this is done, navigate to JBOSS_PORTAL_HOME_DIRECTORY/wsrp and type:

build deploy

At the end of the build process, portal-wsrp.sar is copied to JBOSS_HOME/server/default/deploy.

Note

WSRP is built upon the JBoss WS web service stack. There is a known issue with the version 1.0.0.GA of JBoss WS bundled with JBoss Application Server 4.0.4.GA, issue which prevents the complete deployment of JBoss Portal's WSRP service if the user is not online or behind a firewall/proxy. This has been addressed in version 1.0.2.GA of JBoss WS. Please follow the instructions on how to upgrade JBoss WS as found on JBoss Portal's wiki.

9.3. Making a portlet remotable

JBoss Portal does not, by default, expose local portlets for consumption by remote WSRP consumers. In order to make a portlet remotely available, a jboss-portlet.xml deployment descriptor for that portlet must be added to the WEB-INF folder of the web application containing the portlet and must be similar to the example below:

            
<?xml version="1.0" encoding="UTF-8"?>
<portlet>
   <portlet-name>BasicPortlet</portlet-name>
   <remotable>true</remotable>
</portlet>
         

Here, the portlet named "BasicPortlet" is specified as being remotable. The "remotable" element is optional.

It is also possible to specify that all the portlets declared within a given jboss-portlet.xml file have a specific "remotable" status by default. Usually, this feature will be used to remotely expose several portlets without having to specify the status for all the declared portlets. Let's look at an example:

            
<portlet-app>
   <remotable>true</remotable>
   <portlet>
      <portlet-name>RemotelyExposedPortlet</portlet-name>
      ...
   </portlet>
   <portlet>
      <portlet-name>NotRemotelyExposedPortlet</portlet-name>
      <remotable>false</remotable>
      ...
   </portlet>
</portlet-app>
         

In the example above, we defined two portlets with a default "remotable" status set to true. This means that all portlets defined in this descriptor are, by default, exposed remotely by JBoss Portal's WSRP producer. Note, however, that it is possible to override the default behavior by adding a remotable element to a portlet description. In that case, the "remotable" status defined by the portlet takes precedence over the default. In the example above, the RemotelyExposedPortlet inherits the "remotable" status defined by default since it does not specify a remotable element in its description. The NotRemotelyExposedPortlet, however, overrides the default behavior and is not remotely exposed. Note that in the absence of a top-level remotable element, portlets are NOT remotely exposed.

9.4. Accessing JBoss Portal's WSRP Producer from a remote Consumer

WSRP Consumers vary a lot as far as how they are configured. Most of them require that you either specify the URL for the Producer's WSDL definition or the URLs for the individual endpoints.

JBoss Portal's Producer is automatically set up when you deploy a portal instance. Assuming you're running a default configuration (i.e. you haven't changed the server's port number), you can access the WSDL file at http://localhost:8080/portal-wsrp/MarkupService?wsdl. You can acces the endpoint URLs are:

  • http://localhost:8080/portal-wsrp/ServiceDescriptionService
  • http://localhost:8080/portal-wsrp/MarkupService
  • http://localhost:8080/portal-wsrp/RegistrationService
  • http://localhost:8080/portal-wsrp/PortletManagementService

9.5. Consuming remote WSRP portlets in JBoss Portal

9.5.1. Overview

To be able to consume WSRP portlets from a remote producer, JBoss Portal's WSRP consumer needs to know how to access the remote producer. This is done via -wsrp.xml descriptors that provide JBoss Portal's consumer information about which remote producers to access and with which configuration. These files can be dropped in the deploy directory of the JBoss application server or nested in .sar files for examples. It is possible to configure access to several different producers within a single -wsrp.xml file or use one file per producer.

JBoss Portal's producer exposes its information to the Portal itself as a default consumer with the identifier self. That means that all the remotable portlets are also exposed as remote portlets in the portal. The portal-wsrp.sar file contains the file default-wsrp.xml that contains this default producer. This file can be edited or removed if needed.

Once a remote producer has been configured in a -wsrp.xml file, it becomes available in the list of portlet provider in the Management portlet on the Admin page of JBoss Portal. You can then examine the list of portlets that are exposed by this producer and configure the portlets just like you would for local portlets.

Note

As of 2.4, the optional Portlet Management interface of WSRP is NOT supported. It is therefore not possible to clone and configure portlets on the consumer side. This will be supported in 2.6.

Let's see how it works step by step. Let's create a public-bea-wsrp.xml file as follows:

               
<deployments>
   <deployment>
      <wsrp-producer>
         <producer-id>bea</producer-id>
         <expiration-cache>120</expiration-cache>
         <endpoint-wsdl-url>http://wsrp.bea.com:7001/producer/producer?WSDL</endpoint-wsdl-url>
         <registration-data>
            <consumer-name>JBoss Portal 2.4 Test</consumer-name>
            <property>
               <name>registration/consumerRole</name>
               <lang>en</lang>
               <value>public</value>
            </property>
         </registration-data>
      </wsrp-producer>
   </deployment>
</deployments>
            

This producer descriptor gives access to BEA's public WSRP producer. We will look at the details of the different elements later. Note for now the producer-id element with a "bea" value. Put this file in the deploy directory and start the server (with JBoss Portal and its WSRP service deployed).

Let's now look at the Admin page and the management portlet. Click on the "Portlets" link at the top to manage the portlets. Once this is done, look at the list of available portlet providers. If all went well, you should see something similar to this:

We have 3 available portlet providers: local, self and bea. The "local" portlet provider exposes all the portlets deployed in this particular instance of Portal. The "self" provider is the default WSRP consumer bundled with Portal that consumes the portlets exposed by the default WSRP producer. The "bea" provider corresponds to BEA's public producer we just configured. Select it and click on "Change portlet provider". You should now see something similar to:

From there on out, you should be able to configure the portlet just as any other, baring the restriction that the WSRP Portlet Management interface is not yet supported in 2.4. If everything went well, you created an instance of the portlet and assigned it to a window in a page. If you go to that page, you should see something similar to below for this portlet:

9.5.2. Required configuration information

Let's look at which information needs to be provided to configure access to a remote producer.

First, we need to provide an identifier for the producer we are configuring so that we can refer to it afterwards via the <producer-id> element.

JBoss Portal also needs to learn about the remote producer's endpoints to be able to connect to the web services and perform the WSRP invocations. Two options are currently provided to inform JBoss Portal of how to connect to the remote web service, both by providing the required information via children elements:

  • We can provide the URLs for each of the different WSRP interfaces offered by the remote producer via the <endpoint-config> element and its <service-description-url>, <markup-url>, <registration-url> and <portlet-management-url> children. These URLs are producer-specific so you will need to refer to your producer documentation or WSDL file to determine the appropriate values.
  • Alternatively, and this is the easiest way to configure your producer, we can provide a URL pointing to the WSDL description of the WSRP web services offered by the producer via <endpoint-wsdl-url>. JBoss Portal will then heuristically determine from the information contained in the WSDL file how to connect appropriately to the remote WSRP services.

    Note

    It is important to note that, when using this method, JBoss Portal will try to match a port name to an interface based solely on the provided name. There are no standard names for these ports so it is possible (though rare) that this matching process fails. In this case, you should look at the WSDL file and provide the endpoint URLs manually, as per the previous method.

Both <producer-id> and either <endpoint-config> or <endpoint-wsdl-url> are required elements for a functional remote producer configuration.

9.5.3. Optional configuration

It is also possible to provide addtional configuration, which, in some cases, might be important to establish a proper connection to the remote producer.

One such optional configuration is caching. To prevent useless roundtrips between the local consumer and the remote producer, it is possible to cache some of the information sent by the producer (such as the list of offered portlets). Such information is refreshed periodically. The rate at which the information is refreshed is defined by the <expiration-cache> element which specifies the refreshing period in seconds.

Additionally, some producers require consumers to register with them before authorizing them to access their offered portlets. JBoss Portal currently only supports a very basic subset of in-band registration and it is thus possible to provide required registration information in the producer configuration so that the Portal consumer can register with the remote producer when required.

Note

At this time, though, only simple String properties are supported and it is not possible to configure complex registration data.

Registration configuration is done via the <registration-datat> element. We need to provide a consumer name (via the <consumer-name> element) for our consumer and then provide a list of values for the registration properties required by the remote producer via <property> elements. See the example below for more details.

9.5.4. Examples

Here is an example of a WSRP descriptor with a 2 minutes caching time and manual definition of the endpoint URLs:

               
               <?xml version="1.0" encoding="UTF-8"?>
               <deployments>
                  <deployment>
                     <wsrp-producer>
                        <producer-id>MyProducer</producer-id>
                        <expiration-cache>120</expiration-cache>
                        <endpoint-config>
                           <service-description-url>http://www.someproducer.com/portal-wsrp/ServiceDescriptionService</service-description-url>
                           <markup-url>http://www.someproducer.com/portal-wsrp/MarkupService</markup-url>
                           <registration-url>http://www.someproducer.com/portal-wsrp/RegistrationService</registration-url>
                           <portlet-management-url>http://www.someproducer.com/portal-wsrp/PortletManagementService</portlet-management-url>
                        </endpoint-config>
                     </wsrp-producer>
                  <deployment>
               </deployments>
            

Here is an example of a WSRP descriptor with endpoint definition via remote WSDL file, registration data and cache expiring every minute:

               
                  <?xml version="1.0" encoding="UTF-8"?>
                  <deployments>
                     <deployment>
                        <wsrp-producer>
                           <producer-id>AnotherProducer</producer-id>
                           <expiration-cache>60</expiration-cache>
                           <endpoint-wsdl-url>http://example.com/producer/producer?WSDL</endpoint-wsdl-url>
                           <registration-data>
                              <consumer-name>JBoss Portal 2.4 Test</consumer-name>
                              <property>
                                 <name>property name</name>
                                 <lang>en</lang>
                                 <value>property value</value>
                              </property>
                           </registration-data>
                        </wsrp-producer>
                     <deployment>
                  </deployments>
               
            

Chapter 10. Security

Roy Russo

10.1. Securing Portal Objects

This section describes how to secure portal objects (portal instances, pages, and portlet instances), using the JBoss Portal *-object.xml descriptor OR portlet-instances.xml descriptor. View the User Guide for information on how to secure objects using the Management Portlet.

Securing portal objects declaratively, is done through the *-object.xml ( Section 6.1.1, “*-object.xml” ), for Portal Instances and Pages, or the portlet-instances.xml ( Section 6.1.2, “portlet-instances.xml” ) for Portlet Instances. The portion you will be adding to each object is denoted by the <security-constraint> tag:

<?xml version="1.0" encoding="UTF-8"?>
<deployments>
   <deployment>
      <if-exists>overwrite</if-exists>
      <parent-ref>default</parent-ref>
      <properties/>
      <page>
         <page-name>MyPage</page-name>
         <window>
            <window-name>HelloWorldPortletPageWindow</window-name>
            <instance-ref>HelloWorldPortletPageInstance</instance-ref>
            <region>center</region>
            <height>0</height>
         </window>
         <security-constraint>
            <policy-permission>
               <unchecked/>
               <action-name>viewrecursive</action-name>
            </policy-permission>
         </security-constraint>
      </page>
   </deployment>
</deployments>
         

A security constraint on an object (our example above, secures a specific portal page), is explained as:

<security-constraint>
   <policy-permission>
      <unchecked/>
      <action-name>viewrecursive</action-name>
   </policy-permission>
</security-constraint>

The security contraint portion is worth taking a look at, in an isolated fashion. It allows you to secure a specific window/page/portal-instance based on a user's role.

Role definition: You must define a role that this security constraint will apply to. Possible values are:

  • <unchecked/> Anyone can view this page.
  • <role-name>SOMEROLE</role-name> Access to this page is limited to the defined role.

Access Rights: You must define the access rights given to the role defined. Possible values are:

  • view Users can view the page.
  • viewrecursive Users can view the page and child pages.
  • personalize Users are able to view AND personalize the page.
  • personalizerecursive Users are able to view AND personalize the page AND its child pages.

We provide three live samples of this descriptor, here Section 6.1.2, “portlet-instances.xml” , Section 6.3.1, “Defining a new portal page” ,and Section 6.3.2, “Defining a new portal instance”

Chapter 11. CMS Portlet

Thomas Heute

JBoss Portal packages a Web Content Management System capable of serving and allowing administration of web content. This chapter describes the CMS Portlet which is responsible for serving resources requested, the following chapter describes the CMSAdmin Portlet and all administration functionality.

11.1. Introduction

The CMS Portlet displays content from the file store inside a portlet window, or, in the case of binary content, outside of the portlet window altogether.

11.2. Features

The CMSPortlet handles all requests for all content types.

The methodology of serving content within the CMSPortlet, allows for some beneficial features, like:

  1. Search-engine friendly URLs: http://domain/[portal]/content/company.html
  2. Serve binaries with simple urls independant of the portal: http://domain/content/products.pdf
  3. Deploy several instances of the CMSPortlet on any page and configure them to display different start pages.
  4. Localization support: CMSPortlet will display content based on the user request locale, or display content using the default locale setting.

11.3. CMS Configuration

11.3.1. Welcome page

The CMS portlet default page is defined as a preference and can be overriden like any other preference up to the user's preference level. The default CMS portlet displayed when you install JBoss Portal for the first time is describe in the following file: jboss-portal.sar/portal-core.war/WEB-INF/portlet.xml .

         <portlet-preferences>
            <preference>
               <name>indexpage</name>
               <value>/default/index.html</value>
            </preference>
         </portlet-preferences>
         

The preference key is "indexpage". To change the default page, just make sure to create an html document using the CMS Admin portlet then change the value of "indexpage" to the corresponding path.

11.3.2. Service Configuration

11.3.2.1. Tuning Jackrabbit

JBoss Portal uses Apache Jackrabbit as its Java Content Repository implementation. Configuration of the service descriptor, allows for changing many of the variables associated with the service.

Here is the default configuration for the CMS repository found under portal-cms.sar/META-INF-INF/jboss-service.xml

         ...
         <attribute name="DoChecking">true</attribute>
         <attribute name="DefaultContentLocation">portal/cms/conf/default-content/default/</attribute>
         <attribute name="DefaultLocale">en</attribute>
         <attribute name="RepositoryName">PortalRepository</attribute>
         <attribute name="HomeDir">${jboss.server.data.dir}${/}portal${/}cms${/}conf</attribute>
            

Below is a list of items found in the service descriptor and their definitions. Only items commonly changed are covered here and it is recommended you do not change any others unless you are very brave.

  • DoChecking: Should the portal attempt to check for the existence of the repository configuration files and default content on startup?
  • DefaultContentLocation: Location of the default content used to pre-populate the repository.
  • DefaultLocale: Two-letter abbreviation of the default locale the portal should use when fetching content for users. A complete ISO-639 list can be found here .
  • HomeDir: Location of configuration information for the repository when in 100% FileSystem store mode. Otherwise, its in the database.

11.3.2.2. Changing the url under which the content should be accessible

By default, the content will be accessible to a url like this: http://www.example.com/content/[...], if you need or prefer to change "content" to something else you will need to edit the following file: portal-cms.sar/META-INF-INF/jboss-service.xml and change the value of Prefix to something else. Please note that you cannot change it to "nothing", you need to provide a value.

               
         ...
   <mbean
      code="org.jboss.portal.core.cms.CMSObjectCommandFactory"
      name="portal:commandFactory=CMSObject"
      xmbean-dd=""
      xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
      <xmbean/>
      <attribute name="Prefix">content</attribute>
      <attribute name="TargetWindowRef">default.default.CMSPortletWindow</attribute>
      <depends optional-attribute-name="Factory" proxy-type="attribute">portal:commandFactory=Delegating</depends>
      <depends optional-attribute-name="CMSService" proxy-type="attribute">portal:service=CMS</depends>
   </mbean>
         ...
           
            
  • Prefix: This is the context path prefix that will trigger the portal to render content. By default, navigating to a URL such as http://localhost:8080/[portal_context]/content/Test.PDF will trigger the portal to display the PDF isolated from the portal pages. The path following the Prefix has to be absolute when fetching content.

11.3.3. Configuring the Content Store Location

By default, the JBoss Portal CMS stores all node properties, references, and binary content in the database, using the portal datasource. The location of some of these items is configurable, and there are 3 options:

11.3.3.1. 100% Filesystem Storage

To enable 100% Filesystem storage, you must edit the file: jboss-portal.sar/portal-cms.sar/META-INF/jboss-service.xml . You will note that the file is set to use the HibernateStore and HibernatePersistenceManager classes, by default. To have the CMS use 100% file system storage, simply comment these blocks. Then, you should uncomment to use the LocalFileSystem and XMLPersistenceManager classes. Follow these steps to activate 100% FS storage:

  1. Comment out the following blocks (there are 3 in total):

    <!-- HibernateStore: uses RDBMS + Hibernate for storage -->
    <FileSystem class="org.jboss.portal.cms.hibernate.HibernateStore">
    ...
    </FileSystem>
    

    And uncomment the blocks under them (there are 3 in total):

    <!-- LocalFileSystem: uses FileSystem for storage. -->
    <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
    ...
    </FileSystem>

  2. Now comment out the following blocks (there are 2 in total):

    <!-- HibernatePersistentManager: uses RDBMS + Hibernate for storage -->
    <PersistenceManager class="org.jboss.portal.cms.hibernate.state.HibernatePersistenceManager">
    ...
    </PersistenceManager>

    And uncomment the blocks under them (there are 2 in total):

    <!-- XMLPersistenceManager: uses FileSystem for storage -->
    <PersistenceManager class="org.apache.jackrabbit.core.state.xml.XMLPersistenceManager"/>
    

Warning

If you do any change at the workspaces configuration you will need to delete the file $JBOSS_HOME/server/xxx/data/portal/cms/conf/workspaces/default/workspace.xml before restarting JBoss or redeploying JBoss Portal. If you forget to do that, the changes won't affect the CMS. For the same reason, you also need to delete that file if you recompile JBoss Portal after changing the name of the datasource. Note that on a cluster environment, you need to remove that file (if it exists) on all the nodes.

11.3.3.2. 100% Database Storage

This is the default configuration for the CMS store. Please view the original jboss-portal.sar/portal-cms.sar/META-INF/jboss-service.xml , for guidance on how to reset it.

11.3.3.3. Mixed Storage

Mixed storage consists of meta-data being stored in the DB and blobs being stored on the Filesystem. This is the recommended setting for those of you that serve large files or stream media content.

Setting the repository this way is simple. Change every instance in the file jboss-portal.sar/portal-cms.sar/META-INF/jboss-service.xml , from:

<param name="externalBLOBs" value="false"/>

to:

<param name="externalBLOBs" value="true"/>

Warning

If you do any change at the workspaces configuration you will need to delete the file $JBOSS_HOME/server/xxx/data/portal/cms/conf/workspaces/default/workspace.xml before restarting JBoss or redeploying JBoss Portal. If you forget to do that, the changes won't affect the CMS. For the same reason, you also need to delete that file if you recompile JBoss Portal after changing the name of the datasource. Note that on a cluster environment, you need to remove that file (if it exists) on all the nodes.

11.4. Localization Support

The CMS Portlet now serves content based on the user's locale setting. For example: if a user's locale is set to Spanish in his browser, and he requests URL: default/index.html , the CMSPortlet will first try and retrieve the Spanish version of that file. If a Spanish version is not found, it will then try and retrieve the default language version set for the CMSPortlet.

11.5. CMS Service

The CMS portlet calls a CMS service that can be reused in your own portlets.

11.5.1. CMS Interceptors

Since JBoss Portal 2.4 you can add your own interceptor stack to the CMS service. The interceptors are called around each command (Get a file, write a file, create a folder...), this is a very easy way to customize some actions based on your needs.

To create your own interceptor you just need to extend the org.jboss.portal.cms.CMSInterceptor class and provide the content of the invoke(JCRCommand) method. Do not forget to make a call to JCRCommand.invokeNext() or the command will never be executed.

JBoss Portal provides two CMS interceptors out of the box, a very basic Log interceptor ( org.jboss.portal.cms.impl.interceptors.LogInterceptor ) that prints all the commands called. And a cache interceptor to enable distributed caching or content ( org.jboss.portal.cms.impl.interceptors.CacheInterceptor ). For more information about the cache interceptor, see below.

To add or remove an interceptor, you just need to edit the following file: portal-cms-sar/META-INF/jboss-service.xml. It works the same way as the server interceptor, for each interceptor you need to define an mbean then add it to the cms interceptor stack. For example, if you have the 2 default interceptors, you should have the following lines in the jboss-service.xml file:

               
   <mbean
      code="org.jboss.portal.cms.impl.interceptors.LogInterceptor"
      name="portal:service=Interceptor,type=Cms,name=Log"
      xmbean-dd=""
      xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
      <xmbean/>
   </mbean>
   <mbean
      code="org.jboss.portal.cms.impl.interceptors.CacheInterceptor"
      name="portal:service=Interceptor,type=Cms,name=Cache"
      xmbean-dd=""
      xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
      <xmbean/>
      <depends>portal:service=CMSTreeCache</depends>
   </mbean>
   <mbean
      code="org.jboss.portal.server.impl.invocation.JBossInterceptorStack"
      name="portal:service=InterceptorStack,type=Cms"
      xmbean-dd=""
      xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
      <xmbean/>
      <depends-list optional-attribute-name="InterceptorNames">
         <depends-list-element>portal:service=Interceptor,type=Cms,name=Log</depends-list-element>
         <depends-list-element>portal:service=Interceptor,type=Cms,name=Cache</depends-list-element>
      </depends-list>
   </mbean>
               
            

The first two mbeans define the interceptors and the third mbean, define which interceptors to add to the CMS service.

If you create your own interceptor org.example.myCMSInterceptor, the service descriptor file will look like:

            
   <mbean
      code="org.example.myCMSInterceptor"
      name="portal:service=Interceptor,type=Cms,name=MyName"
      xmbean-dd=""
      xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
      <xmbean/>
   </mbean>
   <mbean
      code="org.jboss.portal.cms.impl.interceptors.LogInterceptor"
      name="portal:service=Interceptor,type=Cms,name=Log"
      xmbean-dd=""
      xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
      <xmbean/>
   </mbean>
   <mbean
      code="org.jboss.portal.cms.impl.interceptors.CacheInterceptor"
      name="portal:service=Interceptor,type=Cms,name=Cache"
      xmbean-dd=""
      xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
      <xmbean/>
      <depends>portal:service=CMSTreeCache</depends>
   </mbean>
   <mbean
      code="org.jboss.portal.server.impl.invocation.JBossInterceptorStack"
      name="portal:service=InterceptorStack,type=Cms"
      xmbean-dd=""
      xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
      <xmbean/>
      <depends-list optional-attribute-name="InterceptorNames">
         <depends-list-element>portal:service=Interceptor,type=Cms,name=Log</depends-list-element>
         <depends-list-element>portal:service=Interceptor,type=Cms,name=Cache</depends-list-element>
         <depends-list-element>portal:service=Interceptor,type=Cms,name=MyName</depends-list-element>
      </depends-list>
   </mbean>
               
            

Note

The interceptor order is important ! For example the cache interceptor may stop the call, so if you place the log interceptor after the call you wouldn't see all the commands that have been executed by the portlets.

To check that the interceptors have been correctly added, you can check the JMX console, by going to: http://localhost.localdomain:8080/jmx-console/HtmlAdaptor?action=inspectMBean&name=portal%3Aservice%3DInterceptorStack%2Ctype%3DCms You should notice all the interceptors in the attribute "interceptors".

11.5.2. CMS Cache

The CMS cache is implemented as an interceptor, it makes it easy to be added or removed as you saw above. The CMS cache is available by default only if you precised portal.clustered = true in local.properties then cleaned, built and deployed the corresponding portal.

Chapter 12. Layouts and Themes

Martin Holzner

Mark Fernandes

12.1. Overview

Portals usually render the markup fragments of several portlets, and aggregate these fragments into one page that ultimately gets sent back as response. Each portlet on that page will be decorated by the portal to limit the real estate the portlet has on the page, but also to allow the portal to inject extra functionality on a per portlet basis. Classic examples of this injection are the maximize, minimize and mode change links that will appear in the portlet window , together with the title.

Layouts and themes allow to manipulate the look and feel of the portal. Layouts are responsible to render markup that will wrap the markup fragments produced by the individual portlets. Themes, on the other hand, are responsible to style and enhance this markup.

In JBoss Portal, layouts are implemented as a JSP or a Servlet. Themes are implemeted using CSS Style sheets, java script and images. The binding elemement between layouts and themes are the class and id attributes of the rendered markup.

JBoss Portal has the concept of regions on a page. When a page is defined, and portlet windows are assigned to the page, the region, and order inside the region, has to be specified as well. For portal layouts this has significant meaning. It defines the top most markup container that can wrap portlet content (other then the static markup in the JSP itself). In other words: from a layout perspective all portlets of a page are assigned to one or more regions. Each region can contain one or more portlets. To render the page content to return from a portal request, the portal has to render the layout JSP, and for each region, all the portlets in the region.

Since the markup around each region, and around each portlet inside that region, is effectively the same for all the pages of a portal, it makes sense to encapsulate it in its own entity.

To implement this encapsulation there are several ways:

  • JSPs that get included from the layout JSP for each region/portlet
  • a taglib that allows to place region, window, and decoration tags into the layout JSP
  • a taglib that uses a pluggable API to delegate the markup generation to a set of classes

In JBoss Portal you can currently see two out of these approaches, namley the first and the last. Examples for the first can be found in the portal-core.war, implemented by the nodesk and phalanx layouts. Examples for the third approach can be found in the same war, implemented by the industrial and Nphalanx layout. What encapsulates the markup generation for each region, window, and portlet decoration in this last approach is what's called the RenderSet.

The RenderSet consist of four interfaces that correspond with the four markup containers that wrap the markup fragments of one of more portlets:

  • Region
  • Window
  • Decoration
  • Portlet Content

While we want to leave it open to you to decide which way to implement your layouts and themes, we strongly believe that the last approach is superior, and allows for far more flexibility, and clearer separation of duties between portal developers and web designers.

Portal layouts also have the concept of a layout strategy. The layout strategy is a pluggable API, and lets the layout developer have a last say about the content to be rendered. The strategy is called right after the portal has determined what needs to be rendered as part of the current request. So the strategy is invoked right between the point where the portal knows what needs to be done, and before the actual work is initiated. The strategy gets all the details about what is going to happen, and it can take measures to influence those details.

Some simple examples of those measures are:

  • ommit one of the portlets from being rendered
  • change the portlet mode or window state of a portlet before it gets rendered
  • change the layout to be used for this request
  • ...and many more

The last topic to introduce in this overview is the one of portal themes. A theme is a collection of web design artifacts. It defines a set of css, java script and image files that together decide about the look and feel of the portal page. The theme can take a wide spectrum of control over the look and feel. It can limit itself to decide fonts and colors, or it can take over a lot more and decide the placement (location) of portlets and much more.

12.2. Layouts

12.2.1. How to define a Layout

Layouts are used by the portal to produce the actual markup of a portal response. After all the portlets on a page have been rendered and have produced their markup fragments, the layout is responsible for aggregating all these pieces, mix them with some ingredients from the portal itself, and at the end write the response back to the requesting client.

Layouts can be either a JSP or a Servlet. The portal determines the layout to use via the configured properties of the portal, or the requested page. Both, portal and pages, can define the layout to use in order to render their content. In case both define a layout, the layout defined for the page will overwrite the one defined for the portal.

A Layout is defined in the layout descriptor named portal-layouts.xml. This descriptor must be part of the portal application, and is picked up by the layout deployer. If the layout deployer detects such a descriptor in a web application, it will parse the content and register the layouts with the layout service of the portal. Here is an example of such a descriptor file:

            <layouts>
               <layout>
                  <name>phalanx</name>
                  <uri>/phalanx/index.jsp</uri>
               </layout>
               <layout>
                  <name>industrial</name>
                  <uri>/industrial/index.jsp</uri>
                  <uri state="maximized">/industrial/maximized.jsp</uri>
               </layout>
            </layouts>

12.2.2. How to use a Layout

12.2.2.1. Declarative use

Portals and pages can be configured to use a particular layout. The connection to the desired layout is made in the portal descriptor (YourNameHere-object.xml). Here is an example of such a portal descriptor:

                <portal>
                    <portal-name>default</portal-name>
                    <properties>
                       <!-- Set the layout for the default portal -->
                       <!-- see also portal-layouts.xml -->
                       <property>
                          <name>layout.id</name>
                          <value>phalanx</value>
                       </property>
                    </properties>
                    <pages>
                       <page>
                        <page-name>theme test</page-name>
                        <properties>
                           <!-- set a difference layout for this page -->
                           <property>
                              <name>layout.id</name>
                              <value>industrial</value>
                           </property>
                        </properties>
                       </page>
                    </pages>
                  </portal>

The name specified for the layout to use has to match one of the names defined in the portal-layouts.xml descriptor of one of the deployed applications.

As you can see, the portal or page property points to the layout to use via the name of the layout. The name has been given to the layout in the layout descriptor. It is in that layout descriptor where the name gets linked to the physical resource (the JSP or Servlet) that will actually render the layout.

12.2.2.2. Programatic use

To access a layout from code, you need to get a reference to the LayoutService interface. The layout service is an mbean that allows access to the PortalLayout interface for each layout that was defined in a portal layout descriptor. As a layout developer you should never have to deal with the layout service directly. Your layout hooks are the portal and page properties to configure the layout, and the layout strategy, where you can change the layout to use for the current request, before the actual render process begins.

12.2.3. Where to place the Descriptor files

Both descriptors, the portal and the theme descriptor, are located in the WEB-INF/ folder of the deployed portal application. Note that this is not limited to the portal-core.war, but can be added to any WAR that you deploy to the same server. The Portal runtime will detect the deployed application and introspect the WEB-INF folder for known descriptors like the two metioned here. If present, the appropriate meta data is formed and added to the portal runtime. From that time on the resources in that application are available to be used by the portal. This is an elegant way to dynamically add new layouts or themes to the portal without having to bring down , or even rebuild the core portal itself.

12.2.4. How to connect a Layout to a Layout Strategy

As you might have noticed already, a layout definition consists of a name and one or more uri elements. We have already seen the function of the name element. Now let's take a closer look at the uri element. In the example above, the phalanx layout defined one uri element only, the industrial layout defines two. What you can see in the industrial layout is the option of defining different uri's for different states. In this example , we configured the layout to use a different JSP if the layout state is maximized. If no such separation is made in the layout descriptor, then the portal will always use the same JSP for this layout. Note that the 'state' attribute value works together with the state that was set by the layout strategy. Please refere to the section about the layout strategy for more details.

12.2.5. Layout JSP-tags

The portal comes with a set of JSP tags that allow the layout developer faster development.

There are currently two taglibs, containing tags for different approaches to layouts:

  • portal-layout.tld
  • theme-basic-lib.tld

The theme-basic-lib.tld contains a list of tags that allow a JSP writer to access the state of the rendered page content. It is built on the assumption that regions, portlet windows and portlet decoration is managed inside the JSP.

The portal-layout.tld contains tags that work under the assumption that the RenderSet will take care of how regions, portlet windows and the portlet decoration will be rendered. The advantage of this approach is that the resulting JSP is much simpler and easier to read and maintain.

Here is an example layout JSP that uses tags from the latter:

             
             <%@ taglib uri="/WEB-INF/theme/portal-layout.tld" prefix="p" %>
             <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
             <html xmlns="http://www.w3.org/1999/xhtml">
             <head>
             <title>JBoss Portal: 2.2 early (Industrial)</title>
             <meta http-equiv="Content-Type" content="text/html;" />
             <p:theme themeName='phalanx' />
             <p:headerContent />
             </head>
             <body id="body">
             <div id="portal-container">
             <div id="sizer">
             <div id="expander">
             <div id="logoName"></div>
             <table border="0" cellpadding="0" cellspacing="0" id="header-container">
             <tr>
             <td align="center" valign="top" id="header"><div id="spacer"></div></td>
             </tr>
             </table>
             <div id="content-container">
             <p:region regionName='This-Is-The-Page-Region-To-Query-The-Page'
             regionID='This-Is-The-Tag-ID-Attribute-To-Match-The-CSS-Selector'/>
             <p:region regionName='left' regionID='regionA'/>
             <p:region regionName='center' regionID='regionB'/>
             <hr class="cleaner" />
             <div id="footer-container" class="portal-copyright">Powered by
             <a class="portal-copyright" href="http://www.jboss.com/products/jbossportal">JBoss Portal</a><br/>
             Theme by <a class="portal-copyright" href="http://www.novell.com">Novell</a>
             </div>
             </div>
             </div>
             </div>
             </div>
             </body>
             </html>
             

1. The theme tag

The theme tag looks for the determined theme of the current request (see Portal Themes for more details). If no theme was determined, this tag allows an optional attribute 'themeName' that can be used to specifiy a default theme to use as a last resort. Based on the determined theme name, the ThemeService is called to lookup the theme with this name and to get the resources associated with this theme. The resulting style and link elements are injected, making sure that war context URLS are resolved appropriately.

2. The headerContent tag

This tags allows portlets to inject content into the header. More details about this function are mentioned in the 'other Theme Functions' section of this document.

3. The region tag

The region tag renders all the portlets in the specified region of the current page, using the determined RenderSet to produce the markup that surrounds the individual portlet markup fragments. The regionName attribute functions as a query param into the current page. It determines from what page region the portlets will be rendered in this tag. The regionID attribute is what the RenderSet can use to generate a css selector for this particular region. In case of the divRenderer, a DIV tag with an id attribute corresponding to the provided value will be rendered for this region. This id in turn can be picked up by the CSS to style the region.

12.3. Layout Strategy

12.3.1. What is a Layout Strategy

The layout strategy is a pluggable API that allows the layout developer to influence the content of the page that is about to be rendered. Based on the current request URL, the portal determined the portal and page that needs to be rendered. The page contains a list of portlets, and those portlets are in a particular navigational state. The navigational state consists of the portlet mode and the window state of the portlet. This information, togeher with the determined layout, the region and order assignments of each portlet, the allowed window states and portlet modes for both, the portal and the individual portlets, is passed to the layout strategy before the actual rendering is invoked. The layout strategy can check what is about to be rendered, and take action in a limited way to influence the content that is about to be rendered.

12.3.2. How can I use a Layout Strategy

12.3.2.1. Define a Strategy

A layout strategy is defined in the strategy descriptor. The descriptor is named portal-strategies.xml, and is located in the WEB-INF/layout folder of any web application deployed to the server. Here is an example of such a descriptor:

               <portal-strategies>
               <set name="default">
               <strategy content-type="text/html">
               <implementation>org.jboss.portal.theme.impl.strategy.DefaultStrategyImpl</implementation>
               </strategy>
               </set>
               <set name="maximizedRegion">
               <strategy content-type="text/html">
               <implementation>org.jboss.portal.theme.impl.strategy.MaximizingStrategyImpl</implementation>
               </strategy>
               </set>
               </portal-strategies>
               

Layout strategies are defined as sets. A set consists of one or more strategy definitions, separated by content type they are assigned for. The idea behind this is to allow the layout developer to apply different strategies based on requested content type. Each set has a name that is unique in the application context it is deployed in. The strategy can be refered to by this name. As a result of that it is considered a named layout strategy in contrast to an anonymous strategy as described below.

12.3.2.2. Specify the Strategy to use

The strategy that will be used for a portal request is defined as a property of the current layout, the requested portal, or the requested page. If the layout defines a strategy to use it will overwrite all other assignments. If there is no particular strategy defined for the layout, then the page property will overwrite the portal property. If no strategy can be determined, then a last attempt will be made to use the strategy with the name 'default'. If no strategy can be determined at all, the request will proceed normally without invoking any strategy. Here is an example layout descriptor that defines a strategy for the layouts defined:

               
               <layouts>
               <strategy content-type="text/html">
               <implementation>com.novell.portal.strategy.MaximizingStrategy</implementation>
               </strategy>
               
               <layout>
               <name>generic</name>
               <uri>/generic/index.jsp</uri>
               <uri state="maximized">/generic/maximized.jsp</uri>
               </layout>
               </layouts>
               

In this case the strategy is anonymous and directly assigned to the generic layout. The strategy cannot be discovered independently from the generic layout. Here is an example portal descriptor that points to a strategy for the portal, and for a particular page:

               
               <portal>
               <portal-name>default</portal-name>
               <properties>
               <property>
               <name>layout.strategyId</name>
               <value>default</value>
               </property>
               </properties>
               <pages>
               <default-page>theme test</default-page>
               <page>
               <page-name>theme test</page-name>
               <properties>
               <!-- set a difference layout strategy for this page -->
               <property>
               <name>layout.strategyId</name>
               <value>maximizedRegion</value>
               </property>
               </properties>
               <window>
               <window-name>CatalogPortletWindow</window-name>
               <instance-ref>CatalogPortletInstance</instance-ref>
               <region>left</region>
               <height>0</height>
               </window>
               </page>
               </pages>
               </portal>
               

As you can see, analogous to how layouts are refered to, the strategy name is the linking element between the portal descriptor and the layout strategy descriptor. The content type is determined at runtime, and serves as a secondary query parameter to get the correct strategy for this content type out of the set that matches the name provided in the portal descriptor.

12.3.3. Linking the Strategy and the Layout

As mentioned above, the layout descriptor can link a strategy directly to the layout. This will overwrite all other defined strategies for the portal or the page, for any page that uses this layout.

The layout strategy can set a state to return to the portal as a result of the strategy evaluation. This state will be matched with the state attribute of the uri element of the layout. If there is a match, then the uri that matches this state will be used as the layout for the current request. So, if the strategy sets a state of 'maximized' , the portal will try to use the layout resource that is pointed to for that particular state in the currently selected layout. As you might remember from the previous layout section, a layout can point to another JSP or Servlet based on the state attribute of the uri element, like so:

            <layouts>
            <layout>
            <name>industrial</name>
            <uri>/industrial/index.jsp</uri>
            <uri state="maximized">/industrial/maximized.jsp</uri>
            </layout>
            </layouts>

In this case all reuquests that don't return a state 'maximized' from the evaluation of the strategy will use the /industrial/index.jsp as the layout. However, if the evaluation of the strategy returns a state of 'maximized' then the request will use /industrial/maximized.jsp as the layout.

12.4. RenderSets

12.4.1. What is a RenderSet

A RenderSet can be used to produce the markup containers around portlets and portlet regions. The markup for each region, and each portlet window in a region is identical. Further more, it is most likely identical across several layouts. The way portlets are arranged and decorated will most likely not change across layouts. What will change is the look and feel of the decoration, the images, fonts, and colors used to render each portlet window on the page. This is clearly a task for the web designer, and hence should be realized via the portal theme. The layout only needs to provide enough information to the theme so that it can do its job. The RenderSet is exactly that link between the layout and the theme that takes the information available in the portal and renders markup containing the current state of the page and each portlet on it. It makes sure that the markup around each region and portlet contains the selectors that the theme css needs to style the page content appropriately.

A RenderSet consists of the implementations of four interfaces. Each of those interfaces corresponds to a markup container on the page.

Here are the four markup containers and their interface representation:

  • Region - RegionRenderer
  • Window - WindowRenderer
  • Decoration - DecorationRenderer
  • Portlet Content - PortletRenderer

All the renderer interfaces are specified in the org.jboss.portal.theme.render package.

The four markup containers are hierarchical. The region contains one or more windows. A window contains the portlet decoration and the portlet content.

The region is responsible for arranging the positioning and order of each portlet window. Should they be arranged in a row or a column? If there are more then one portlet window in a region, in what order should they appear?

The window is responsible for placing the window decoration, including the portlet title, over the portlet content, or under, or next to it.

The decoration is responsible for inserting the correct markup with the links to the portlet modes and window states currently available for each portlet.

The portlet content is responsible for inserting the actually rendered markup fragment that was produced by the portlet itself.

12.4.2. How is a RenderSet defined

Similar to layouts, render sets must be defined in a RenderSet descriptor. The RenderSet descriptor is located in the WEB-INF/layout folder of a web application, and is named portal-renderSet.xml. Here is an example descriptor:

            
            <?xml version="1.0" encoding="UTF-8"?>
            <portal-renderSet>
            <renderSet name="divRenderer">
            <set content-type="text/html">
            <region-renderer>org.jboss.portal.theme.impl.render.DivRegionRenderer</region-renderer>
            <window-renderer>org.jboss.portal.theme.impl.render.DivWindowRenderer</window-renderer>
            <portlet-renderer>org.jboss.portal.theme.impl.render.DivPortletRenderer</portlet-renderer>
            <decoration-renderer>org.jboss.portal.theme.impl.render.DivDecorationRenderer</decoration-renderer>
            </set>
            </renderSet>
            <renderSet name="emptyRenderer">
            <set content-type="text/html">
            <region-renderer>org.jboss.portal.theme.impl.render.EmptyRegionRenderer</region-renderer>
            <window-renderer>org.jboss.portal.theme.impl.render.EmptyWindowRenderer</window-renderer>
            <portlet-renderer>org.jboss.portal.theme.impl.render.EmptyPortletRenderer</portlet-renderer>
            <decoration-renderer>org.jboss.portal.theme.impl.render.EmptyDecorationRenderer</decoration-renderer>
            </set>
            </renderSet>
            </portal-renderSet>
            

12.4.3. How to specify what RenderSet to use

Analogous to how a strategy is specified, the RenderSet can be specified as a portal or page property, or a particular layout can specify an anonymous RenderSet to use. Here is an example of a portal descriptor:

            
            <?xml version="1.0" encoding="UTF-8"?>
            <portal>
            <portal-name>default</portal-name>
            <properties>
            <!-- use the divRenderer for this portal -->
            <property>
            <name>theme.renderSetId</name>
            <value>divRenderer</value>
            </property>
            </properties>
            <pages>
            <default-page>default</default-page>
            <page>
            <page-name>default</page-name>
            <properties>
            <!-- overwrite the portal's renderset for this page -->
            <property>
            <name>theme.renderSetId</name>
            <value>emptyRenderer</value>
            </property>
            </properties>
            <window>
            <window-name>TestPortletWindow</window-name>
            <instance-ref>TestPortletInstance</instance-ref>
            <region>center</region>
            <height>0</height>
            </window>
            </page>
            </pages>
            </portal>
            

Here is an example of a layout descriptor with an anonymous RenderSet:

            
            <?xml version="1.0" encoding="UTF-8"?>
            <layouts>
            <renderSet>
            <set content-type="text/html">
            <region-renderer>org.foo.theme.render.MyRegionRenderer</region-renderer>
            <window-renderer>org.foo.theme.render.MyWindowRenderer</window-renderer>
            <portlet-renderer>org.foo.theme.render.MyPortletRenderer</portlet-renderer>
            <decoration-renderer>org.foo.theme.render.MyDecorationRenderer</decoration-renderer>
            </set>
            </renderSet>
            <layout>
            <name>generic</name>
            <uri>/generic/index.jsp</uri>
            <uri state="maximized">/generic/maximized.jsp</uri>
            </layout>
            </layouts>
            

Again, anologous to layout strategies, the anonymous RenderSet overwrites the one specified for the page, and that overwrites the one specified for the portal. In other words: all pages that use the layout that defines an anonymous RenderSet will use that RenderSet, and ignore what is defined as RenderSet for the portal or the page.

In addition to specifying the renderSet for a portal or a page, each individual portlet window can define what renderSet to use for the one of the three aspects of a window, the window renderer, the decoration renderer, and the portlet renderer. This feature allow you to use the the window renderer implementation from one renderSet, and the decoration renderer from another. Here is an example for a window that uses the implementations of the emptyRenderer renderSet for all three aspects:

            
            <window>
               <window-name>NavigationPortletWindow</window-name>
               <instance-ref>NavigationPortletInstance</instance-ref>
               <region>navigation</region>
               <height>0</height>
               <!-- overwrite portal and page properties set for the renderSet for this window -->
               <properties>
                  <!-- use the window renderer from the emptyRenderer renderSet -->
                  <property>
                     <name>theme.windowRendererId</name>
                     <value>emptyRenderer</value>
                  </property>
                  <!-- use the decoration renderer from the emptyRenderer renderSet -->
                  <property>
                     <name>theme.decorationRendererId</name>
                     <value>emptyRenderer</value>
                  </property>
                  <!-- use the portlet renderer from the emptyRenderer renderSet -->
                  <property>
                     <name>theme.portletRendererId</name>
                     <value>emptyRenderer</value>
                  </property>
               </properties>
            </window>

12.5. Themes

12.5.1. What is a Theme

A portal theme is a collection of CSS styles, JavaScript files, and images, that all work together to style and enhance the rendered markup of the portal page. The theme works together with the layout and the RenderSet in procuding the content and final look and feel of the portal response. Through clean separation of markup and styles a much more flexible and powerfull approach to theming portals is possible. While this approach is not enforced, it is strongly encouraged. If you follow the definitions of the ThemeStyleGuide (see later), it is not necessary to change the layout or the strategy, or the RenderSet to achieve very different look and feels for the portal. All you need to change is the theme. Since the theme has no binary dependencies, it is very simple to swapt it, or change individual items of it. No compile or redeploy is necessary. Themes can be added or removed while the portal is active. Themes can be deployed in separate web applications furthering even more the flexibility of this approach. Web developers don't have to work with JSPs. They can stay in their favorite design tool and simple work against the exploded war content that is deployed into the portal. The results can be validated life in the portal.

12.5.2. How to define a Theme

Themes can be added as part of any web application that is deployed to the portal server. All what is needed is a theme descriptor file that is part of the deployed archive. This descriptor indicates to the portal what themes and theme resources are becoming available to the portal. The theme deployer scans the descriptor and adds the theme(s) to the ThemeService, which in turn makes the themes available for consumption by the portal. Here is an example of a theme descriptor:

               
               <themes>
               <theme>
               <name>nodesk</name>
               <link href="/nodesk/css/portal_style.css" rel="stylesheet" type="text/css" />
               <link rel="shortcut icon" href="/images/favicon.ico" />
               </theme>
               <theme>
               <name>phalanx</name>
               <link href="/phalanx/css/portal_style.css" rel="stylesheet" type="text/css" />
               <link rel="shortcut icon" href="/images/favicon.ico" />
               </theme>
               
               <theme>
               <name>industrial-CSSSelect</name>
               <link rel="stylesheet" id="main_css" href="/industrial/portal_style.css" type="text/css" />
               <link rel="shortcut icon" href="/industrial/images/favicon.ico" />
               
               <script language="JavaScript" type="text/javascript">
               // MAF - script to switch current tab and css in layout...
               function switchCss(currentTab,colNum) {
               var obj = currentTab;
               var objParent = obj.parentNode;
               
               if (document.getElementById("current") != null) {
               var o = document.getElementById("current");
               o.setAttribute("id","");
               o.className = 'hoverOff';
               objParent.setAttribute("id","current");
               }
               
               var css = document.getElementById("main_css");
               source = css.href;
               if (colNum == "3Col") {
               if (source.indexOf("portal_style.css" != -1)) {
               source = source.replace("portal_style.css","portal_style_3Col.css");
               }
               if (source.indexOf("portal_style_1Col.css" != -1)) {
               source = source.replace("portal_style_1Col.css","portal_style_3Col.css");
               }
               }
               if (colNum == "2Col") {
               if (source.indexOf("portal_style_3Col.css" != -1)) {
               source = source.replace("portal_style_3Col.css","portal_style.css");
               }
               if (source.indexOf("portal_style_1Col.css" != -1)) {
               source = source.replace("portal_style_1Col.css","portal_style.css");
               }
               }
               if (colNum == "1Col") {
               if (source.indexOf("portal_style_3Col.css" != -1)) {
               source = source.replace("portal_style_3Col.css","portal_style_1Col.css");
               }
               if (source.indexOf("portal_style.css" != -1)) {
               source = source.replace("portal_style.css","portal_style_1Col.css");
               }
               }
               
               css.href = source;
               }
               </script>
               </theme>
               </themes>
               

Themes are defined in the portal-themes.xml theme descriptor, which is localted in the WEB-INF/ folder of the web application.

12.5.3. How to use a Theme

Again, analogous to the way it is done for layouts, themes are specified in the portal descriptor as a portal or page property. The page property overwrites the portal property. In addition to these two options, themes can also be specified as part of the theme JSP tag , that is placed on the layout JSP. Here is an example portal descriptor that specifies the phalanx theme as the theme for the entire portal, and the industrial theme for the theme test page:

               
               <portal>
               <portal-name>default</portal-name>
               <properties>
               <!-- Set the theme for the default portal -->
               <property>
               <name>layout.id</name>
               <value>phalanx</value>
               </property>
               </properties>
               <pages>
               <page>
               <page-name>theme test</page-name>
               <properties>
               <!-- set a difference layout for this page -->
               <property>
               <name>layout.id</name>
               <value>industrial</value>
               </property>
               </properties>
               <window>
               <window-name>CatalogPortletWindow</window-name>
               <instance-ref>CatalogPortletInstance</instance-ref>
               <region>left</region>
               <height>0</height>
               </window>
               </page>
               </pages>
               </portal>
               

And here is an example of a layout JSP that defines a default theme to use if no other theme was defined for the portal or page:

               
               <%@ taglib uri="/WEB-INF/theme/portal-layout.tld" prefix="p" %>
               <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
               <html xmlns="http://www.w3.org/1999/xhtml">
               <head>
               <title><%= "JBoss Portal :: 2.2 early (Industrial)" %></title>
               <meta http-equiv="Content-Type" content="text/html;" />
               <p:theme themeName='industrial' />
               <p:headerContent />
               </head>
               <body id="body">
               <div id="portal-container">
               <div id="sizer">
               <div id="expander">
               <div id="logoName"></div>
               <table border="0" cellpadding="0" cellspacing="0" id="header-container">
               <tr>
               <td align="center" valign="top" id="header"><div id="spacer"></div></td>
               </tr>
               </table>
               <div id="content-container">
               <p:region regionName='This-Is-The-Page-Region-To-Query-The-Page'
               regionID='This-Is-The-Tag-ID-Attribute-To-Match-The-CSS-Selector'/>
               <p:region regionName='left' regionID='regionA'/>
               <p:region regionName='center' regionID='regionB'/>
               <hr class="cleaner" />
               <div id="footer-container" class="portal-copyright">Powered by
               <a class="portal-copyright" href="http://www.jboss.com/products/jbossportal">JBoss Portal</a><br/>
               Theme by <a class="portal-copyright" href="http://www.novell.com">Novell</a>
               </div>
               </div>
               </div>
               </div>
               </div>
               </body>
               </html>
               

For the function of the individual tags in this example, please refere to the layout section of this document.

12.5.4. How to write your own Theme

Ask your favorite web designer and/or consult the ThemeStyleGuide in this document ;)

12.6. Other Theme Functionalities and Features

This section contains all the functionalities that don't fit with any of the other topics. Bits and pieces of useful functions that are related to the theme and layout functionality.

12.6.1. Content Rewriting and Header Content Injection

Portlets can have their content rewritten by the portal. This is useful if you want to uniquely namespace markup (JavaScript functions for example) in the scope of a page. The rewrite functionality can be applied to the portlet content (the markup fragment) and to content a portlet wants to inject into the header. The rewrite is implemented as specified in the WSRP (OASIS: Web Services for Remote Portlets; producer write). As a result of this, the token to use for rewrite is the WSRP specified "wsrp_rewrite_". If the portlet sets the following response property

res.setProperty("WSRP_REWRITE","true");

all occurences of the wsrp_rewrite_ token in the portlet fragment will be replaced with a unique token (the window id). If the portlet also specifies content to be injected into the header of the page, that content is also subject to this rewrite.

res.setProperty("HEADER_CONTENT", "<script>function wsrp_rewrite_OnFocus(){alert('hello button');}</script>");

Note that in order for the header content injection to work, the layout needs to make use of the headerContent JSP tag, like:

            
            <%@ taglib uri="/WEB-INF/theme/portal-layout.tld" prefix="p" %>
            <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
            <html xmlns="http://www.w3.org/1999/xhtml">
            <head>
            <title><JBoss Portal 2.2 early</title>
            <meta http-equiv="Content-Type" content="text/html;" />
            
            <p:headerContent />
            
            </head>
            <body id="body">
            <p>...</p>
            </body>
            </html>
            

12.6.2. Declarative CSS Style injection

If a portlet needs a CSS style sheet to be injected via a link tag in the page header, it can do so by providing the context relative URI to the file in the jboss-portlet.xml descriptor, like:

            
            <portlet-app>
            <portlet>
            <portlet-name>HeaderContentPortlet</portlet-name>
            <header-content>
            <link rel="stylesheet" type="text/css" href="/portlet-styles/HeaderContent.css" title="" media="screen" />
            </header-content>
            </portlet>
            </portlet-app>
            

This functionality, just like the previously described header content injection, requires the layout JSP to add the "headerContent" JSP tag (see example above). One thing to note here is the order of the tags. If the headerContent tag is placed after the theme tag, it will allow portlet injected CSS files to overwrite the theme's behaviour, making this feature even more powerful!

12.6.3. Disabling Portlet Decoration

One possible use of window properties is demonstrated in the divRenderer RenderSet implementation. If a window definition (in the portal descriptor) contains a property like:

            
            <window>
               <window-name>HintPortletWindow</window-name>
               <instance-ref>HintPortletInstance</instance-ref>
               <region>center</region>
               <height>0</height>
               <properties>
                  <!-- turn the decoration off for this portlet (i.e. no title and mode/state links) -->
                  <property>
                     <name>theme.decorationRendererId</name>
                     <value>emptyRenderer</value>
                  </property>
               </properties>
            </window>
            

the DivWindowRenderer will use the decoration renderer from the emptyRenderer RenderSet to render the decoration for this window (not delegate to the DivDecorationRenderer). As a result, the portlet window will be part of the rendered page, but it will not have a title, nor will it have any links to change the portlet mode or window state.

12.7. Theme Style Guide (based on the Industrial theme)

12.7.1. Overview

This document outlines the different selectors used to handle the layout and look/feel of the Industrial theme included in the JBoss portal.

A couple of things to know about the theming approach discussed below:

  • Main premise behind this approach was to provide a clean separation between the business and presentation layer of the portal. As we go through each selector and explain the relation to the visual presentation on the page, this will become more apparent.
  • The flexibility of the selectors used in the theme stylesheet allow a designer to very easily customize the visual aspects of the portal, thereby taking the responsibility off of the developers hands through allowing the designer to quickly achieve the desired effect w/out the need to dive down into code and/or having to deploy changes to the portal. This saves time and allows both developers and designers to focus on what they do best.
  • This theme incorporates a liquid layout approach which allows elements on a page to expand/contract based on screen resolution and provides a consistent look across varying display settings. However, the stylesheet is adaptable to facilitate a fixed layout and/or combination approach where elements are pixel based and completely independent of viewport.
  • The pieces that make up the portal theme consist of at least one stylesheet and any associated images. Having a consolidated set of files to control the portal look and feel allows administrators to effortlessly swap themes on the fly. In addition, this clean separation of the pieces that make up a specific theme will enable sharing and collaboration of different themes by those looking to get involved or contribute to the open source initiative.

12.7.2. Main Screen Shot

Screen shot using color outline of main ID selectors used to control presentation and layout:

  • Red Border - portal-container
  • Yellow Border - header-container
  • Orange Border - content-container
  • Blue Border - regionA/regionB
  • Green Border - portlet-container

12.7.3. List of CSS Selectors

The following is a list of the selectors used in the theme stylesheet, including a brief explanation of how each selector is used in the portal:

  • Portal Body Selector

                         #body {
                         background-image: url(images/portal_background.gif);
                         margin: 0px;
                         padding: 0px;
                         }
                      

    Usage: This selector controls the background of the page, and can be modified to set a base font-family, layout margin, etc. that will be inherited by all child elements that do not have their own individual style applied. By default, the selector pulls an image background for the page.

  • Portal Header Selectors

                         #spacer {
                         width: 1024px;
                         line-height: 0px;
                         font-size: 0px;
                         height: 0px;
                         }
                      

    Usage: Spacer div used to keep header at certain width regardless of display size. This is done to avoid overlapping of tab navigation in header. To account for different display sizes, this selector can be modified to force a horizontal scroll in the browser which eliminates any issue with overlapping elements in the header.

                         #header-container {
                         background-image: url(images/portal_background.gif);
                         background-repeat: repeat-y;
                         height: 100%;
                         min-width: 1000px;
                         width: 100%;
                         /* test to reposition header on page
                         position: absolute;
                         bottom: 5px;*/
                         }
                      

    Usage: Wrapper selector used to control the position of the header on the page (see yellow border in screen shot). This selector is applied as an ID on the table used to structure the header. You can adjust the attributes to reposition the header location on the page and/or create margin space on the top, right, bottom and left sides of the header.

    Screenshot:

                         #header {
                         background-image: url(images/header.gif);
                         background-repeat: repeat-x;
                         height: 100px;
                         padding: 0px;
                         /*margin: 0 25% 0 25%;*/
                         }
                      

    Usage: This selector applies the header background image in the portal. It can be adjusted to accommodate a header background of a certain width/height or, as it currently does, repeat the header graphic so that it tiles across the header portion of the page.

                         #logoName {
                         background-image: url(images/JBossLogo.gif);
                         background-repeat: no-repeat;
                         width: 187px;
                         height: 35px;
                         position: absolute;
                         left: 15px;
                         top: 16px;
                         z-index: 2;
                         }
                      

    Usage: Logo selector which is used to brand the header with a specific, customized logo. The style is applied as an ID on an absolutely positioned DIV element which enables it to be moved to any location on the page, and allows it to be adjusted to accommodate a logo of any set width/height.

  • Portal Layout Region Selectors

                         #portal-container {
                         /*width: 100%;*/
                         
                         /*IE specific approach to preserve min-width for portlet regions 	*/
                         padding: 0 350px 0 350px;
                         }
                      

    Usage: Wrapper for entire portal which starts/ends after/before the BODY tag (see red border in screen shot). The padding attribute for this selector is used to preserve a minimum width setting for the portlet regions (discussed below). Similar to body selector, this style can modified to create margin or padding space on the top, right, bottom and left sections of the page. It provides the design capability to accommodate most layouts (e.g. a centered look such as the phalanx theme where there is some spacing around the content of the portal, or a full width look as illustrated in the Industrial theme).

    Screenshot:

                         /* min width for IE */
                         #expander {
                         margin: 0 -350px 0 -350px;
                         position: relative;
                         }
                         
                         /* min width for IE */
                         #sizer {
                         width: 100%;
                         }
                         
                         /* IE min width \*/
                         * html #portal-container,
                         * html #sizer,
                         * html #expander { height: 0; }
                      

    Usage: These selectors are used in conjunction with the above, portal-container, selector to preserve a minimum width setting for the portlet regions. This was implemented to maintain a consistent look across different browsers.

                         /*table that contains all regions. does not include header*/
                         #content-container {
                         height: 100%;
                         text-align:left;
                         max-width: 1600px;
                         min-width: 800px;
                         }
                      

    Usage: Wrapper that contains all regions in portal with the exception of the header (see orange border in screen shot). Its attributes can be adjusted to create margin space on page, as well as control positioning of the area of the page below the header.

    Screenshot:

                         #regionA {
                         /* test to swap columns with regionB...
                         float: right; */
                         
                         width: 30%;
                         float: left;
                         margin: 0px;
                         padding: 0px;
                         min-width: 250px;
                         }
                      

    Usage: First portlet region located within the content-container (see blue border in screen shot). This selector controls the width of the region as well as its location on the page. Designers can very easily reposition this region in the portal (e.g. swap left regionA with right regionB, etc.) by adjusting the attributes of this selector.

                         #regionB {
                         /*test to swap columns with regionA...
                         margin: 0 30% 0 0; */
                         
                         /* two column layout*/
                         margin: 0 0 0 30%;
                         padding: 0;
                         width: 69%;
                         
                         /* test to add 3rd region in layout...
                         width: 40%;
                         float: left;*/
                         }
                      

    Usage: Second portlet region located within the content-container (see blue border in screen shot). Similar to regionA, this selector controls the width of the region as well as its location on the page.

                         #regionC {
                         /* inclusion of 3rd region - comment out for 2 region testing
                         padding: 0px;
                         width: 27%;
                         float: left;*/
                         display: none;
                         }
                      

    Usage: Third portlet region located within the content-container (please refer to blue border in screen shot representing regionA and regionB for an example). Used for 3 column layout. Similar to regionA and regionB, this selector controls the width of the region as well as its location on the page.

                         /* give a maximized portlet more space */
                         #regionMaximized {
                         width: 100%;
                         float: left;
                         margin: 0px;
                         padding: 0px;
                         min-width: 400px;
                         }
                      

    Usage: Portlet region located within the content-container (please refer to blue border in screen shot representing regionA and regionB for an example). Used for a one column layout to allow one portlet to take over the entire page. Similar to regionA, regionB, and regionB, this selector controls the width of the region as well as its location on the page.

    Screenshot:

                         hr.cleaner {
                         clear:both;
                         height:1px;
                         margin: -1px 0 0 0;
                         padding:0;
                         border:none;
                         visibility: hidden;
                         }
                      

    Usage: Used to clear floats in regionA, regionB and regionC DIVs so that footer spans bottom of page.

                         #footer-container {
                         margin: 30px 25% 0 25%;
                         text-align: center;
                         }
                      

    Usage: Footer region located towards the bottom of the content-container (see above screen shot). This region spans the entire width of the page, but can be adjusted (just like regionA, regionB and regionC) to take on a certain position and width/height in the layout.

                         #navigation-container {}
                      

    Usage: Unused at this time.

                         #sub-navigation-container {}
                      

    Usage: Unused at this time.

  • Tab Navigation Selectors for Header

                         UL#tabsHeader {
                         margin: 0;
                         padding-left: 300px;
                         min-width: 550px;
                         }
                      

    Usage: Used to provide position (through padding attribute) of tabbed navigational items in header. A padding-left of 300px gives space for the left hand logo area and can be adjusted as needed to set the desired location for the navigation.

                         UL#tabsHeader li {
                         list-style: none;
                         float: left;
                         margin-left: 0px;
                         margin-top: 74px;
                         margin-right: 0px;
                         line-height: 24px;
                         padding: 0px;
                         border-left: 1px solid #72828E;
                         }
                      

    Usage: Selector used to style list items as horizontal navigation and to set the spacing and position of each nav item that's available.

                         UL#tabsHeader li:hover {
                         background-image: url(images/highlightedTab.gif);
                         background-repeat: repeat-x;
                         }
                      

    Usage: Used to provide hover pseudo class on navigation items so that the tab background will change upon mouseover. Note that currently IE only supports the hover pseudo class on links, so this selector will only affect non-IE browsers (e.g. FireFox, etc.).

                         UL#tabsHeader li.hoverOn {
                         background-image: url(images/highlightedTab.gif);
                         background-repeat: repeat-x;
                         }
                         
                         UL#tabsHeader li.hoverOff {
                         background-image:none;
                         }
                      

    Usage: These two selectors are implemented to account for the fact that IE cannot understand the use of a pseudo class on the LI element. They provide the same mouseover effect as the “UL#tabsHeader li:hover�? selector when hovering the navigation item in IE, and are used in combination with onmouseover/onmouseout event handlers in the header navigation:

                         
                         <li onmouseover="this.className='hoverOn'" onmouseout="this.className='hoverOff'">
                         <a href="#">Tab Nav</a>
                         </li>
                         

                         UL#tabsHeader a {
                         display: block;
                         float: left;
                         padding: 4px 15px 5px 15px;
                         text-decoration: none;
                         font: 13px/normal Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         background: 100% 0 no-repeat;
                         color: #596874;
                         }
                      

    Usage: This selector styles the navigational links, indicating padding surrounding the link as well as font family, color and text-decoration.

                         UL#tabsHeader a:hover {
                         text-decoration: underline;
                         }
                      

    Usage: Used to underline navigational links when hovering with mouse. Unlike the li:hover pseudo class, IE does support the hover effect on links, so there is no need for a separate set of selectors to deal with this effect.

                         UL#tabsHeader #current, UL#tabsHeader #current a {
                         font: 13px/normal Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-weight: 600;
                         color: #EBEAEA;
                         background-image: url(images/activeTab.gif);
                         background-repeat: repeat-x;
                         border-right: 0px;
                         border-left: 0px;
                         }
                      

    Usage: This selector is set on the current/selected navigation item to style both the background of the tab as well as font properties such as color and weight. Example:

                         
                         <li id="current" onmouseover="this.className='hoverOn'" onmouseout="this.className='hoverOff'">
                         <a href="#">Tab Nav</a>
                         </li>
                         

                         /* backslash for IE5-Mac \*/
                         UL#tabsHeader a {float: none;} /* End Mac Hack */
                         html>body UL#tabsHeader a {width: auto;} /* fixes IE issues */
                      

    Usage: Also known in the industry as an example of the “Holly Hack�?, the above is added to the stylesheet to handle certain buggy issues with IE. This section of the stylesheet should be left alone as subsequent changes can effect the way things behave in IE.

                         li.currentTabBackground {
                         background: #fff;
                         }
                         
                         li.currentTabBackgroundSubNav {
                         background: #eeeeef;
                         }
                      

    Usage: The above two selectors are not currently in use. Included to account for future changes to the navigation where multiple tiers/levels might be incorporated.

  • Portlet Container Window Selectors

                         .portlet-container {
                         padding: 10px;
                         }
                      

    Usage: Wrapper that surrounds the portlet windows (see green border in screen shot). Currently, this selector is used to create space (padding) between the portlets displayed in each particular region.

    Screenshot:

                         .portlet-titlebar-title {
                         font-family: Verdana, Arial, Helvetica, sans-serif;
                         font-size: 11px;
                         font-weight: 500;
                         color: #596874;
                         white-space: nowrap;
                         line-height: 100%;
                         float: left;
                         text-indent: 15px;
                         }
                      

    Usage: Class used to style the title of each portlet window. Attributes of this selector set font properties, indentation and position of title.

                         .portlet-titlebar-decoration {
                         background-image: url(images/portlet-win-decoration.gif);
                         background-repeat: no-repeat;
                         height: 11px;
                         width: 11px;
                         float: left;
                         position: relative;
                         top: 6px;
                         }
                      

    Usage: Used to display top left portlet window decoration (e.g. sphere icon in Industrial theme). Attributes for this selector set position and dimensions of this decoration.

                         .portlet-mode-container {
                         float: right;
                         }
                      

    Usage: Wrapper that contains the portlet window modes that display in the top right section of the portlet windows.

                         .portlet-titlebar-left {
                         background-image: url(images/portlet-top-left.gif);
                         background-repeat: no-repeat;
                         width: 9px;
                         height: 33px;
                         background-position: right;
                         min-width: 9px;
                         }
                      

    Usage: Used to style the top left corner of the portlet window. Each portlet window consists of one table that has 3 columns and 3 rows. This selector styles the first column (TD) in the first row (TR).

    Screenshot:

                         .portlet-titlebar-center {
                         background-image: url(images/portlet-top-middle.gif);
                         background-repeat: repeat-x;
                         height: 33px;
                         }
                      

    Usage: Used to style the center section of the portlet title bar. Each portlet window consists of one table that has 3 columns and 3 rows. This selector styles the second column (TD) in the first row (TR).

    Screenshot:

                         .portlet-titlebar-right {
                         background-image: url(images/portlet-top-right.gif);
                         background-repeat: no-repeat;
                         width: 10px;
                         height: 33px;
                         min-width: 10px;
                         }
                      

    Usage: Used to style the top right corner of the portlet window. Each portlet window consists of one table that has 3 columns and 3 rows. This selector styles the third column (TD) in the first row (TR).

    Screenshot:

                         .portlet-content-left {
                         background-image: url(images/portlet-left-vertical.gif);
                         height: 100%;
                         background-repeat: repeat-y;
                         background-position: right;
                         width: 9px;
                         min-width: 9px;
                         }
                      

    Usage: Used to style the left hand vertical lines that make up the portlet window. Each portlet window consists of one table that has 3 columns and 3 rows. This selector styles the first column (TD) in the second row (TR).

    Screenshot:

                         .portlet-content-center {
                         background-color: #f7f7f7;
                         background-repeat: repeat;
                         vertical-align: top;
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 13px;
                         }
                      

    Usage: Used to style the center, content area where the portlet content is injected into the portlet window (see below screen). Attributes for this selector control the positioning of the portlet content as well as the background and font properties. Each portlet window consists of one table that has 3 columns and 3 rows. This selector styles the second column (TD) in the second row (TR).

    Screenshot:

                         .portlet-body {
                         background-color: #f7f7f7;
                         }
                      

    Usage: An extra selector for controlling the content section of the portlet windows (see below screen). This was added to better deal with structuring the content that gets inserted/rendered in the portlet windows, specifically if the content is causing display problems in a portlet.

    Screenshot:

                         .portlet-content-right {
                         background-image: url(images/portlet-right-vertical.gif);
                         height: 100%;
                         background-repeat: repeat-y;
                         background-position: left;
                         width: 10px;
                         min-width: 10px;
                         }
                      

    Usage: Used to style the right hand vertical lines that make up the portlet window. Each portlet window consists of one table that has 3 columns and 3 rows. This selector styles the third column (TD) in the second row (TR).

    Screenshot:

                         .portlet-footer-left {
                         background-image: url(images/portlet-bottom-left.gif);
                         width: 9px;
                         height: 9px;
                         background-repeat: no-repeat;
                         background-position: top right;
                         min-width: 9px;
                         }
                      

    Usage: Used to style the bottom left corner of the portlet window. Each portlet window consists of one table that has 3 columns and 3 rows. This selector styles the first column (TD) in the third row (TR).

    Screenshot:

                         .portlet-footer-center {
                         background-image: url(images/portlet-bottom-middle.gif);
                         height: 14px;
                         background-repeat: repeat-x;
                         }
                      

    Usage: Used to style the bottom, center of the portlet window (i.e. the bottom horizontal line in the Industrial theme). Each portlet window consists of one table that has 3 columns and 3 rows. This selector styles the second column (TD) in the third row (TR).

    Screenshot:

                         .portlet-footer-right {
                         background-image: url(images/portlet-bottom-right.gif);
                         width: 10px;
                         height: 9px;
                         background-repeat: no-repeat;
                         min-width: 10px;
                         }
                      

    Usage: Used to style the bottom right corner of the portlet window. Each portlet window consists of one table that has 3 columns and 3 rows. This selector styles the third column (TD) in the third row (TR).

    Screenshot:

  • Portlet Window Mode Selectors

                         .portlet-mode-maximized {
                         background-image: url(images/maximize.gif);
                         width: 16px;
                         height: 23px;
                         background-repeat: no-repeat;
                         float: left;
                         display: inline;
                         cursor: pointer;
                         }
                      

    Usage: Selector used to display the portlet maximize mode. Attributes for this selector control the display and dimensions of the maximize icon, including the behavior of the mouse pointer when hovering the mode.

                         .portlet-mode-minimized {
                         background-image: url(images/minimize.gif);
                         width: 16px;
                         height: 23px;
                         background-repeat: no-repeat;
                         float: left;
                         display: inline;
                         cursor: pointer;
                         }
                      

    Usage: Selector used to display the portlet minimize mode. Attributes for this selector control the display and dimensions of the minimize icon, including the behavior of the mouse pointer when hovering the mode.

                         .portlet-mode-normal {
                         background-image: url(images/normal.gif);
                         width: 16px;
                         height: 23px;
                         background-repeat: no-repeat;
                         float: left;
                         display: inline;
                         cursor: pointer;
                         }
                      

    Usage: Selector used to display the portlet normal mode (i.e. the icon that when clicked, restores the portlet to the original, default view). Attributes for this selector control the display and dimensions of the normal icon, including the behavior of the mouse pointer when hovering the mode.

                         .portlet-mode-help {
                         background-image: url(images/help.gif);
                         width: 16px;
                         height: 23px;
                         background-repeat: no-repeat;
                         float: left;
                         display: inline;
                         cursor: pointer;
                         }
                      

    Usage: Selector used to display the portlet help mode. Attributes for this selector control the display and dimensions of the help icon, including the behavior of the mouse pointer when hovering the mode.

                         .portlet-mode-edit {
                         background-image: url(images/edit.gif);
                         width: 16px;
                         height: 23px;
                         background-repeat: no-repeat;
                         float: left;
                         display: inline;
                         cursor: pointer;
                         }
                      

    Usage: Selector used to display the portlet edit mode. Attributes for this selector control the display and dimensions of the edit icon, including the behavior of the mouse pointer when hovering the mode.

                         .portlet-mode-remove {
                         background-image: url(images/remove.gif);
                         width: 16px;
                         height: 23px;
                         background-repeat: no-repeat;
                         float: left;
                         display: inline;
                         cursor: pointer;
                         }
                      

    Usage: Currently not available. But here is the intended use: Selector used to display the portlet remove mode. Attributes for this selector control the display and dimensions of the remove icon, including the behavior of the mouse pointer when hovering the mode.

                         .portlet-mode-view {
                         background-image: url(images/view.gif);
                         width: 16px;
                         height: 23px;
                         background-repeat: no-repeat;
                         float: left;
                         display: inline;
                         cursor: pointer;
                         }
                      

    Usage: Selector used to display the portlet view mode. Attributes for this selector control the display and dimensions of the view icon, including the behavior of the mouse pointer when hovering the mode.

                         .portlet-mode-reload {
                         background-image: url(images/reload.gif);
                         width: 16px;
                         height: 23px;
                         background-repeat: no-repeat;
                         float: left;
                         display: inline;
                         cursor: pointer;
                         }
                      

    Usage: Currently not available. But here is the intended use: Selector used to display the portlet reload mode. Attributes for this selector control the display and dimensions of the reload icon, including the behavior of the mouse pointer when hovering the mode.

  • Copyright Selectors

                         .portal-copyright {
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 9px;
                         color: #5E6D7A;
                         }
                         
                         a.portal-copyright {
                         color: #768591;
                         text-decoration: none;
                         }
                         
                         a.portal-copyright:hover  {
                         color: #96A5B1;
                         text-decoration: none;
                         }
                      

    Usage: The above three selectors are used to style copyright content in the portal. The portal-copyright selector sets the font properties (color, etc.), and the a.portal-copyright/a.portal-copyright:hover selectors style any links that are part of the copyright information.

  • Element Selectors

                         a {
                         color: #768591;
                         text-decoration: none;
                         }
                         a:hover  {
                         color: #96A5B1;
                         text-decoration: none;
                         }
                      

    Usage: The above two selectors style all anchor elements that do not have their own class/selector applied.

                         INPUT {
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 10px;
                         }
                      

    Usage: The above selector styles all INPUT elements that do not have their own class/selector applied.

                         SELECT {
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 10px;
                         }
                      

    Usage: The above selector styles all SELECT elements that do not have their own class/selector applied.

                         FONT {
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 10px;
                         color: #768591;
                         }
                      

    Usage: The above selector styles all FONT elements that do not have their own class/selector applied.

                         FIELDSET {
                         background-color: #f7f7f7;
                         border:1px solid #BABDB6;
                         padding: 6px;
                         }
                      

    Usage: The above selector styles all FIELDSET elements that do not have their own class/selector applied.

                         LEGEND {
                         background-color: transparent;
                         padding-left: 6px;
                         padding-right: 6px;
                         padding-bottom: 0px;
                         font-size: 14px;
                         }
                      

    Usage: The above selector styles all LEGEND elements that do not have their own class/selector applied.

  • Table Selectors

                         .portlet-table-header {}
                      

    Usage: Not currently in use. Intended for styling tables (specifically, the TH or table header elements) that get rendered within a portlet window.

                         .portlet-table-body {}
                      

    Usage: Not currently in use. Intended for styling the table body element used to group rows in a table.

                         .portlet-table-alternate {}
                      

    Usage: Not currently in use. Used to style the background color (and possibly other attributes) for every other row within a table.

                         .portlet-table-selected {}
                      

    Usage: Not currently in use. Used to style text, color, etc. in a selected cell range.

                         .portlet-table-subheader {}
                      

    Usage: Not currently in use. Used to style a subheading within a table that gets rendered in a portlet.

                         .portlet-table-footer {}
                      

    Usage: Not currently in use. Similar to portlet-table-header and portlet-table-body, this selector is used to style the table footer element which is used to group the footer row in a table.

                         .portlet-table-text {}
                      

    Usage: Text that belongs to the table but does not fall in one of the other categories (e.g. explanatory or help text that is associated with the table). This selector can also be modified to provide styled text that can be used in all tables that are rendered within a portlet.

  • FONT Selectors

                         .portlet-font {
                         color:#000;
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 10px;
                         }
                      

    Usage: Used to style the font properties on text used in a portlet. Typically this class is used for the display of non-accentuated information.

                         .portlet-font-dim {
                         color:#888385;
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 10px;
                         }
                      

    Usage: A lighter version (color-wise) of the portlet-font selector.

  • FORM Selectors

                         .portlet-form-label {
                         color:#4A4A4A;
                         text-decoration:none;
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 9px;
                         }
                      

    Usage: Text used for the descriptive label of an entire form (not the label for each actual form field).

                         .portlet-form-button {
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 9px;
                         font-weight: bold;
                         color: #270F07;
                         }
                      

    Usage: Used to style portlet form buttons (e.g. Submit).

                         .portlet-icon-label {}
                      

    Usage: Not currently in use. Text that appears beside a context dependent action icon.

                         .portlet-dlg-icon-label {}
                      

    Usage: Not currently in use. Text that appears beside a "standard" icon (e.g Ok, or Cancel).

                         .portlet-form-field-label {
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 9px;
                         color: #4A4A4A;
                         }
                      

    Usage: Selector used to style portlet form field labels.

                         .portlet-form-field {
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 9px;
                         color: #4A4A4A;
                         margin-top: 10px;
                         }
                      

    Usage: Selector used to style portlet form fields (i.e. INPUT controls, SELECT elements, etc.).

  • LINK Selectors

                         .portal-links:link {
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 9px;
                         font-weight: bold;
                         color: #242424;
                         text-decoration: none;
                         }
                         
                         .portal-links:hover  {
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 9px;
                         font-weight: bold;
                         color: #5699B7;
                         text-decoration: none;
                         }
                         
                         .portal-links:active {
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 9px;
                         font-weight: bold;
                         color: #242424;
                         text-decoration: none;
                         }
                         
                         .portal-links:visited {
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 9px;
                         font-weight: bold;
                         color: #242424;
                         text-decoration: none;
                         }
                      

    Usage: The above four selectors are used to style links in the portal. Each pseudo class (i.e. hover, active, etc.) provides a different link style.

  • MESSAGE Selectors

                         .portlet-msg-status {
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 10px;
                         font-style: normal;
                         color: #788793;
                         }
                      

    Usage: Selector used to signify the status of a current operation that takes place in the portlet (e.g. “saving results�?, “step 1 of 4�?).

                         .portlet-msg-info {
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 9px;
                         font-style: italic;
                         color: #000;
                         }
                      

    Usage: Selector used to signify general information in a portlet (e.g. help messages).

                         .portlet-msg-error {
                         color:red;
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 9px;
                         font-weight: bold;
                         }
                      

    Usage: Selector used to signify an error message in the portlet (e.g. form validation error).

                         .portlet-msg-alert {
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 9px;
                         font-weight: bold;
                         color: #821717;
                         }
                      

    Usage: Selector used to style an alert that is displayed to the user.

                         .portlet-msg-success {
                         font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular;
                         font-size: 9px;
                         font-weight: bold;
                         color: #359630;
                         }
                      

    Usage: Selector used to indicate successful completion of an action in a portlet (e.g. “save successful�?).

  • SECTION Selectors

                         .portlet-section-header {
                         font-weight: bold;
                         font-family: Verdana, Arial, Helvetica, sans-serif;
                         font-size: 13px;
                         color: #768591;
                         background-color: #f7f7f7;
                         }
                      

    Usage: Table or section header.

                         .portlet-section-body {
                         font-family: Verdana, Arial, Helvetica, sans-serif;
                         font-size: 10px;
                         }
                      

    Usage: Normal text in a table cell.

                         .portlet-section-alternate {
                         background-color: #ececed;
                         font-family: Verdana, Arial, Helvetica, sans-serif;
                         font-size: 9px;
                         }
                      

    Usage: Used to style background color and text in every other table row.

                         .portlet-section-selected {
                         background-color: #89AEC6;
                         font-family: Verdana, Arial, Helvetica, sans-serif;
                         font-size: 9px;
                         }
                      

    Usage: Used to style background and font properties in a selected cell range.

                         .portlet-section-subheader {
                         font-weight: bold;
                         font-size: 10px;
                         font-family: Verdana, Arial, Helvetica, sans-serif;
                         color: #000;
                         }
                      

    Usage: Used to style a subheading within a table/section that gets rendered in a portlet.

                         .portlet-section-footer {
                         font-family: Verdana, Arial, Helvetica, sans-serif;
                         background-color: #f7f7f7;
                         font-size: 8px;
                         }
                      

    Usage: Used to style footer area of a section/table that gets rendered in a portlet.

                         .portlet-section-text {}
                      

    Usage: Not currently used. Text that belongs to a section but does not fall in one of the other categories. This selector can also be modified to provide styled text that can be used in all sections that are rendered within a portlet.

  • MENU Selectors

                         .portlet-menu {}
                      

    Usage: Not currently used. General menu settings such as background color, margins, etc.

                         .portlet-menu-item {
                         color: #242424;
                         text-decoration: none;
                         font-family: Verdana, Arial, Helvetica, sans-serif;
                         font-size: 9px;
                         }
                      

    Usage: Not currently used. Normal, unselected menu item.

                         .portlet-menu-item:hover {
                         color: #5699B7;
                         text-decoration: none;
                         font-family: Verdana, Arial, Helvetica, sans-serif;
                         font-size: 9px;
                         }
                      

    Usage: Not currently used. Used to style hover effect on a normal, unselected menu item.

                         .portlet-menu-item-selected {}
                      

    Usage: Not currently used. Applies to selected menu items.

                         .portlet-menu-item-selected:hover {
                         
                         }
                      

    Usage: Not currently used. Selector styles the hover effect on a selected menu item.

                         .portlet-menu-cascade-item {}
                      

    Usage: Not currently used. Normal, unselected menu item that has sub-menus.

                         .portlet-menu-cascade-item-selected {}
                      

    Usage: Not currently used. Selected sub-menu item.

                         .portlet-menu-description {}
                      

    Usage: Not currently used. Descriptive text for the menu (e.g. in a help context below the menu).

                         .portlet-menu-caption {}
                      

    Usage: Not currently used. Selector used to style menu captions.

  • WSRP Selectors

                         .portlet-horizontal-separator {}
                      

    Usage: Not currently used. A separator bar similar to a horizontal rule, but with styling matching the page.

                         .portlet-nestedTitle-bar {}
                      

    Usage: Not currently used. Allows portlets to mimic the title bar when nesting something.

                         .portlet-nestedTitle {}
                      

    Usage: Not currently used. Allows portlets to match the textual character of the title on the title bar.

                         .portlet-tab {}
                      

    Usage: Not currently used. Support portlets having tabs in the same style as the page or other portlets.

                         .portlet-tab-active {}
                      

    Usage: Not currently used. Highlight the tab currently being shown.

                         .portlet-tab-selected {}
                      

    Usage: Not currently used. Highlight the selected tab (not yet active).

                         .portlet-tab-disabled {}
                      

    Usage: Not currently used. A tab which can not be currently activated.

                         .portlet-tab-area {}
                      

    Usage: Not currently used. Top level style for the content of a tab.

Chapter 13. Troubleshooting and FAQ

Roy Russo

13.1. Troubleshooting and FAQ

Installation / Configuration

CMS

Errors

Miscellaneous

I am seeing "ERROR [JDBCExceptionReporter] Table not found in statement" in the logfile on first boot. What is this?

Ignore this error. It is used by the portal to create the initial database tables. On second boot, you should not see them at all.

I want to do a clean install/upgrade over my existing one. What are the steps?

  • Shut down JBoss AS
  • Delete JBOSS_HOME/server/default/data/portal
  • Delete all JBoss Portal tables from your database
  • Start JBoss AS.

Is my database vendor/version combination supported?

See Section 1.4, “Database”

How do I force the Hibernate Dialect used for my database?

See Section 3.3, “Forcing the DB dialect”

How do I change the context-root of the portal to http://localhost:8080/?

See Section 3.2, “Changing the context path”

How do I change the CMS repository configuration?

There are 3 supported modes: 100% DB (default), 100% Filsystem, and Mixed (Blobs on the Filesystem and metadata in the DB). You can see configuration options here: Section 11.3.3, “Configuring the Content Store Location”

On reboot, the CMS is complaining about a locked repository.

This occurs when JBoss AS is improperly shutdown or the CMS Service errors on startup. To remove the lock, shutdown JBoss, and then remove the file under JBOSS_HOME/server/default/data/portal/cms/conf/.lock.

I created a file in the CMSAdmin. How do I view it?

Using the default configuration, the path to the file in the browser would be: http://localhost:8080/portal/content/path/to/file.ext. Note that all requests for cms content must be prepended with /content and then followed by the path/to/the/file.gif as it is in your directory structure.

When I access a specific portal-instance or page, I keep seeing "401 - not authorized" error in my browser.

You are likely not authorized to view the page or portal instance. You can either modify the security using the Management Portlet under the Admin Tab, or secure your portlets via the object descriptor, Section 10.1, “Securing Portal Objects”

How do I disable development-mode errors on the presentation layer?

See: Section 6.2.2, “Portlet Debugging (jboss-portal.sar/conf/config.xml)”

Is there a sample portlet I can look at to learn about portlet development and JBoss Portal deployments?