Sun Identity Manager Service Provider 8.1 Deployment

Using Apache Struts to Create User Pages

The Service Provider User Interface pages are constructed using the Tiles component of the Apache Struts Framework.

One approach to separating layout from content is the use of dynamic JSP includes. The Tiles framework uses a more advanced form of the JSP include action. In a Tiles application, the layout template usually defines the position of a header, menu, body content, and footer. Other pages are then included to fill each of these positions. Tiles makes using template layouts easier through the use of a simple tag library.

Technically, a tile is a rectangular region in a JSP. A tile may be assembled from other tiles, creating a tree-like hierarchy. A tile can accept variable information at runtime in the form of attributes, making it parameterizable. Tile attributes are defined when inserting the tile and are visible within the tile only. They are not visible in subtiles or to a page enclosing the tile.

Layout Template

In Service Provider, the primary layout template is defined in $WSHOME/spe/user/common/layouts/page.jsp .

<%@ taglib uri="/tags/struts-tiles" prefix="tiles" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<html:html>
   <head>
      <title><bean:write name="title" filter="off"/></title>
      <html:base/>
   </head>
   <body>
      <tiles:insert name="masthead"/>
      <tiles:insert name="navbar"/>
      <tiles:insert name="subnavbar"/>
      <tiles:insert name="content"/>
      </body>
</html:html>

This simple layout template indicates that the body of the page is built from four tiles: masthead, navbar, subnavbar, and content. Each tile corresponds to a JSP file in the $WSHOME/spe/user/common/tiles directory.

Tiles Definitions

A JSP template system uses one template for the layout and another for the fill-in components. Tiles calls these layout files “definitions”. To avoid creating an extra file just to specify the layout, Tiles allow the layout definitions to be stored as a JavaBean. For Service Provider, these definitions are declared in the following XML configuration files, located in the $WSHOME/WEB-INF/spe/config directory:

These definitions files are specified in the deployment descriptor file, $WSHOME/WEB-INF/web.xml:

<init-param>
   <param-name>definitions-config</param-name>
   <param-value>/WEB-INF/spe/config/tiles-tab-defs.xml,
                /WEB-INF/spe/config/tiles-nav-defs.xml,
                /WEB-INF/spe/config/tiles-page-defs.xml</param-value>
</init-param>

The following example shows the base definition for a Service Provider page, as defined in tiles-page-defs.xml:

<definition name=".page.Base" path="spe/user/common/layouts/page.jsp"
      controllerClass="com.sun.idm.idmx.web.LocalizePageTitles">
   <put name="page_title_key" value="${page_title_key}" />
   <put name="masthead" value="spe/user/common/tiles/masthead.jsp" />
   <put name="navbar"   value="${navbar}" />
   <put name="left_nav" value="spe/user/common/tiles/left_nav.jsp" />
   <put name="content"  value="${content}" />
   <put name="footer"   value="spe/user/common/tiles/footer.jsp" />
</definition>

The attributes passed into this definition may consist of message resource bundle keys, like page_title_key, or references (directly or indirectly) to other tiles inserted on the page.

A tile definition may include a controller class. This class may access tile attributes from the context before the tile is rendered. In Service Provider, the controller class looks up the appropriate page title or subtitle from the message resource bundle based on the key passed as a tile attribute. The Struts framework uses a locale-specific resource bundle, if it exists.

Adding a New Page

The following example extends the Base definition and uses a custom JSP named my_page.jsp to render the content tile. It renders content appropriate for the for a JSP named my_page.jsp:

<definition name=".page.MyPage" extends=".page.Base">
   <put name="page_title_key" value="message.my_page_title" />
   <put name="navbar" value=".nav_bar.MyPage" />
   <put name="content" value="/pages/my_page.jsp" />
</definition>

The rendered page consists of content from the masthead, navbar and content tiles. The content tile contains the output from my_page.jsp. (Even though the Base page tile definition contains references to the left-hand and “footer” tiles, these do not appear on the rendered page because they are not included in the page.jsp layout template.) The localized title string will be rendered in the browser’s title bar.

