webcenter application pages. tech note content

26
TechNote Oracle WebCenter Displaying Content on WebCenter Pages January 2008 This technical note demonstrates how to display content stored in a content repository on Oracle WebCenter application pages. Tech Note Content 1. Overview 2. Create a WebCenter Application and a Data Control 3. Build Example 1: Photo Browsing Page 4. Build Example 2: Text Display Page 5. Summary 1. Overview There are several content repository options in a WebCenter instance, for example, Oracle Universal Content Management, Oracle Content Database, and Oracle Portal. Application developers can also access content stored in the server’s file system, although this option is recommended for testing purposes only. Because each content management solution has its own proprietary API, WebCenter supplies several JCR 1.0 adapters to access different content repositories. Note: The Java Community Process JSR 170 specifies a standard API to access a content repository. The standard defines several levels for the API. Oracle WebCenter 10.1.3.2 includes Level 1-compliant adapters only. Level 1 supports read-only repository access. Therefore, the examples presented in this paper display content but do not enable you to upload or modify it. For uploading or modifying content, you must use a repository-specific API. Although JCR 1.0 is a relatively simple API, ADF application developers can also use the data control paradigm to access a content repository. After creating a JCR data control (using a JDeveloper wizard) to access a specific content repository, you can simply add methods to a JSF page using drag and drop. The examples discussed in this paper use a JCR data control to access content stored in the file system. If your installation contains any WebCenter-supported content repository, the same examples still apply; the only difference is in creating the data control. The first example demonstrates how to browse and show photos stored in a content repository (see Figure 5). The second example illustrates how to include textual content (simple text or HTML fragments) on a WebCenter page (see Figure 16). The sample files used in this example are contained in the JCRDemoFiles.zip file, which you can download and unzip. In our example, we unzipped the file to the C drive, where it created a subdirectory, C:\JCRDemo\Files. You can also download the completed JDeveloper application (JCRDemoApp.zip ). Note: You can use a different drive and different root directory when unzipping the files. Remember to refer to the actual root directory when creating the JCR data controls. Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 1

Upload: others

Post on 12-Sep-2021

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: WebCenter application pages. Tech Note Content

TechNote Oracle WebCenter

Displaying Content on WebCenter PagesJanuary 2008

This technical note demonstrates how to display content stored in a content repository on Oracle WebCenter application pages.

Tech Note Content 1. Overview2. Create a WebCenter Application and a Data Control3. Build Example 1: Photo Browsing Page4. Build Example 2: Text Display Page5. Summary

1. Overview

There are several content repository options in a WebCenter instance, for example, Oracle Universal Content Management, Oracle Content Database, and Oracle Portal. Application developers can also access content stored in the server’s file system, although this option is recommended for testing purposes only. Because each content management solution has its own proprietary API, WebCenter supplies several JCR 1.0 adapters to access different content repositories.

Note: The Java Community Process JSR 170 specifies a standard API to access a content repository. The standard defines several levels for the API. Oracle WebCenter 10.1.3.2 includes Level 1-compliant adapters only. Level 1 supports read-only repository access. Therefore, the examples presented in this paper display content but do not enable you to upload or modify it. For uploading or modifying content, you must use a repository-specific API.

Although JCR 1.0 is a relatively simple API, ADF application developers can also use the data control paradigm to access a content repository. After creating a JCR data control (using a JDeveloper wizard) to access a specific content repository, you can simply add methods to a JSF page using drag and drop. The examples discussed in this paper use a JCR data control to access content stored in the file system. If your installation contains any WebCenter-supported content repository, the same examples still apply; the only difference is in creating the data control. The first example demonstrates how to browse and show photos stored in a content repository (see Figure 5). The second example illustrates how to include textual content (simple text or HTML fragments) on a WebCenter page (see Figure 16). The sample files used in this example are contained in the JCRDemoFiles.zip file, which you can download and unzip. In our example, we unzipped the file to the C drive, where it created a subdirectory, C:\JCRDemo\Files. You can also download the completed JDeveloper application (JCRDemoApp.zip).

Note: You can use a different drive and different root directory when unzipping the files. Remember to refer to the actual root directory when creating the JCR data controls.

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 1

Page 2: WebCenter application pages. Tech Note Content

2. Create the WebCenter Application and a Data Control

Start JDeveloper 10.1.3.3 and create a new application called JCRDemo. Select the WebCenter template, specify the directory, and provide jcrdemo as the package prefix.

Figure 1. New WebCenter Application

