Author: rdickens
Date: 2013-01-17 20:49:30 -0500 (Thu, 17 Jan 2013)
New Revision: 9061
Modified:
epp/docs/branches/6.0/Developer_Guide/en-US/chapter-5-GDG_Application_development.xml
Log:
Source URL:
https://docs.jboss.org/author/display/GTNPORTAL35/GDG-Application+develop...
Incorporated raw docs from Confluence wiki
Modified:
epp/docs/branches/6.0/Developer_Guide/en-US/chapter-5-GDG_Application_development.xml
===================================================================
---
epp/docs/branches/6.0/Developer_Guide/en-US/chapter-5-GDG_Application_development.xml 2013-01-18
00:12:20 UTC (rev 9060)
+++
epp/docs/branches/6.0/Developer_Guide/en-US/chapter-5-GDG_Application_development.xml 2013-01-18
01:49:30 UTC (rev 9061)
@@ -5,8 +5,8 @@
<section id="sid-819807">
<title>Gadget Development</title>
<section id="sid-819807_GDG-GadgetDevelopment-Introduction">
+ <title>Introduction</title>
<remark>Source:
https://docs.jboss.org/author/display/GTNPORTAL35/GDG-Portlet+Development, incorporated
changes up to version 10</remark>
- <title>Introduction</title>
<para>
In the context of JBoss Portal Platform, gadgets are defined by the Google
OpenSocial specifications. Since JBoss Portal Platform &VY;, the portal framework
includes Apache Shindig 2.0 which is made to support the version 0.9 and 1.0 of
OpenSocial.
</para>
@@ -30,11 +30,1144 @@
<section id="sid-819805">
<title>Portlet Development</title>
<para>
- JBoss Enterprise Portal interface is fully customizable with applications
called portlets. Application development can be done by using the plain Portlet
specification JSR-286 (refer to the "Portlet Primer" chapter in the
JBoss Portal Platform Reference Guide for more information), but it is also possible to
use the JBoss Portlet Bridge to write applications with JavaServerFaces (JSF), RichFaces
or Seam (refer to the "Getting started with JBoss Portlet Bridge"
chapter of the JBoss Portal Platform Reference Guide).
+ JBoss Enterprise Portal interface is fully customizable with applications
called portlets. Application development can be done by using the plain Portlet
specification JSR286 (refer to the "Portlet Primer" chapter in the JBoss
Portal Platform Reference Guide for more information), but it is also possible to use the
JBoss Portlet Bridge to write applications with JavaServerFaces (JSF), RichFaces or Seam
(refer to the "Getting started with JBoss Portlet Bridge" chapter of the
JBoss Portal Platform Reference Guide).
</para>
<remark>FIXME: Insert link to "[Starting a Portlet
Project]"</remark>
<para>
Whichever technology you choose, refer to [Starting a Portlet Project] to
learn how to set up your project in a robust and effective way using the JBoss Portal
Platform Bill of Materials (BOM).
</para>
- </section>
+ <section id="sid-55378991">
+
+ <title>Starting a Portlet Project</title>
+ <section
id="sid-55378991_StartingaPortletProject-TheBOMConcept">
+
+ <title>The BOM Concept</title>
+ <para>
+ To make the management of dependencies easier, GateIn Portal Team has
prepared the Bill of Materials (BOM) needed for developing typical portlet applications.
BOM is a Maven
+ <code>pom.xml</code>
+ file which specifies the versions, types and scopes of dependencies which are
granted to be compatible with (or indeed in many cases provided by) GateIn Portal.
+ </para>
+ </section>
+ <section id="sid-55378991_StartingaPortletProject-HowtoUseBOM">
+
+ <title>How to Use GateIn Portal BOM</title>
+ <remark>FIXME: Link to Quickstarts section when it's
available</remark>
+ <para>
+ Let us look at the
+ <code>pom.xml</code>
+ file from Simplest Hello World
+ link linkend="sid-55378941">Quickstart/link
+ below, which contains all necessary details.
+ </para>
+ <para>
+ In its
+ <code><dependencyManagement></code>
+ section, it declares
+ <code><dependency></code>
+ <code>gatein-3.5-bom</code>
+ with
+ <code><scope></code>
+ <code>import</code>
+ . It indicates that the dependency will
+ <emphasis role="italics">de facto</emphasis>
+ be replaced with the dependencies in its
+ <code>dependencyManagement</code>
+ section. Due to this fact, in the
+ <code><dependencies></code>
+ section of the Simplest Hello World
+ <code>pom.xml</code>
+ , we can declare the
+ <code>javax.portlet:portlet-api</code>
+ dependency without specifying its
+ <code><version></code>
+ ,
+ <code><type></code>
+ or
+ <code><scope></code>
+ . All those details are managed by
+ <code>gatein-3.5-bom</code>
+ .
+ </para>
+ <example>
+ <title>Simplest Hello World Portlet</title>
+ <programlisting>
+<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>simplest-hello-world-portlet</artifactId>
+ <groupId>org.gatein.portal.quickstarts</groupId>
+ <name>Simplest Hello World Portlet</name>
+ <version>3.5.0.Final</version>
+ <packaging>war</packaging>
+ <description>The very essence of every possible
portlet.</description>
+ <url>http://www.gatein.org</url>
+ <licenses>
+ <license>
+ <name>Apache License, Version 2.0</name>
+ <distribution>repo</distribution>
+
<url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
+ </license>
+ </licenses>
+
+ <properties>
+ <!-- GateIn Bill of Materials (BOM) version -->
+
<org.jboss.bom.gatein-bom.version>1.0.0.Final</org.jboss.bom.gatein-bom.version>
+
+ <!-- Plugin versions and settings -->
+
<jboss.as.plugin.version>7.1.1.Final</jboss.as.plugin.version>
+ <!-- maven-compiler-plugin -->
+
<maven.compiler.plugin.version>2.5.1</maven.compiler.plugin.version>
+ <maven.compiler.target>1.6</maven.compiler.target>
+ <maven.compiler.source>1.6</maven.compiler.source>
+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <!--
+ Define the version of GateIn we build for. In its dependencyManagement,
+ GateIn Bill of Materials (BOM) specifies the versions, types and scopes
+ of dependencies which are granted to be compatible with (or indeed
+ in many cases provided by) GateIn Portal.
+ -->
+ <dependency>
+ <groupId>org.jboss.bom</groupId>
+ <artifactId>gatein-3.5-bom</artifactId>
+
<version>${org.jboss.bom.gatein-bom.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <!--
+ The versions, scopes and types of these dependencies are managed in
gatein-*-bom.
+ You need to name only groupId and artifactId here.
+ Name only those artifacts you refer to in your code.
+ Look at gatein-*-bom POM file for the complete list of available artifacts.
+ -->
+ <dependency>
+ <groupId>javax.portlet</groupId>
+ <artifactId>portlet-api</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>${project.artifactId}</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.jboss.as.plugins</groupId>
+
<artifactId>jboss-as-maven-plugin</artifactId>
+
<version>${jboss.as.plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+
<artifactId>maven-compiler-plugin</artifactId>
+
<version>${maven.compiler.plugin.version}</version>
+ <configuration>
+
<source>${maven.compiler.source}</source>
+
<target>${maven.compiler.target}</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
+</programlisting>
+ </example>
+ <para>
+ Further steps, after you have set up the
+ <code>pom.xml</code>
+ file for your project, depend on the technology you have chosen for writing
portlets.
+ </para>
+ </section>
+ </section>
+ <section id="sid-55477012">
+
+ <title>Standard Portlet Development (JSR286)</title>
+ <section
id="sid-55477012_StandardPortletDevelopmentJSR286-TheJavaPart">
+
+ <title>The Java Part</title>
+ <remark>FIXME: Link to Quickstarts section when it's
available</remark>
+ <para>
+ After setting up the the Maven
+ <code>pom.xml</code>
+ file as shown in the
+ <link linkend="sid-55378991">previous section</link>
+ , we can continue with implementing a basic JSR286 compatible portlet.
Simplest Hello World Portlet from the
+ link linkend="sid-55378941">GateIn Quickstarts/link
+ collection shows the very essence of every JSR286 Portlet:
+ </para>
+ <example>
+ <title>SimplestHelloWorldPortlet.java</title>
+ <programlisting>
+package org.jboss.portal.portlet.samples;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.portlet.GenericPortlet;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+
+/**
+ * The simplest posible Portlet.
+ *
+ * @author Peter Palaga
+ */
+public class SimplestHelloWorldPortlet extends GenericPortlet {
+ /**
+ * Serves the VIEW mode. Writes "Hello World !" to the response writer.
+ *
+ * @see javax.portlet.GenericPortlet#doView(javax.portlet.RenderRequest,
javax.portlet.RenderResponse)
+ */
+ @Override
+ public void doView(RenderRequest request, RenderResponse response) throws IOException
{
+ PrintWriter writer = response.getWriter();
+ writer.write("Hello World !");
+ writer.close();
+ }
+}
+</programlisting>
+ </example>
+ <para>As you can see in the listing, we have done two important
things:</para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ We extended
+ <code>javax.portlet.GenericPortlet</code>
+ from
+ <code>javax.portlet:portlet-api</code>
+ artifact.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ We have overriden the
+ <code>doView()</code>
+ method.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ In this simplest portlet variant we have decided not to support EDIT and HELP
portlet modes. To add them, just override the
+ <code>doEdit()</code>
+ and
+ <code>doHelp</code>
+ from
+ <code>javax.portlet.GenericPortlet</code>
+ and configure the
+ <code>portlet.xml</code>
+ file accordingly.
+ </para>
+ </section>
+ <section
id="sid-55477012_StandardPortletDevelopmentJSR286-portlet.xml">
+
+ <title>portlet.xml</title>
+ <para>
+ The
+ <code>portlet.xml</code>
+ file for a plain JSR286 portlet is pretty straigtforward:
+ </para>
+ <example>
+ <title>portlet.xml</title>
+ <programlisting>
+<portlet-app
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
version="2.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2...
http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
+ <portlet>
+ <description>Simplest Hello World Portlet is the very essence of
every possible Portlet.</description>
+
<portlet-name>SimplestHelloWorldPortlet</portlet-name>
+ <display-name>Simplest Hello World
Portlet</display-name>
+
<portlet-class>org.jboss.portal.portlet.samples.SimplestHelloWorldPortlet</portlet-class>
+ <supports>
+ <mime-type>text/html</mime-type>
+ <portlet-mode>view</portlet-mode>
+ <!-- You can uncomment the other modes when your portlet-class
supports them
+ <portlet-mode>edit</portlet-mode>
+ <portlet-mode>help</portlet-mode>
+ -->
+ </supports>
+ <portlet-info>
+ <title>Simplest Hello World Portlet</title>
+ </portlet-info>
+ </portlet>
+</portlet-app>
+</programlisting>
+ </example>
+ </section>
+ <section
id="sid-55477012_StandardPortletDevelopmentJSR286-web.xml">
+
+ <title>web.xml</title>
+ <para>
+ There is no need to configure any filters, servlets, mapping & co.
for a plain JSR286 portlet to work but maven-war-plugin by default requires the
+ <code>web.xml</code>
+ . To solve it, just include a
+ <code>web.xml</code>
+ file which contains solely the root element like the following:
+ </para>
+ <example>
+ <title>web.xml</title>
+ <programlisting>
+<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ version="2.5">
+ <!--
+ There is no need to configure any filters, servlets, mapping & co.
for this demo to work
+ but maven-war-plugin by default requires this file.
+ -->
+</web-app>
+</programlisting>
+ </example>
+ </section>
+ <section
id="sid-55477012_StandardPortletDevelopmentJSR286-FurtherSteps">
+
+ <title>Further Steps</title>
+ <para>
+ After having done all the above, it is time to
+ <link linkend="sid-55379158">build and deploy the
portlet</link>
+ ,
+ <ulink
url="https://docs.jboss.org/author/pages/viewpage.action?pageId=5426...
it</ulink>
+ and
+ <ulink
url="https://docs.jboss.org/author/pages/viewpage.action?pageId=5426...
it to a page</ulink>
+ so that you can test its functionality.
+ </para>
+ </section>
+ <section
id="sid-55477012_StandardPortletDevelopmentJSR286-Seealso">
+
+ <title>See also</title>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink
url="https://docs.jboss.org/author/pages/viewpage.action?pageId=5426...
Primer</ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink
url="http://jcp.org/en/jsr/detail?id=286">JSR286</ulink>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section id="sid-55477014">
+
+ <title>JSF2 Portlet Development</title>
+ <para>
+ The Portlet Bridge pre-installed in GateIn Portal allows for implementing
portlets with JavaServer Faces (JSF) 2.1 and RichFaces (RF) 4.2.3. As RichFaces is just a
component library for JavaServer Faces, the guidelines for using both of them is very
similar. More precisely, setup for a JavaServer Faces portlet project is a superset of a
RichFaces project setup. In accordance with that, you need to read both
+ <xref linkend="sid-55477016"/>
+ and
+ <xref linkend="sid-55477018"/>
+ when developing with RichFaces.
+ </para>
+ <section id="sid-55477016">
+
+ <title>Basic JSF Portlet Development</title>
+ <para>JSF stands for JavaServer Pages. The JSF version delivered by the
built-in Portlet Bridge is 2.1.</para>
+ <section
id="sid-55477016_BasicJSFPortletDevelopment-ExampleCode">
+
+ <title>Example Code</title>
+ <remark>FIXME: Link to Quickstarts section when it's
available</remark>
+ <para>
+ This section cites code from JSF2 Hello World Portlet from the
+ link linkend="sid-55378941">GateIn Portal Quickstarts/link
+ collection.
+ </para>
+ <section
id="sid-55477016_BasicJSFPortletDevelopment-pom.xml">
+
+ <title>pom.xml</title>
+ <para>
+ There is only one noticeable difference in
+ <code>pom.xml</code>
+ against what we have shown as a general case in the
+ <xref linkend="sid-55378991"/>
+ section: We need to add different dependencies for JSF:
+ </para>
+ <example>
+ <title>pom.xml</title>
+ <programlisting>
+068. <dependencies>
+069. <!--
+070. The versions, scopes and types of these dependencies are managed in
gatein-*-bom.
+071. You need to name only groupId and artifactId here.
+072. Name only those artifacts you refer to in your code.
+073. Look at gatein-*-bom POM file for the complete list of available
artifacts.
+074. -->
+075. <dependency>
+076.
<groupId>org.jboss.spec.javax.faces</groupId>
+077.
<artifactId>jboss-jsf-api_2.1_spec</artifactId>
+078. </dependency>
+079. <dependency>
+080. <groupId>org.jboss.portletbridge</groupId>
+081. <artifactId>portletbridge-api</artifactId>
+082. </dependency>
+083. </dependencies>
+</programlisting>
+ </example>
+ </section>
+ <section
id="sid-55477016_BasicJSFPortletDevelopment-JSFTemplateFiles">
+
+ <title>JSF Template Files</title>
+ <para>
+ In the following listing you can see the beginning of a typical JSF
portlet template. It is taken from
+ <code>main.xhtml</code>
+ file located in
+ <code>src/main/webapp/pages</code>
+ directory.
+ </para>
+ <para>Code Snippet error: Read timed out.</para>
+ <para>
+ Note that
+ <code><f:view></code>
+ as a root element of the portlet template above prevents an erroneous
+ <code><html></code>
+ within
+ <code><body></code>
+ coming from portal. Moreover, the
+ <code><h:head></code>
+ and
+ <code><h:body></code>
+ elements are always needed for JSF Facelets to work.
+ </para>
+ <para>
+ The following listing shows the use of several JSF elements, such as
+ <code><h:outputLabel></code>
+ ,
+ <code><h:inputText></code>
+ and
+ <code><h:commandButton></code>
+ within
+ <code><h:form></code>
+ .
+ </para>
+ <para>Code Snippet error: Read timed out.</para>
+ <para>
+ The complete source code of the above template can be found in
+ <code>src/main/webapp/pages/main.xhtml</code>
+ of JSF2 Hello World Portlet project.
+ </para>
+ </section>
+ <section
id="sid-55477016_BasicJSFPortletDevelopment-JavaBeans">
+
+ <title>Java Beans</title>
+ <para>
+ In the JSF template file shown above, we refer to
+ <code>helloBean</code>
+ . This bean is implemented in Java as follows:
+ </para>
+ <informalexample>
+ <programlisting>
+26. /**
+27. * {@link HelloBean} is the JSF backing bean for the application, holding the input
data to be re-displayed.
+28. */
+29. @ManagedBean(name = "helloBean")
+30. @SessionScoped
+31. public class HelloBean implements Serializable {
+32.
+33. private static final long serialVersionUID = -6239437588285327644L;
+34.
+35. /**
+36. * Stores the name which will be used to greet the application user.
+37. */
+38. private String name;
+39.
+40. /**
+41. * Initializes {@link #name} with the value {@code "World"}.
+42. */
+43. @PostConstruct
+44. public void postContruct() {
+45. this.name = "World";
+46. }
+47.
+48. /**
+49. * Returns {@link #name}.
+50. *
+51. * @return {@link #name}
+52. */
+53. public String getName() {
+54. return name;
+55. }
+56.
+57. /**
+58. * Set {@link #name}.
+59. *
+60. * @param name
+61. */
+62. public void setName(String name) {
+63. this.name = name;
+64. }
+65.
+66. /**
+67. * Resets {@link #name} to the default value {@code "World"}.
+68. *
+69. * @param ae ignored
+70. */
+71. public void reset(ActionEvent ae) {
+72. this.name = "World";
+73. }
+74.
+75. }
+</programlisting>
+ </informalexample>
+ <para>
+ The
+ <code>@ManagedBean</code>
+ and
+ <code>@SessionScoped</code>
+ annotations allow for omitting of equivalent declarations in the
+ <code>faces-config.xml</code>
+ file.
+ </para>
+ </section>
+ <section
id="sid-55477016_BasicJSFPortletDevelopment-portlet.xml">
+
+ <title>portlet.xml</title>
+ <para>portlet.xml is the place where we tie the JSF templates with
the portlet.</para>
+ <example>
+ <title>portlet.xml</title>
+ <programlisting>
+<portlet-app
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
version="2.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2...
+
http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
+ <portlet>
+ <description>A simple JSF2 portlet.</description>
+ <portlet-name>jsf2HelloWorldPortlet</portlet-name>
+ <display-name>JSF2 Hello World
Portlet</display-name>
+
<portlet-class>javax.portlet.faces.GenericFacesPortlet</portlet-class>
+ <init-param>
+
<name>javax.portlet.faces.defaultViewId.view</name>
+ <value>/pages/main.xhtml</value>
+ </init-param>
+ <init-param>
+
<name>javax.portlet.faces.defaultViewId.edit</name>
+ <value>/pages/edit.xhtml</value>
+ </init-param>
+ <init-param>
+
<name>javax.portlet.faces.defaultViewId.help</name>
+ <value>/pages/help.xhtml</value>
+ </init-param>
+ <init-param>
+
<name>javax.portlet.faces.preserveActionParams</name>
+ <value>true</value>
+ </init-param>
+ <expiration-cache>0</expiration-cache>
+ <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>JSF2 Hello World Portlet</title>
+ </portlet-info>
+ <container-runtime-option>
+ <name>org.gatein.pc.remotable</name>
+ <value>true</value>
+ </container-runtime-option>
+ </portlet>
+</portlet-app>
+
+
+</programlisting>
+ </example>
+ <para>
+ Note that the
+ <code>javax.portlet.faces.defaultViewId.*</code>
+ <code>init-params</code>
+ are used to bind the JSF templates with the respective portlet view
modes.
+ <code>javax.portlet.faces.GenericFacesPortlet</code>
+ as a
+ <code><portlet-class></code>
+ will serve the purpose for most JSF portlets.
+ </para>
+ </section>
+ <section
id="sid-55477016_BasicJSFPortletDevelopment-web.xml">
+
+ <title>web.xml</title>
+ <para>
+ JSF portlets require a few tweaks in the
+ <code>web.xml</code>
+ file:
+ </para>
+ <example>
+ <title>web.xml</title>
+ <programlisting>
+<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
+ <display-name>jsf2-hello-world-portlet</display-name>
+ <context-param>
+ <description>See
https://docs.jboss.org/author/display/PBR/Render+Policy</descripti...
+
<param-name>javax.portlet.faces.RENDER_POLICY</param-name>
+ <param-value>ALWAYS_DELEGATE</param-value>
+ </context-param>
+
+ <!-- The following params are documented here:
http://myfaces.apache.org/core21/myfaces-impl/webconfig.html -->
+ <context-param>
+
<param-name>javax.faces.FACELETS_VIEW_MAPPINGS</param-name>
+ <param-value>*.xhtml</param-value>
+ </context-param>
+ <context-param>
+ <param-name>facelets.DEVELOPMENT</param-name>
+ <param-value>false</param-value>
+ </context-param>
+ <context-param>
+ <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
+ <param-value>.xhtml</param-value>
+ </context-param>
+
+ <servlet>
+ <servlet-name>Faces Servlet</servlet-name>
+
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>*.faces</url-pattern>
+ </servlet-mapping>
+</web-app>
+</programlisting>
+ </example>
+ </section>
+ <section
id="sid-55477016_BasicJSFPortletDevelopment-CustomCSS">
+
+ <title>Custom CSS</title>
+ <para>
+ Portlet Bridge supports loading of CSS resources in the "JSF
way". Just use the
+ <code><h:outputStylesheet library="css"
name="jsf2-hello-world-portlet.css" /></code>
+ as we do in the
+ <code>main.xhtml</code>
+ file above. The
+ <code>jsf2-hello-world-portlet.css</code>
+ file needs to be placed in
+ <code>resources/css</code>
+ folder of the web application.
+ </para>
+ <para>
+ Note that relative paths like
+ <code>url('css/background/jsf-logo.png')</code>
+ do not work when used in CSS loaded via
+ <code><h:outputStylesheet ...></code>
+ . Rather a JSF Expression Language expression
+
<code>#{resource['/css/background/jsf-logo.png']</code>
+ } needs to be used. This expression is dynamically evaluated to a proper
public URL. The path
+ <code>'/css/background/jsf-logo.png'</code>
+ used in the expression is relative to
+ <code>resources</code>
+ folder of the web application. See also
+ <ulink
url="https://docs.jboss.org/author/pages/viewpage.action?pageId=5180...
Serving</ulink>
+ .
+ </para>
+ <example>
+ <title>jsf2-hello-world-portlet.css</title>
+ <programlisting>
+17. div.jsf2HelloWorldPortlet {
+18. padding: 10px;
+19. /* In the following we use a JSF Expression Language expression rather then plain
relative path.
+20. Plain relative paths do not work in JSF portlets. The expression
#{resource['...']} is
+21. dynamically evaluated to a proper public URL. The path
'/css/background/jsf-logo.png'
+22. used in the expression is relative to resources folder of this web
application.
+23. See
https://docs.jboss.org/author/display/PBR/Resource+Serving */
+24. background: url(#{resource['/css/background/jsf-logo.png']}) no-repeat;
+25. background-position-x: 753px;
+26. background-position-y: 10px;
+27. }
+28. div.jsf2HelloWorldPortlet p {
+29. width: 713px;
+30. }
+</programlisting>
+ </example>
+ </section>
+ <section
id="sid-55477016_BasicJSFPortletDevelopment-Internationalization">
+
+ <title>Internationalization</title>
+ <para>
+ Internationalization is supported via standard Java Resource bundles. In
our example project the
+ <code>*.property</code>
+ files of
+ <code>org.jboss.as.quickstarts.jsf.messages</code>
+ resource bundle are stored under
+ <code>src/main/resources/org/jboss/as/quickstarts/jsf</code>
+ . The following settings in
+ <code>faces-config.xml</code>
+ are needed so that this bundle can be used in JSF templates.
+ </para>
+ <example>
+ <title>faces-config.xml</title>
+ <programlisting>
+<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
+ <application>
+ <!-- Declare the internationalization resources -->
+ <resource-bundle>
+ <!-- The resource bundle property files are in
src/main/resources/org/jboss/as/quickstarts/jsf -->
+
<base-name>org.jboss.as.quickstarts.jsf.messages</base-name>
+ <var>msgs</var>
+ </resource-bundle>
+ <locale-config>
+ <default-locale>en</default-locale>
+ <supported-locale>de</supported-locale>
+ </locale-config>
+ </application>
+</faces-config>
+</programlisting>
+ </example>
+ <para>
+ Note that in the above faces-config.xml, we have made our bundle visible
in JSF templates under the variable
+ <code>msgs</code>
+ . Its individual entries can then be accessed using the usual Expression
Language dot notation: e.g.
+ <code>#{msgs.Name</code>
+ }.
+ </para>
+ </section>
+ </section>
+ <section
id="sid-55477016_BasicJSFPortletDevelopment-FurtherSteps">
+
+ <title>Further Steps</title>
+ <para>
+ After having done all the above, it is time to
+ <link linkend="sid-55379158">build and deploy the
portlet</link>
+ ,
+ <ulink
url="https://docs.jboss.org/author/pages/viewpage.action?pageId=5426...
it</ulink>
+ and
+ <ulink
url="https://docs.jboss.org/author/pages/viewpage.action?pageId=5426...
it to a page</ulink>
+ so that you can test its functionality.
+ </para>
+ </section>
+ <section id="sid-55477016_BasicJSFPortletDevelopment-Seealso">
+
+ <title>See also</title>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink
url="https://docs.jboss.org/author/pages/viewpage.action?pageId=5426...
Primer</ulink>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section id="sid-55477018">
+
+ <title>JSF Portlet Development with RichFaces</title>
+ <para>
+ As we have already noted, RichFaces (RF) is just a component library for
JavaServer Faces (JSF). Therefore, everything said in the
+ <xref linkend="sid-55477016"/>
+ chapter applies here too.
+ </para>
+ <section
id="sid-55477018_JSFPortletDevelopmentwithRichFaces-ExampleCode">
+
+ <title>Example Code</title>
+ <remark>FIXME: Link to Quickstarts section when it's
available</remark>
+ <para>
+ This section cites code from JSF2+RF4 Hello World Portlet from the
+ link linkend="sid-55378941">GateIn Portal Quickstarts/link
+ collection.
+ </para>
+ <section
id="sid-55477018_JSFPortletDevelopmentwithRichFaces-pom.xml">
+
+ <title>pom.xml</title>
+ <para>We need to add several RF-specific dependencies to the general
JSF ones:</para>
+ <example>
+ <title>pom.xml</title>
+ <programlisting>
+068. <dependencies>
+069. <!--
+070. The versions, scopes and types of these dependencies are managed in
gatein-*-bom.
+071. You need to name only groupId and artifactId here.
+072. Name only those artifacts you refer to in your code.
+073. Look at gatein-*-bom POM file for the complete list of available
artifacts.
+074. -->
+075. <!-- General JSF dependencies -->
+076. <dependency>
+077.
<groupId>org.jboss.spec.javax.faces</groupId>
+078.
<artifactId>jboss-jsf-api_2.1_spec</artifactId>
+079. </dependency>
+080. <dependency>
+081. <groupId>org.jboss.portletbridge</groupId>
+082. <artifactId>portletbridge-api</artifactId>
+083. </dependency>
+084.
+085. <!-- RF-sprecific dependencies -->
+086. <dependency>
+087. <groupId>org.jboss.portletbridge</groupId>
+088.
<artifactId>portletbridge-extension-richfaces</artifactId>
+089. </dependency>
+090. <dependency>
+091. <groupId>org.richfaces.ui</groupId>
+092.
<artifactId>richfaces-components-api</artifactId>
+093. </dependency>
+094. <dependency>
+095. <groupId>org.richfaces.ui</groupId>
+096.
<artifactId>richfaces-components-ui</artifactId>
+097. </dependency>
+098. <dependency>
+099. <groupId>org.richfaces.core</groupId>
+100.
<artifactId>richfaces-core-impl</artifactId>
+101. </dependency>
+102. </dependencies>
+</programlisting>
+ </example>
+ </section>
+ <section
id="sid-55477018_JSFPortletDevelopmentwithRichFaces-JSFTemplateFiles">
+
+ <title>JSF Template Files</title>
+ <para>
+ We use
+ <code><rich:*></code>
+ components in the templates:
+ </para>
+ <example>
+ <title>Form with rich: components in main.xhtml</title>
+ <programlisting>
+ </p>
+ <h:form id="jsf2HelloWorldPortlet">
+ <h:panelGrid columns="2">
+ <h:outputLabel value="#{msgs.Greeting}"
for="greeting"/>
+ <rich:select id="greeting"
value="#{helloBean.greeting}">
+ <f:selectItems value="#{helloBean.greetings}"
/>
+ <f:ajax render="output"
event="selectitem"/>
+ </rich:select>
+
+ <h:outputLabel value="#{msgs.Name}"
for="nameInput"/>
+ <h:inputText id="nameInput"
value="#{helloBean.name}">
+ <f:validateLength minimum="1"
maximum="50" />
+ <f:ajax render="output"
event="keyup"/>
+ </h:inputText>
+ </h:panelGrid>
+ <p>
+ <h:panelGroup id="output">
+ <strong><h:outputText
value="#{helloBean.greeting} #{helloBean.name}!" rendered="#{not empty
helloBean.name}"/></strong>
+ </h:panelGroup>
+ </p>
+ <p>
+ <h:commandButton id="reset"
value="#{msgs.Reset}" actionListener="#{helloBean.reset}">
+ <f:ajax render="@form" />
+ </h:commandButton> - #{msgs.ResetComment}
+ </p>
+ <p>
+ <h:commandButton id="reload"
value="#{msgs.Reload}" /> - #{msgs.ReloadComment}
+ </p>
+</programlisting>
+ </example>
+ <para>The complete source code of the above template can be found in
src/main/webapp/pages/main.xhtml of JSF2+RF4 Hello World Portlet quickstart.</para>
+ </section>
+ <section
id="sid-55477018_JSFPortletDevelopmentwithRichFaces-JavaBeans">
+
+ <title>Java Beans</title>
+ <para>
+ The HelloBean presented in the
+ <xref linkend="sid-55477016"/>
+ chapter was extended firstly to provide a list of greeting phrases
selectable in the drop-down box on the main.xhtml page and secondly to be able to store
the greeting phrase selected in the drop-down box.
+ </para>
+ <example>
+ <title>HelloBean.java</title>
+ <programlisting>
+ /**
+ * Static list of greetings. Contains {@code "Hello"} and {@code
"Hi"}.
+ */
+ private static final List<SelectItem> GREETINGS;
+
+ static {
+ List<SelectItem> l = new ArrayList<SelectItem>(2);
+ l.add(new SelectItem("Hello"));
+ l.add(new SelectItem("Hi"));
+ GREETINGS = Collections.unmodifiableList(l);
+ }
+
+ /**
+ * Stores the greeting phrase which will be used to greet the application user.
+ */
+ private String greeting;
+</programlisting>
+ </example>
+ <example>
+ <title>HelloBean.java</title>
+ <programlisting>
+ /**
+ * Returns {@link #greeting}.
+ *
+ * @return {@link #greeting}
+ */
+ public String getGreeting() {
+ return greeting;
+ }
+
+ /**
+ * Set {@link #greeting}.
+ *
+ * @param greeting
+ */
+ public void setGreeting(String greeting) {
+ this.greeting = greeting;
+ }
+
+ /**
+ * Returns {@link #GREETINGS}.
+ *
+ * @return {@link #GREETINGS}
+ */
+ public List<SelectItem> getGreetings() {
+ return GREETINGS;
+ }
+
+
+ /**
+ * Resets {@link #name} to the default value {@code "World"} and {@link
#greeting} with the default value {@code "Hello"}.
+ *
+ * @param ae ignored
+ */
+ public void reset(ActionEvent ae) {
+ this.name = "World";
+ this.greeting = "Hello";
+ }
+
+ }
+</programlisting>
+ </example>
+ </section>
+ <section
id="sid-55477018_JSFPortletDevelopmentwithRichFaces-portlet.xml">
+
+ <title>portlet.xml</title>
+ <para>
+ There is no substantial change in portlet.xml against the
+ <xref linkend="sid-55477016"/>
+ chapter. Only
+ <code><description></code>
+ ,
+ <code><portlet-name></code>
+ ,
+ <code><display-name></code>
+ and
+ <code><title></code>
+ have been changed.
+ </para>
+ <example>
+ <title>portlet.xml</title>
+ <programlisting>
+<portlet-app
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
version="2.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2...
+
http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
+ <portlet>
+ <description>A simple portlet usinf JSF2 and
RF4.</description>
+
<portlet-name>jsf2Rf4HelloWorldPortlet</portlet-name>
+ <display-name>JSF2+RF4 Hello World
Portlet</display-name>
+
<portlet-class>javax.portlet.faces.GenericFacesPortlet</portlet-class>
+ <init-param>
+
<name>javax.portlet.faces.defaultViewId.view</name>
+ <value>/pages/main.xhtml</value>
+ </init-param>
+ <init-param>
+
<name>javax.portlet.faces.defaultViewId.edit</name>
+ <value>/pages/edit.xhtml</value>
+ </init-param>
+ <init-param>
+
<name>javax.portlet.faces.defaultViewId.help</name>
+ <value>/pages/help.xhtml</value>
+ </init-param>
+ <init-param>
+
<name>javax.portlet.faces.preserveActionParams</name>
+ <value>true</value>
+ </init-param>
+ <expiration-cache>0</expiration-cache>
+ <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>JSF2+RF4 Hello World Portlet</title>
+ </portlet-info>
+ <container-runtime-option>
+ <name>org.gatein.pc.remotable</name>
+ <value>true</value>
+ </container-runtime-option>
+ </portlet>
+</portlet-app>
+</programlisting>
+ </example>
+ </section>
+ <section
id="sid-55477018_JSFPortletDevelopmentwithRichFaces-web.xml">
+
+ <title>web.xml</title>
+ <para>
+ We set a few more
+ <code>init-params</code>
+ in web.xml for RichFaces components to work:
+ </para>
+ <example>
+ <title>web.xml</title>
+ <programlisting>
+<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
+
<display-name>jsf2-rf4-hello-world-portlet</display-name>
+ <context-param>
+ <description>See
https://docs.jboss.org/author/display/PBR/Installing+Portlet+Bridge#Insta...
+
<param-name>org.gatein.portletbridge.WAR_BUNDLES_PORTLETBRIDGE</param-name>
+ <param-value>true</param-value>
+ </context-param>
+ <context-param>
+ <description>See
https://docs.jboss.org/author/display/PBR/Render+Policy</descripti...
+
<param-name>javax.portlet.faces.RENDER_POLICY</param-name>
+ <param-value>ALWAYS_DELEGATE</param-value>
+ </context-param>
+
+ <!-- The following params are documented here:
http://myfaces.apache.org/core21/myfaces-impl/webconfig.html -->
+ <context-param>
+
<param-name>javax.faces.FACELETS_VIEW_MAPPINGS</param-name>
+ <param-value>*.xhtml</param-value>
+ </context-param>
+ <context-param>
+ <param-name>facelets.DEVELOPMENT</param-name>
+ <param-value>false</param-value>
+ </context-param>
+ <context-param>
+ <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
+ <param-value>.xhtml</param-value>
+ </context-param>
+ <context-param>
+
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
+ <param-value>server</param-value>
+ </context-param>
+ <context-param>
+ <param-name>javax.faces.PROJECT_STAGE</param-name>
+ <!-- Change to Production to compress js files, etc. -->
+ <param-value>Development</param-value>
+ </context-param>
+
+ <context-param>
+
<description>http://docs.jboss.org/richfaces/latest_4_X/Developer_Guide/en-US/html/chap-Developer_Guide-Skinning_and_theming.html</description>
+ <param-name>org.richfaces.skin</param-name>
+ <param-value>#{skinBean.skin}</param-value>
+ </context-param>
+ <context-param>
+ <description>See
http://docs.jboss.org/richfaces/latest_4_X/Developer_Guide/en-US/html/cha...
+
<param-name>org.richfaces.resourceOptimization.enabled</param-name>
+ <param-value>true</param-value>
+ </context-param>
+
+ <servlet>
+ <servlet-name>Faces Servlet</servlet-name>
+
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>*.faces</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>*.jsf</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>/faces/*</url-pattern>
+ </servlet-mapping>
+
+ <mime-mapping>
+ <extension>xcss</extension>
+ <mime-type>text/css</mime-type>
+ </mime-mapping>
+
+</web-app>
+</programlisting>
+ </example>
+ </section>
+ <section
id="sid-55477018_JSFPortletDevelopmentwithRichFaces-CustomCSS">
+
+ <title>Custom CSS</title>
+ <para>
+ Fully analogous with
+ <link linkend="sid-55477016">plain JSF
portlets</link>
+ .
+ </para>
+ </section>
+ <section
id="sid-55477018_JSFPortletDevelopmentwithRichFaces-Internationalization">
+
+ <title>Internationalization</title>
+ <para>
+ Fully analogous with
+ <link linkend="sid-55477016">plain JSF
portlets</link>
+ .
+ </para>
+ </section>
+ </section>
+ <section
id="sid-55477018_JSFPortletDevelopmentwithRichFaces-FurtherSteps">
+
+ <title>Further Steps</title>
+ <para>
+ After having done all the above, it is time to
+ <link linkend="sid-55379158">build and deploy the
portlet</link>
+ ,
+ <ulink
url="https://docs.jboss.org/author/pages/viewpage.action?pageId=5426...
it</ulink>
+ and
+ <ulink
url="https://docs.jboss.org/author/pages/viewpage.action?pageId=5426...
it to a page</ulink>
+ so that you can test its functionality.
+ </para>
+ </section>
+ <section
id="sid-55477018_JSFPortletDevelopmentwithRichFaces-Seealso">
+
+ <title>See also</title>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink
url="https://docs.jboss.org/author/pages/viewpage.action?pageId=5426...
Primer</ulink>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ </section>
+ <section id="sid-55379158">
+
+ <title>Building and Deploying Portlets</title>
+ <orderedlist>
+ <listitem>
+ <para>Make sure you have your GateIn Portal instance is
running.</para>
+ </listitem>
+ <listitem>
+ <para>Open a command line and navigate to the root directory of your
portlet project.</para>
+ </listitem>
+ <listitem>
+ <para>Type this command to build and deploy the archive:</para>
+ <informalexample>
+ <programlisting>mvn clean package
jboss-as:deploy</programlisting>
+ </informalexample>
+ <para>
+ To deploy to other than default
+ <code>localhost:9999</code>
+ JBoss instance, copy the following configuration
+
+ just after
+
<code><version>${jboss.as.plugin.version}</version></code>
+ in the
+ <code>pom.xml</code>
+ file and adjust it to suit your needs.
+
+ Note that
+ <code><username></code>
+ and
+ <code><password></code>
+ elements can be omitted sometimes, depending on your JBoss security
settings.
+
+ </para>
+ <informalexample>
+ <programlisting><configuration>
+ <hostname>127.0.0.1</hostname>
+ <port>9999</port>
+ <username>admin</username>
+ <password>secret</password>
+</configuration></programlisting>
+ </informalexample>
+ <para>
+ This will deploy
+ <code>target/simplest-hello-world-portlet.war</code>
+ to the running instance of the portal.
+ </para>
+ </listitem>
+ </orderedlist>
+ </section>
+ </section>
</chapter>