The definition name (.page.MyPage) can be referenced in a Struts ActionForward in the same manner as a regular file URI. Slashes can be used in a definition name, but by best practice convention, a period is used as a delimiter to distinguish the tiles definitions from file URIs, such as "/spe/user/Login.do".

Updating the Navigation Bar

Once you have defined a new page to be added to the Service Provider User Interface, you must add a button to the navigation bar so that users can access the new page.

The navigation and subnavigation bars are implemented with tab-style buttons created from tiles. The JSP for a tab button outputs an HTML fragment consisting of a single table cell. The cell contains the localized text and optional hyperlink for the tab.

The following example lists the base definition for an unselected navigation button:

<definition name=".nav_tab.Base"       path="spe/user/common/tiles/nav_tab.jsp"
      controllerClass="com.sun.idm.idmx.web.LocalizeButtonLabel">
   <put name="button_link" value="${button_link}" />
   <put name="button_label_key" value="${button_label_key}" />
   <put name="link_class" value="Tab1Lnk" />
</definition>

The first two attributes are the message resource bundle keys associated with the text displayed within the button and the URI of the hyperlink for that text. The remaining attributes are the style sheet classes that give the button its appearance.

The base definition for a selected navigation button requires different style sheet classes. These classes must specify a different background color to indicate the tab has been selected and deactivate the hyperlink in the button text.

The following example lists the base definition for a selected navigation button:

<definition name=".nav_tab_selected.Base"       path="spe/user/common/tiles/nav_tab_selected.jsp"
      controllerClass="com.sun.idm.idmx.web.LocalizeButtonLabel">
   <put name="button_label_key" value="${button_label_key}" />
   <put name="text_class" value="Tab1SelTxtNew" />
   <put name="button_class" value="Tab1TblSelTd" />
</definition>

To create the definitions for the new button in each state, extending the base definitions as follows:

<definition name=".nav_tab_selected.MyPage"
       extends=".nav_tab_selected.Base">
   <put name="button_text" value="My Page" />
</definition>
<definition name=".nav_tab.MyPage" extends=".nav_tab.Base">
   <put name="button_link" value="/spe/user/MyPage.do" />
   <put name="button_text" value="My Page" />
</definition>

The individual button tiles can be combined together into a new tile for the navigation bar itself. To do this, pass a list of button tiles to the following base navigation bar definition:

<definition name=".nav_bar.Base"
       path="spe/user/common/tiles/nav_bar.jsp">
   <put name="div_class" value="Tab1Div" />
   <put name="context_class" value="Tab1TblNew" />
</definition>

Use the following example to define a list of buttons that will appear in the navigation bar for the new page:

<definition name=".nav_bar.MyPage" extends=".nav_bar.Base">
   <putList name="tab_list" >
      <add value=".nav_tab.Home" />
      <add value=".nav_tab.Profile" />
      <add value=".nav_tab_selected.MyPage" />
   </putList>
</definition>

The JSP that renders the navigation bar (spe/user/common/tiles/nav_bar.jsp ) loops through this list of buttons and includes the appropriate tile, passing attributes specific to that button. (The attributes can include the hyperlink, button text, style class, etc.).

To force the new button to appear in the navigation bar on other pages, you must add the (non-selected) definition to each page-specific navigation bar definition. For example, to add our new button to the navigation bar on the home page:

<definition name=".nav_bar.Home" extends=".nav_bar.Base">
   <putList name="tab_list" >
      <add value=".nav_tab_selected.Home" />
      <add value=".nav_tab.Profile" />
      <add value=".nav_tab.MyPage" />
   </putList>
</definition>

Tag Library

The following custom tags may be used in the user pages:

counter— A counter that is incremented by one every time the tag is called during a request. This tag is only used in the masthead, navigation bar, and the navigation button tiles. You may specify the value attribute to set the initial value of the counter. For example, to reset the counter, counter value=”1”.

generateForm— Displays the content produced by the page processor. This tag may be used in content-based tiles, such as those used in Form.jsp.

Tracing Struts Messages

Messages from Struts can be logged by enabling the Identity Manager trace feature and specifying trace levels for the org.apache.struts package, or any of its subclasses/subpackages. Struts logging does not allow configuring the names of specific methods that should be logged, and this level of configuration will be ignored.