The JCRDemo application will be used for both examples. Next we create two data controls: the Photos data control for the first example and the Texts data control for the second example. It is good practice to separate the data control definition from its usage. For this reason, we will create the data controls in the Model project, not the ViewController project, where the user interface will be created. In the Application Navigator, right-click Model and select New. In the New Gallery, choose All Technologies from the Filter By list because JCR data controls are not displayed within the scope of this project. Expand the Business Tier node, select Content Repository, and then select the Content Repository Data Control item. Click OK.

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 2

Page 3: WebCenter application pages. Tech Note Content

Figure 2. New Content Repository Data Control

In the Create Data Control Wizard, name the data control Photos. Select File System as the Repository Type, and specify C:\JCRDemo\Files\Photos for Base Path. Click Test to verify that the path is correct.

Figure 3. Attribute for the File System-Based Data Control

Click Finish.

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 3

Page 4: WebCenter application pages. Tech Note Content

Now create a data control for the second example. Call it Texts and use C:\JCRDemo\Files\Texts as the Base Path. In the Data Control Palette, you now have two data controls. Expand Photos to reveal the operations defined by this data control.

Figure 4. Operations of the Photos JCR Data Control

The first three operations (search, advancedSearch, and getItems) return a collection of items from the repository. While getItems returns all the items in a repository folder, search and advancedSearch can be used to return items matching search criteria. In our examples, we use getItems, but you can use any of the search operations. The other two operations, getAttributes and getURI, can be used to return various attributes of the items. Later we will use the getURI operation.

3. Build Example 1: Photo Browsing Page

In the first example, we create a simple WebCenter page that displays a scrollable set of thumbnail photos. Clicking a thumbnail opens the full-sized photo in a new browser window. Figure 5 shows how the completed page looks.

Figure 5. Thumbnails

We will use the Photos data control. Thumbnail images are stored in the Thumbs subdirectory, and full-sized images are in the FullSized subdirectory.

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 4

Page 5: WebCenter application pages. Tech Note Content

Create the application page Double-click the ViewController project to open the Project Properties window. Select the J2EE Application node and shorten the J2EE Web Context Root to JCRDemo. This simplifies the URL to access the application page. Next, we add a new JSF page to this project. Right-click ViewController, and from the New Gallery select the Web Tier > JSF category. Choose the JSF JSP item. In the Create JSF JSP Wizard, enter browse.jspx for the File Name and make sure the JSP Document option is selected.

Figure 6. Create a New JSF Page

In the next wizard step, select the “Do Not Automatically Expose UI Components in a Managed Bean” option. In the Tag Libraries step, make sure that the following libraries are selected for the page:

• ADF Faces Components

• ADF Faces HTML

• JSF Core

• JSF HTML

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 5

Page 6: WebCenter application pages. Tech Note Content

Figure 7. Select Required Tag Libraries

Click Finish.

Create operation bindings Next we create the bindings to scroll through the result of the getItems operation of the JCR data control. The simplest way to create all the bindings is to drag and drop the operation result onto the JSF page; JDeveloper will create all the necessary bindings as well as an ADF Read-only Table user interface element. For this example, we plan to use the bindings only, not the user interface. The new page, browse.jspx, is already open in the visual editor in Design mode. In the Data Control Palette, expand the Photos > getItems node. Drag the Return node onto the empty page. Choose Tables > ADF Read-only Table from the Create context menu.

Figure 8. Choose ADF Read-only Table

Because the getItems operation requires parameters, the Action Binding Editor opens. Define the path as /FullSized and type as nt:file. These parameter values mean that only files (not subfolders) will be displayed from the folder with the /FullSized relative path.

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 6

Page 7: WebCenter application pages. Tech Note Content

Figure 9. Configure getItems Parameters

After you click OK, a second wizard prompts you to configure the columns of the ADF table that is being created. You can accept the defaults by clicking OK because you do not need this table.

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 7

Page 8: WebCenter application pages. Tech Note Content

Figure 10. Configure Table Columns and Behavior

Select the Source view of the browse.jspx file and delete the table from the source (that is, delete everything between and including the <af:table ...> and </af:table> tags). Make sure that you delete the table using the Source view and not the Structure pane. If you delete from the Structure pane, JDeveloper will also delete the table binding. Right-click the JSPX file and choose Go to Page Definition to open the browsePageDef.xml file, which contains all the definitions used by the page. You can see that three objects are generated. First a methodAction binding calls the getItems method of the Photos data control. Here we specify the method’s parameters. Then there is a methodIterator, which iterates through the result of the getItems method. Finally, there is a table binding to specify the attributes (columns) of the iterator. This is how the page definition looks:

