The .jars included in this distribution provide a simple MVC framework for creating JSR168 portlets. The goal of this framework is to simplify Java-portlet development by providing some of the most popular features that are central to the leading MVC frameworks. It's also a goal that this framework be simple to use; not requiring days, weeks, or months of practice in order to master its usage. As such, this framework does not try to be a one-stop shop for all the most popular patterns, features, etc. that are out there. You will also be able to package your portlets into small units of deployment that you can easily distribute to different Portlet/Portal environments using this framework.
This framework was developed using the JBoss Portal 2.0 platform. Nothing in the actual framework requires JBoss. In other words, you are free to deploy your portlets developed with this framework into any JSR168-compliant portal. If you encounter any problems using this framework in other JSR168 portals, please send me a note describing the problem in detail and include any stack traces that are available with the problem. However, because the framework was developed on JBoss, I have included some starter template files (xml, etc.) that make it quick and easy to develop portlets using this framework in JBoss Portal 2.0.
FeaturesThe above steps are the minimum it takes to create a new portlet based on the framework. In a practical usage, you will provide a variety of portlet actions that are dispatched and processed in your doProcessAction() method. You can add additional JSP pages to your portlet and make your portlet 'aware' of these pages by adding additional portlet.jsp.${ACTION_NAME} <init-param>'s to your portlet's portlet.xml; one ${ACTION_NAME} per unique action-JSP page combination. Note that many times your portlet's edit page will often be the page presented most of a portlet's actions - a typical exception to this is the 'save' action in which your portlet will save changes and then render in view mode.
You may optionally implement custom portlet-initialization behavior in your portlet by overriding this method. doInit() is invoked at the end of BaseMVCPortlet's init() method processing; this occurs on deployment of a portlet and startup of a portal server.
You must provide an implementation of this method. Your implementation will trap for the various actions associated with your portlet and perform the necessary processing. You obtain the current action by inspecting the 'action' property of PortletForm (example: MyPortletForm.getAction()). You should pass in the action as a request parameter from your portlet JSP page(s) in order for the 'action' property to have a meaningful value.
Typically you will need to only override the doViewRender() method. Your doViewRender() implementation should inspect the PortletForm parameter's action property to determine how/what to render. The default implementation of doViewRender() in BaseMVCPortlet simply returns the view.jsp you configured for your portlet. However, depending on the action just processed, the content type of the client, etc., you may need to implement logic for determining exactly what JSP component to use for rendering. Your logic should create a PortletPage (see below) based on the correct JSP component and ensure that its content type is set correctly (by default, PortletPage.contentType="text/html").
All of your do[View,Edit,Help]Render() implementations return an instance of PortletPage. This class simply encapsulates a combination of a content type and the path to a JSP page that will produce the content (of said content type). By default, PortletPage instances have contentType set to "text/html". so most of the time you will provide (return) a PortletPage like this:
return new PortletPage(getViewPage()); // return the view JSP pageor
return new PortletPage(getPage(MyPortletForm.getAction())); // return the JSP page configured for the current action.or
// assume our portlet's configuration included the following: <init-param> <description>Use the edit-JSP page for the portlet 'load' action.</description> <name>portlet.jsp.load.names.wmlc</name> <value>/WEB-INF/jsp/portlets/MyPortlet/view-wmlc.jsp</value> </init-param> // also, assume that our doProcessAction(...) impl has just handled the "load.names.wmlc" action // then, in our doViewRender(...) implementation, we end processing with code like the // following (NOTE: wmlc = Compiled WML) PortletPage portletPage = new PortletPage(getPage(MyPortletForm.getAction())); if (MyPortletForm.getAction().endsWith("wmlc")) { portletPage.setContentType("application/vnd.wap.wmlc"); // set the content type dynamically } return portletPage; // return the JSP page configured for the action.
In all cases you must provide a JSP page for the VIEW, EDIT, and HELP actions of a portlet. You can simplify this somewhat by creating a view.jsp and configuring your portlet to use the view.jsp for all of VIEW, EDIT, HELP actions. An example JSP page (in JSP 2.0 syntax with JSTL 1.1) is show here (suitable for use as a starter template):
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@ taglib prefix="portlet" uri="http://java.sun.com/portlet" %> <%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %> <%@ taglib prefix="jp-portlet" uri="/WEB-INF/lib/jp-mvc-portlet-fwk-1.0.jar" %> <%-- Use this page as a starter or template page for all your portlet JSP pages. --%> <%-- The following two tags are used to 'transfer' the portletForm from renderRequest scope to page scope. JSTL and other JSP custom tags know nothing about the various portlet scopes. --%> <portlet:defineObjects/> <%-- JSR168 tag --%> <jp-portlet:portletForm/> <%-- Base MVC Portlet Framework tag --%> <%-- The result of these two tags is that now, there is a PortletForm (or subclass of PortletForm) available in page-scope under the key "portletForm". Thus, properties of the 'form bean' can be accessed via the JSP expression language like so: ${portletForm.someProperty} and ${portletForm.anotherProperty} --%> View Mode<br /> ${portletForm}<br /> <jp-portlet:renderIfIn role="Admin"> <%-- Base MVC Portlet Framework tag --%> role-specific content .... <jp-portlet:renderIfIn>
Notice in the sample JSP page above the introduction of two custom JSP tags from the framework, <jp-portlet:portletForm/> and <jp-portlet:renderIfIn role="Admin">. The first tag is essentially required for practical usage of framework features with your JSP pages; it must be used after using the JSR168 <portlet:defineObjects/> tag. After these two tags are invoked in your JSP page you will have a reference to your PortletForm available in PAGE SCOPE with name portletForm.
The second tag, <jp-portlet:renderIfIn role="...">...<jp-portlet:renderIfIn>, checks to see if the current user that made the request has the specified role; if so, the content enclosed by tag is rendered to client browser; if not, the content enclosed is skipped.
portlet.form | Fully-qualified of class to instantiate as a form bean for the portlet. Must extend com.javaplant.portlet.PortletForm. | required |
Example:<init-param> <description>Form class to instantiate for this portlet (like a Struts ActionForm).</description> <name>portlet.form</name> <value>com.javaplant.portlets.MyPortletForm</value> </init-param> |
portlet.jsp.view | Name of the JSP component to use to render the VIEW mode of the portlet (doView()). | required |
Example:<init-param> <description>JSP (fragment) to use for rendering the portlet in view mode.</description> <name>portlet.jsp.view</name> <value>/WEB-INF/jsp/portlets/MyPortlet/view.jsp</value> </init-param> |
portlet.jsp.edit | Name of the JSP component to use to render the EDIT mode of the portlet (doEdit()). | required |
Example:<init-param> <description>JSP (fragment) to use for rendering the portlet in edit mode.</description> <name>portlet.jsp.edit</name> <value>/WEB-INF/jsp/portlets/MyPortlet/edit.jsp</value> </init-param> |
portlet.jsp.help | Name of the JSP component to use to render the HELP mode of the portlet (doEdit()). | required |
Example:<init-param> <description>JSP (fragment) to use for rendering the portlet in help mode.</description> <name>portlet.jsp.help</name> <value>/WEB-INF/jsp/portlets/MyPortlet/help.jsp</value> </init-param> |
portlet.jsp.${ACTION_NAME} | Name of the JSP component to use to render the ${ACTION_NAME} action of the portlet. NOTE: By convention, the value of ${ACTION_NAME} should match the name of an action submitted by one or more of your portlet views. This action should correspond to the 'action' property of PortletForm. |
optional |
Example:<init-param> <description>JSP (fragment) to use for rendering the portlet when the load action is invoked.</description> <name>portlet.jsp.load</name> <value>/WEB-INF/jsp/portlets/MyPortlet/load.jsp</value> </init-param> <init-param> <description>JSP (fragment) to use for rendering the portlet when the save action is invoked.</description> <name>portlet.jsp.save</name> <value>/WEB-INF/jsp/portlets/MyPortlet/save.jsp</value> </init-param>Another Example: <init-param> <description>Use the edit-JSP page for the portlet 'load' action.</description> <name>portlet.jsp.load</name> <value>/WEB-INF/jsp/portlets/MyPortlet/edit.jsp</value> </init-param> <init-param> <description>Use the view-JSP page for the portlet 'save' action (when successful...).</description> <name>portlet.jsp.save</name> <value>/WEB-INF/jsp/portlets/MyPortlet/view.jsp</value> </init-param> |
portlet.showConfiguration | If set to true a report is generated on deployment or startup showing this portlet's configuration. | optional |
Example:<init-param> <description>Generate a report of this portlet's configuration.</description> <name>portlet.showConfiguration</name> <value>true</value> </init-param> |