<?xml version="1.0" encoding="UTF-8" ?> <pageDefinition xmlns="http://xmlns.oracle.com/adfm/uimodel" version="10.1.3.41.57" id="browsePageDef" Package="jcrdemo.view.pageDefs"> <parameters/> <executables> <variableIterator id="variables"/> <methodIterator id="getItemsIter" Binds="getItems.result" DataControl="Photos" RangeSize="10" BeanClass="Photos.getItems_return"/> </executables> <bindings> <methodAction id="getItems" InstanceName="Photos" DataControl="Photos" MethodName="getItems" RequiresUpdateModel="true" Action="999" IsViewObjectMethod="false" ReturnName="Photos.methodResults.Photos_getItems_result"> <NamedData NDName="path" NDValue="/FullSized" NDType="java.lang.String"/>

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 8

Page 9: WebCenter application pages. Tech Note Content

<NamedData NDName="type" NDValue="nt:file" NDType="java.lang.String"/> </methodAction> <table id="getItems1" IterBinding="getItemsIter"> <AttrNames> <Item Value="name"/> <Item Value="path"/> <Item Value="URI"/> <Item Value="primaryType"/> <Item Value="lastModified"/> </AttrNames> </table> </bindings> </pageDefinition>

Let’s provide self-descriptive names for the bindings that JDeveloper generated. Select the getItems1 Table in the Structure pane. In the Property Inspector pane, change the Id property to Photos. Similarly, change the Id property of the getItemsIter iterator to PhotosIterator. To display four pictures at once, change the RangeSize property of the MethodIterator to 4. The resulting page definition is shown below. All the changes are indicated in bold.

<?xml version="1.0" encoding="UTF-8" ?> <pageDefinition xmlns="http://xmlns.oracle.com/adfm/uimodel" version="10.1.3.41.57" id="browsePageDef" Package="jcrdemo.view.pageDefs"> <parameters/> <executables> <variableIterator id="variables"/> <methodIterator id="PhotosIterator" Binds="getItems.result" DataControl="Photos" RangeSize="4" BeanClass="Photos.getItems_return"/> </executables> <bindings> <methodAction id="getItems" InstanceName="Photos" DataControl="Photos" MethodName="getItems" RequiresUpdateModel="true" Action="999" IsViewObjectMethod="false" ReturnName="Photos.methodResults.Photos_getItems_result"> <NamedData NDName="path" NDValue="/FullSized" NDType="java.lang.String"/> <NamedData NDName="type" NDValue="nt:file" NDType="java.lang.String"/> </methodAction> <table id="Photos" IterBinding="PhotosIterator"> <AttrNames> <Item Value="name"/> <Item Value="path"/> <Item Value="URI"/> <Item Value="primaryType"/> <Item Value="lastModified"/> </AttrNames> </table> </bindings> </pageDefinition>

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 9

Page 10: WebCenter application pages. Tech Note Content

Create the thumbnail browser Return to the Design view of the empty browse.jspx page. We will use a PanelHorizontal component to hold the navigation buttons and the individual images. Each of the images will be displayed in a PanelBox container. From the ADF Faces Core Component Palette, drag a PanelHorizontal object to the page. Set the following properties:

halign = center

valign = top We will use a ForEach loop to scroll in the iterator and display the individual thumbnail images. Drag a ForEach component into the PanelHorizontal. In the Insert ForEach popup, specify the following:

Items = #{bindings.Photos.rangeSet} Var = actPhoto

Figure 11. ForEach Attributes

Drag a PanelBox onto the af:foreach tag in the Structure pane, which gives you more control than the visual editor provides over the placement of a component. In each iteration of the loop, we will use an ObjectImage component to display an image. We also want to display the full-sized image in a separate window when the user clicks a thumbnail image, so we will use a GoLink component surrounded by the ObjectImage. First drag a GoLink onto the PanelBox. Then add an ObjectImage onto the GoLink. Do not set the properties of these components yet, since you some explanation first.

JCR adapter’s GetHandler servlet Earlier, when we created the first method binding to the JCR adapter, the wizard modified the project’s web.xml file. It specified a new servlet called GetHandler, which is provided by the JCR adapter. If you open the web.xml file, you find the following definitions:

<servlet> <servlet-name>GetHandler</servlet-name> <servlet-class>oracle.vcr.http.GetHandlerServlet</servlet-class> </servlet> . . . <servlet-mapping> <servlet-name>GetHandler</servlet-name> <url-pattern>/get/*</url-pattern>

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 10

Page 11: WebCenter application pages. Tech Note Content

</servlet-mapping>

The servlet can be used to access an item stored in the content repository. Each item has a corresponding relative URI, which will be resolved by the servlet. When the servlet receives a request, it locates the requested document using the URI, and then sends back the document in an HTTP reply. The way the servlet locates and fetches the document depends on the actual content repository being used, but developers do not need to be concerned about the details. As long as you have a URI, you can fetch the document’s content. The URI is an attribute of the document; most JCR data control methods provide this attribute. If you look at the definition of the Photos table in the page definition file, you will notice one of the columns of the table returned by the getItems method is a URI. Bind the source property of the ObjectImage to #{actPhoto.URI}. Similarly, change the GoLink’s destination attribute to the same value (#{actPhoto.URI}) and delete the text property.

<af:goLink destination="#{actPhoto.URI}"> <af:objectImage source="#{actPhoto.URI}"/> </af:goLink>

Note: You can change a component’s attribute by selecting it in the Structure pane, then selecting the appropriate property in the Property Inspector pane and entering the new value. However, there is a known issue with specifying Expression Language (EL) in the Destination property of a GoLink component: the Property Inspector does not accept an expression such as #{actPhoto.URI}. So, to make the modification manually, go to the Source mode of the visual editor, locate the <af:goLink...> tag, and insert the attribute destination="#{actPhoto.URI}".

Page formatting We are almost ready to test the first version of the photo-browsing page. Most of the UI components are on the page, but we have to adjust some of their properties for better formatting. The iterator runs through the full-sized images, which must be reduced to thumbnail size. If we set the dimensions of an image on a page, the browser automatically resizes the image to the specified dimensions. Set the ObjectImage component’s height property to 100 and do not set the width property; setting either the height or width property but not both means that the image’s original proportions are retained. Set the width property of the surrounding PanelBox to 160 to ensure uniformly sized frames for all of the photos. Set inlineStyle > text-align to center to center the photo inside the PanelBox. To see the full-sized photos in a new browser window or tab, set the targetFrame property of the GoLink component to _blank. Here is the source of the resulting page:

<h:form> <af:panelHorizontal halign="center" valign="top"> <af:forEach var="actPhoto" items="#{bindings.Photos.rangeSet}"> <af:panelBox width="160" inlineStyle="text-align:center;"> <af:goLink destination="#{actPhoto.URI}" targetFrame="_blank"> <af:objectImage source="#{actPhoto.URI}" height="100"/> </af:goLink> </af:panelBox> </af:forEach> </af:panelHorizontal> </h:form>

Run the page. It should look Figure 12.

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 11

Page 12: WebCenter application pages. Tech Note Content

Figure 12. Thumbnails Without Browsing Feature

Click any photo to view the full-sized photo in a new window or tab.

Add scrolling The next step is to add Previous and Next buttons to allow the user to scroll through all the photos. Each data control method that returns a collection of objects also provides operations on the resulting collection. The figure below shows how a typical ViewObject on a database table looks when expanded in the Data Control Palette.

Figure 13. Typical Method Operations

An iterator running on the result collection fetches only the number of rows specified by the RangeSize property. The PreviousSet and NextSet operations move this range back and forth in the result set. To provide scrolling, you can drag and drop these operations as CommandButton objects on an ADF page. This results in an action binding in the page definition and a button on the page, which is tied to the action. In our example, we use the PreviousSet and NextSet operations in the JCR data control’s getItems method. Although in JDeveloper 10.1.3.3, the Data Control Palette doesn’t display any operations for the method, they do exist. Figure 14 shows how the expanded getItems method looks.

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 12

Page 13: WebCenter application pages. Tech Note Content

Figure 14. getItems Method with No Operations Displayed

Because the operations we need are not displayed, we will create the method bindings and the buttons manually. Return to the page definition file in the visual editor. Insert the following XML fragment just after the </table> tag and before the </bindings> tag:

<action id="PreviousSet" IterBinding="PhotosIterator" InstanceName="Photos.getItems.result" DataControl="Photos" RequiresUpdateModel="true" Action="15" /> <action id="NextSet" IterBinding="PhotosIterator" InstanceName="Photos.getItems.result" DataControl="Photos" RequiresUpdateModel="true" Action="14" />

Notice that the standard operations provided by a data control have action codes; here we use 14 and 15. Both actions work on the result of the getItems method in the Photos data control (InstanceName="Photos.getItems.result"), and they are bound to the iterator called PhotosIterator (IterBinding="PhotosIterator"). Select the browse.jspx page. Drag and drop a CommandButton before the <af:forEach …> component. In the Source view, set the following properties:

Text = PreviousSet ActionListener = #{bindings.PreviousSet.execute} Disabled = #{!bindings.PreviousSet.enabled}

Drop a similar button after the forEach element, and tie it to the NextSet action. This is how the resulting page source looks:

<h:form> <af:panelHorizontal halign="center" valign="top"> <af:commandButton text="Previous" actionListener="#{bindings.PreviousSet.execute}" disabled="#{!bindings.PreviousSet.enabled}"/> <af:forEach var="actPhoto" items="#{bindings.Photos.rangeSet}"> <af:panelBox width="160" inlineStyle="text-align:center;"> <af:goLink destination="#{actPhoto.URI}" targetFrame="_blank"> <af:objectImage source="#{actPhoto.URI}" height="100"/>

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 13

Page 14: WebCenter application pages. Tech Note Content

</af:goLink> </af:panelBox> </af:forEach> <af:commandButton text="Next" actionListener="#{bindings.NextSet.execute}" disabled="#{!bindings.NextSet.enabled}"/> </af:panelHorizontal> </h:form>

Run the page, test the application, and scroll through the photos. On the last page, there is an empty PanelBox that looks as if forEach might make another step after the result set is exhausted. To overcome this problem, set the rendered attribute of the PanelBox to #{actPhoto.URI != null}, as in the example below. This turns off the rendering of the PanelBox when there are no photos to render.

<af:panelBox width="160" inlineStyle="text-align:center;" rendered="#{actPhoto.URI != null}">

Show real thumbnail photos Run the application again. Although the application should work as expected, the page may be rendered slowly (depending on the network speed). In our current solution, four full-sized photos are downloaded to the browser, and then the browser creates the thumbnail photos. To improve performance, we can use precreated thumbnails stored in the content repository. A set of thumbnail photos, each with a height of 100 pixels and having the same name as the corresponding full-sized photo, are located in the C:\JCRDemo\Files\Photos\Thumbs folder. Here is an example of the URI that is returned for an item:

/get/conn/Photos/path/FullSized/London_3.jpg

To display the thumbnail image for any photo, we can simply replace FullSized to Thumbs in the URI so that it refers to the thumbnail photo instead of the full-sized one. We will create a simple managed bean to convert the URI. Open faces-config.xml in Overview mode. Create a new managed bean named thumbURI and the class jcrdemo.view.managed.ThumbURI. Set the scope to request.

Figure 15. Create thumbURI Managed Bean

When you open faces-config.xml in Source mode, you will see the following tag:

<managed-bean> <managed-bean-name>thumbURI</managed-bean-name> <managed-bean-class> jcrdemo.view.managed.ThumbURI

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 14

Page 15: WebCenter application pages. Tech Note Content

</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean>

Typically, a managed bean provides properties with getter and setter methods. You can access these properties in an EL expression. If the bean implements the Map interface, then an EL expression can pass a parameter to the bean. Open the ThumbURI.java file and replace the content with the following code:

package jcrdemo.view.managed; import java.net.URI; import java.util.AbstractMap; import java.util.HashSet; import java.util.Set; public class ThumbURI extends AbstractMap { public Set entrySet() { return new HashSet(); } public Object get(Object key) { URI full = (URI) key; URI thumb = null; String fullPath = full.getPath(); String thumbPath = fullPath.replaceFirst("FullSized", "Thumbs"); try { thumb = new URI(full.getScheme(), thumbPath, full.getFragment()); } catch (Exception e) {} return thumb; } }

Look at the get method. It creates a new URI object, where Thumbs replaces FullSized in the path. Now open browse.jspx and locate the ObjectImage component. Change its source property to #{thumbURI[actPhoto.URI]}. This EL expression calls the thumbURI bean’s get method and passes the actual URI of the full-sized image as a parameter. The returned URI is used to fetch and display the thumbnail image, as in the example below:

<af:objectImage source="#{thumbURI[actPhoto.URI]}" height="100"/>

Test the page, and notice that the performance has improved. This is the final version of this first example.

4. Build Example 2: Text Display Page

The next set of examples shows how to include text stored in the content repository on a WebCenter page (see Figure 16 for a sample screenshot). This functionality is similar to Oracle Portal’s text items.

Fetching the text The ObjectImage component has a source attribute, which can take a URI. The browser does the rest. ObjectImage is translated to an HTML <img …> tag, for example:

<img height="100" border="0" src="/jcrtest/get/conn/Photos/path/Thumbs/London_4.jpg"/>

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 15

Page 16: WebCenter application pages. Tech Note Content

The browser uses the URL in the src attribute and makes a HTTP request to fetch the image. The JCR adapter’s GetHandler servlet serves this request and provides the bytes of the image. To include plain text or HTML on a page, you must write code to perform the fetching. Fortunately, the code is quite simple for issuing a simple HTTP request and fetching the result using standard J2SE libraries. The first two variables, contextRoot and uri, will be assigned in the final code.

String contextRoot = . . .; URI uri = . . .; URLConnection conn = new URL(contextRoot + uri.toString()).openConnection(); InputStreamReader isr = new InputStreamReader(conn.getInputStream()); BufferedReader br = new BufferedReader(isr); String result = "", nextLine; while ((nextLine = br.readLine()) != null) { result += nextLine; }

The code fragment above opens a URLConnection using the URI provided, and then fetches the reply as a series of text lines. To display the stored text, we can use an ADF OutputText component; the code fragment will populate its value property. Select the faces-config.xml file and create another managed bean in the request scope. Enter textItem for the name and jcrdemo.view.managed.TextItem for the class.

<managed-bean> <managed-bean-name>textItem</managed-bean-name> <managed-bean-class> jcrdemo.view.managed.TextItem </managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean>

Replace the contents of the new TextItem.java file with the following code:

package jcrdemo.view.managed; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URI; import java.net.URL; import java.net.URLConnection; import java.util.AbstractMap; import java.util.HashSet; import java.util.Set; import javax.faces.application.FacesMessage; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.servlet.ServletRequest; public class TextItem extends AbstractMap {

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 16

Page 17: WebCenter application pages. Tech Note Content

private String contextRoot; public TextItem() { FacesContext facesCtx = FacesContext.getCurrentInstance(); ExternalContext externalCtx = facesCtx.getExternalContext(); ServletRequest request = (ServletRequest) externalCtx.getRequest(); contextRoot = request.getScheme() + "://" + request.getServerName() + ":" + request.getLocalPort(); contextRoot += externalCtx.getRequestContextPath(); } public Set entrySet() { return new HashSet(); } public Object get(Object key) { try { if (key == null) return ""; URI uri = (URI) key; URLConnection conn = new URL(contextRoot + uri.toString()).openConnection(); InputStreamReader isr = new InputStreamReader(conn.getInputStream()); BufferedReader br = new BufferedReader(isr); String result = "", nextLine; while ((nextLine = br.readLine()) != null) { result = result + "\n" + nextLine; } return result; } catch (Exception e) { FacesContext facesCtx = FacesContext.getCurrentInstance(); FacesMessage message = new FacesMessage("Error rendering text item", e.toString()); message.setSeverity(FacesMessage.SEVERITY_FATAL); facesCtx.addMessage(null, message); return e.toString(); } } }

This bean, like the previous one, implements the Map interface, so we can call it in an EL expression with a parameter. You can see that the main part of the get method is the code that creates an HTTP request and fetches the reply. It is surrounded with exception handling, which reports any exception to the ADF Faces application as a severe error. Because the URI passed to the get method is a relative URI, in the bean’s constructor we create a string representing the context root of the application. The URI is appended to the context root to form the URL that is used to fetch the content.

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 17

Page 18: WebCenter application pages. Tech Note Content

Display the selected text Our first text item example uses the textItem bean to display the text from one of the files in a specified directory, as show in Figure 16.

Figure 16. Display Selected Item

On the left side of the page, an ADF table displays a list of files in a directory. When the user selects a file, its content is displayed on the right side of the page. To start, create a new JSF page called texts.jspx. You can refer to the steps for creating a JSF page at the beginning of the paper. Select the ADF Faces HTML Component Palette. We will create a table with a single row and two columns. Drag a TableLayout component and drop it on the empty page. Drop a RowLayout on the table and then drop two CellFormat components on the row. Figure 17 shows how the page looks in the Structure pane.

Figure 17. Structure Pane Showing the Page

In the Data Control Palette, expand the Texts > getItems node. Drag the Return node on the first CellFormat component in the Structure pane. Choose ADF Read-only Table from the Create context menu. In the Action Binding Editor, give /Samples for the Path and nt:file for the Type parameters. When the Edit Table Columns wizard window opens, delete all the columns except name. Select the Enable Selection checkbox and click OK.

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 18

Page 19: WebCenter application pages. Tech Note Content

Figure 18. Table of Items with Name Column Only

Drop an OutputText component on the second CellFormat component. Figure 19 shows how the resulting page looks in Design mode.

Figure 19. Page with Selectable Table and OutputText

We don’t need the Submit button because we will define an automatic submit. Click the Submit button to select it and press Delete. To set autosubmit on the radio buttons, click one of the radio buttons. In the Structure pane, notice that the af:tableSelectOne node is selected.

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 19

Page 20: WebCenter application pages. Tech Note Content

Figure 20. Selection Facet

In the Property Inspector, delete the value in the Text property and set AutoSubmit to true. To give the table a unique, self-descriptive ID, select the af:table node and set its Id property to files. We will use the Id when defining the PartialTriggers property. There is one more change to make before testing the application. The OutputText component should call the textItem bean. Select the component and change its value property to #{textItem[bindings.getItems1.URI]}. This takes the URI column of the current row in the table and calls the textItem bean with this value. Because the text in the content repository may contain HTML tags, change the OutputText’s Escape property to false. Finally, select the CellFormat component surrounding this OutputText and change the PartialTriggers property to files, which is the identifier for the ADF table on the page. This is how the source of this part of the page looks:

<afh:cellFormat partialTriggers="files"> <af:outputText value="#{textItem[bindings.getItems1.URI]}" escape="false"/> </afh:cellFormat>

Run the page and test the application at this stage. Select various files. Figure 21 shows a sample page:

Figure 21. Example HTML Item

Formatting the page We can format the page to achieve a pleasanter layout. Specifically, we do the following:

• Align the top of the two cells by setting the Valign property for RowLayout to top.

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 20

Page 21: WebCenter application pages. Tech Note Content

• Create a border and some padding around the content by changing the second CellFormat’s inlineStyle property, for example:

<afh:cellFormat partialTriggers="files" inlineStyle="padding:10.0px; border-style:solid; border-color:rgb(0,128,128);">

We can also define sizes for both columns of the table and specify that the table and the content in the columns should fill the available space. Here are the layout control tags; specify the width attributes as indicated in bold.

<afh:tableLayout width="100%"> <afh:rowLayout valign="top"> <afh:cellFormat width="20%"> <af:table . . . width="100%"> . . . </af:table> </afh:cellFormat> <afh:cellFormat . . . width="*"> . . . </afh:cellFormat> </afh:rowLayout> </afh:tableLayout>

Run the page again to see the improved layout.

Displaying an item using its path In the previous example, we displayed a text item with a known URI. Sometimes only the item’s name and path are known, as in Figure 22 below.

Figure 22. Displaying an Item with Its Path

Our next example looks similar to the previous text example, but its implementation is somewhat different. Instead of using the URI from an iterator, we use a String variable that contains a path to the item we want to display. First let’s create another row in the TableLayout, similar to the first one. The easiest way is to copy the row in the Structure pane. Select afh:rowLayout, copy it to the clipboard, and paste it on the afh:tableLayout node. You should see two rows now:

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 21

Page 22: WebCenter application pages. Tech Note Content

Figure 23. Table Layout with Duplicated Row

In the new row, we will not use the selection mechanism, so you should remove the selectionState and selectionListener attributes and the selection facet. There are several ways to do this. Possibly the easiest way is to edit the page source; alternatively, you can use the Property Inspector and Structure panes. In the table tag below, the bold text that is not in italics indicates the parts to be removed:

<af:table value="#{bindings.getItems1.collectionModel}" var="row" rows="#{bindings.getItems1.rangeSize}" first="#{bindings.getItems1.rangeStart}" emptyText="#{bindings.getItems1.viewable ? 'No rows yet.' : 'Access Denied.'}" selectionState="#{bindings.getItems1.collectionModel.selectedRow}" selectionListener= "#{bindings.getItems1.collectionModel.makeCurrent}" id="paths" width="100%"> <af:column sortProperty="path" sortable="false" headerText="#{bindings.getItems1.labels.path}"> <af:outputText value="#{row.path}"/> </af:column> <f:facet name="selection"> <af:tableSelectOne autoSubmit="true"/> </f:facet> </af:table>

Next, change the table’s id attribute to paths and change the column’s definition to display the path instead of the name, as indicated in bold italics in the example above. Change the second CellFormat’s partialTriggers attribute to paths. The next step is to modify the textItem bean so that it accepts a path instead of an URI, and use the JCR DataControl’s getURI method to look up the corresponding URI. Next, we will create a methodAction binding. Open the page definition file. In the Structure pane, right-click bindings, select Insert inside bindings > methodAction. In the Action Binding Editor window, select the Texts data control, and from the Action drop-down list, select getURI(String). Leave the path parameter empty.

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 22

Page 23: WebCenter application pages. Tech Note Content

Figure 24. Bind getURI as Method Action

Open TextItem.java and add the following code into the class. It creates a new writable bean property called getURIOperation. You also have to import oracle.binding.OperationBinding into the class file.

private OperationBinding getURIOperation; public void setGetURIOperation(OperationBinding getURIOperation) { this.getURIOperation = getURIOperation; }

Open faces-config.xml to set a value to this new property. In the Source mode of the visual editor, add a managed property to the textItem bean, as in the example below:

<managed-bean> <managed-bean-name>textItem</managed-bean-name> <managed-bean-class> jcrdemo.view.managed.TextItem </managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <managed-property> <property-name>getURIOperation</property-name> <value>#{bindings.getURI}</value> </managed-property> </managed-bean>

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 23

Page 24: WebCenter application pages. Tech Note Content

In TextItem.java, we will modify the code of the get method to accept a URI or a String type parameter. If a String type object is passed as the parameter, the method fetches the corresponding URI, using the getURI method that is bound to this bean. Replace the statement:

URI uri = (URI) key;

with the following code fragment:

URI uri; if (key instanceof URI) { uri = (URI) key; } else if (key instanceof String) { String path = (String) key; if (path.length() == 0) return ""; if (getURIOperation == null) throw new Exception ("No operation bound"); getURIOperation.getParamsMap().put("path", path); uri = (URI) getURIOperation.execute(); if (uri == null) throw new Exception ("Failed to look up path: " + path); } else throw new Exception ("Wrong parameter type");

This code sets the path parameter of the getURI operation, executes it, and uses the result later in the method. The last step in our example is to provide a link in the item table which, when clicked, passes the selected path to the textItem bean. In the Structure pane, right-click the outputText component that displays the path column, and select Convert from the context menu.

Figure 25. Convert OutputText

Select CommandLink in the Convert OutputText dialog box. Click OK in the Confirm Convert dialog box. Now change the resulting CommandLink’s text attribute to #{row.path}:

<af:commandLink text="#{row.path}"/>

Next, create a temporary variable to hold the selected path. Select faces-config.xml and create a new String type managed bean called actPath. You can use the Design view or enter the following XML fragment in the Source view:

<managed-bean> <managed-bean-name>actPath</managed-bean-name> <managed-bean-class>java.lang.String</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean>

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 24

Page 25: WebCenter application pages. Tech Note Content

Select the texts.jspx file again. Drop a SetActionListener component on top of the CommandLink. In the Insert SetActionListener window, specify From as #{row.path} and To as #{actPath}. This is the resulting XML fragment:

<af:commandLink text="#{row.path}"> <af:setActionListener from="#{row.path}" to="#{actPath}"/> </af:commandLink>

Now change the OutputText that displays the selected item. Set its value property to #{textItem[actPath]}:

<af:outputText value="#{textItem[actPath]}" escape="false"/>

Run the page to see and compare your page with the final version of our example looks, as shown in Figure 26. Try selecting different files from the first and second rows.

Figure 26. Completed Text Items Example

5. Summary

This technical note showed how to display content stored in a content repository on Oracle WebCenter application pages. Because each content management solution has its own proprietary API, WebCenter supplies several JCR 1.0 adapters to access different content repositories. The examples discussed in this paper use a JCR data control to access content stored in the file system. If your installation contains any WebCenter-supported content repository, the same examples still apply; the only difference is in creating the data control.

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 25

Page 26: WebCenter application pages. Tech Note Content

Oracle WebCenter TechNote January 2008 Author: Istvan Kiss Contributing Authors: Oracle Corporation World Headquarters 500 Oracle Parkway Redwood Shores, CA 94065 U.S.A. Worldwide Inquiries: Phone: +1.650.506.7000 Fax: +1.650.506.7200 oracle.com Copyright © 2008, Oracle. All rights reserved. This document is provided for information purposes only and the contents hereof are subject to change without notice. This document is not warranted to be error-free, nor subject to any other warranties or conditions, whether expressed orally or implied in law, including implied warranties and conditions of merchantability or fitness for a particular purpose. We specifically disclaim any liability with respect to this document and no contractual obligations are formed either directly or indirectly by this document. This document may not be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without our prior written permission. Oracle, JD Edwards, PeopleSoft, and Retek are registered trademarks of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Oracle, JD Edwards, PeopleSoft, and Retek are registered trademarks of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.

Oracle WebCenter TechNote: Displaying Content on WebCenter Pages Page 26