Skip Headers
Oracle® Fusion Middleware Web Service Developer's Guide for Oracle WebCenter Interaction
10g Release 4 (10.3.3.0.0)

Part Number E14109-02
Go to Documentation Home
Home
Go to Table of Contents
Contents
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

2 Oracle WebCenter Interaction Portlet and Pagelet Development

The chapter provides general information about Oracle WebCenter Interaction portlet development and configuration, including descriptions of portlet API, proxy API, Programmable Remote Client (PRC) remote APIs, and adaptive portlets.

For details on configuring portlets, see the online help.

Oracle WebCenter Interaction Development Kit (IDK) Portlet API

The Oracle WebCenter Interaction Development Kit (IDK) Portlet API provides Oracle WebCenter Interaction-specific support for portlet development, including manipulating settings in the portal database, accessing user information, and managing communication with the portal.

This page provides an introduction to the Oracle WebCenter Interaction Development Kit (IDK) Portlet API. For more details, see the API documentation.

Note:

The IDK was formerly called the AquaLogic Interaction Development Kit (IDK) and the Plumtree Development Kit (EDK); some package names retain old naming conventions.

The plumtree.remote.portlet package/namespace includes the following interfaces:

In general, these interfaces are called in the following order:

  1. A portlet uses PortletContextFactory.createPortletContext to initiate a connection for communicating with the portal.

  2. The IPortletContext interface returned allows the portlet to access information about the request and response, the current user, and the session. The portlet uses this information as needed, in arbitrary order, to generate a proper response. Using IPortletContext, the portlet can access IPortletRequest, IPortletUser, IRemoteSession and IPortletResponse.

  3. The portlet retrieves parameters from the request using IPortletRequest.

  4. The portlet retrieves user information and preferences from IPortletUser.

  5. The portlet can access functionality in Oracle WebCenter Interaction applications using IRemoteSession. For details, see Adaptive Portlet Design Patterns.

  6. The portlet constructs a response using IPortletResponse. The response includes content to be displayed and any settings to be stored or removed.

For examples of using IPortlet interfaces in a portlet, see Creating a Custom Oracle WebCenter Interaction Portlet with the Java Oracle WebCenter Interaction Development Kit (IDK) Portlet API and Creating a Custom Oracle WebCenter Interaction Portlet with the .NET Oracle WebCenter Interaction Development Kit (IDK) Portlet API.

Creating a Custom Oracle WebCenter Interaction Portlet with the Java Oracle WebCenter Interaction Development Kit (IDK) Portlet API

This simplified Hello World portlet example allows a user to set the message that is displayed within a portlet.

Before writing any code, create a new Oracle WebCenter Interaction Development Kit (IDK) project as described in Java: Setting Up a Custom Oracle WebCenter Interaction Development Kit (IDK) Project in Eclipse.

This example uses two pages: a portlet that displays the current setting value and a form for changing the value, and a page that sets the value in the portal database and redirects to the portal page.

In the new project, create a new JSP page for the portlet (portlet.jsp). The portlet code shown below instantiates the Oracle WebCenter Interaction Development Kit (IDK) and uses the portlet API IPortletRequest object to check for a Portlet setting called "PortletEntry." If the setting has an associated value, the portlet displays it. The portlet also displays a form that allows the user to enter a value. When the user clicks Submit, the portlet code sends the value from the form in a request to the setPrefs.jsp page, shown next.

Note:

There is no need to include html, head and body tags; the portlet is displayed as part of the HTML table that makes up the portal page.

<%@ page language="java" import="com.plumtree.remote.portlet.*,java.util.Date" %>
You refreshed at <%= new Date().toString()%><br/>

<%
//get the idk
IPortletContext portletContext = PortletContextFactory.createPortletContext(request, response);
IPortletRequest portletRequest = portletContext.getRequest();
String settingKey = "PortletEntry";

String settingValue = portletRequest.getSettingValue(SettingType.Portlet, settingKey);

//if the entry has already been set, display it here
if (null != settingValue)
{
%>
  <br/><b> Preference value is <%=settingValue%></b>!<br/>
<%
}  

//form to enter the preference
%>
<P>Enter your preference:
<form METHOD="post" ACTION="setPrefs.jsp" name="form1">
<input type="text" name="<%=settingKey%>">
<br/>
<input type="submit" name="Submit" value="Submit">
</form>

Next, create the Set Preferences page (setPrefs.jsp). The code shown below gets the value for the PortletEntry Portlet setting from the request, then uses the IDK Portlet API IPortletResponse object to add the setting to the database and redirect to the portal. The redirect causes the portal page to refresh and display the updated setting in the portlet.

<%@ page language="java" import="com.plumtree.remote.portlet.*" %>

<%
//set the cache control so we don't get a cached page
response.setHeader("Cache-control", "max-age=0");

//get the idk
IPortletContext portletContext = PortletContextFactory.createPortletContext(request, response);  

//get IPortletResponse to set preferences and redirect back to the portal
IPortletResponse portletResponse = portletContext.getResponse();

//get the setting value from the servlet request
String settingKey = "PortletEntry";
String settingValue = request.getParameter(settingKey);

//set the setting value
portletResponse.setSettingValue(SettingType.Portlet, settingKey, settingValue);

//redirect back to the portal
portletResponse.returnToPortal();

%>

After you have completed the JSP pages, deploy your custom project as described in Java: Deploying a Custom Oracle WebCenter Interaction Development Kit (IDK) Project in Eclipse .

Creating a Custom Oracle WebCenter Interaction Portlet with the .NET Oracle WebCenter Interaction Development Kit (IDK) Portlet API

This simplified Hello World portlet example allows a user to set the message that is displayed within a portlet.

Before writing any code, create a new Oracle WebCenter Interaction Development Kit (IDK) project as described in .NET: Setting Up a Custom Oracle WebCenter Interaction Development Kit (IDK) Project in Visual Studio.

This example creates a portlet that displays the current setting value and a form for changing the value. .NET portlets use a code-behind page to manipulate settings and redirect to the portal. The web form that makes up the portlet (portlet.asp) simply initiates the code-behind page (portlet.aspx.cs) and displays a form that prompts the user to enter a message. The sample code below is for VisualStudio 2005.

Note:

There is no need to include html, head and body tags; the portlet is displayed as part of the HTML table that makes up the portal page.

<%@ Page language="c#" CodeFile="portlet.aspx.cs" AutoEventWireup="false" Inherits="HelloWorld.WebForm1" ResponseEncoding="UTF-8"%> 

<form id="Form1" method="post" runat="server">
<br>
<asp:label runat="server" id="settingsDisplay"></asp:label>
<br><br>
Enter your message:<br>&nbsp;&nbsp;&nbsp;
<asp:textbox id="PrefName" runat="server"></asp:textbox>
<br><br>
<asp:Button id="AddButton" runat="server" Text="Submit" ></asp:Button>
<br>
</form> 

The code-behind page instantiates the Oracle WebCenter Interaction Development Kit (IDK) and uses the portlet API IPortletRequest object to check for a Portlet setting called "MyPref". If the setting has an associated value, the page sends it back for display. If the user entered a new value in the form, the portlet sends it back for display and uses the IPortletResponse object to store it in the portal database. When the setting value and portlet display are updated, the portal page is refreshed.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Plumtree.Remote.Portlet;

namespace HelloWorld

{
  /// <summary>
  /// Summary description for WebForm1.
  /// </summary>
  public class WebForm1 : System.Web.UI.Page
  {
  //put member variables in protected scope as that is the most 
  //limited scope that the aspx page can see.

  protected System.Web.UI.WebControls.Label settingsDisplay;
  protected System.Web.UI.WebControls.TextBox PrefName;
  protected System.Web.UI.WebControls.Button AddButton;
  protected Plumtree.Remote.Portlet.IPortletRequest portletRequest;
  protected Plumtree.Remote.Portlet.IPortletResponse portletResponse;
  protected string settingKey = "MyPref";
  protected string settingValue;
  private void Page_Load(object sender, System.EventArgs e)
  {
  }
      #region Web Form Designer generated code
      override protected void OnInit(EventArgs e)
      {
         //
         // CODEGEN: This call is required by the ASP.NET Web Form 
         // Designer.
         //
         InitializeComponent();
         base.OnInit(e);
      }
  /// <summary>
  /// Required method for Designer support - do not modify
  /// the contents of this method with the code editor.
  /// </summary>
  private void InitializeComponent()
  {  
     this.AddButton.Click += new 
     System.EventHandler(this.AddButton_Click);
     this.Load += new System.EventHandler(this.Page_Load);
  }
  #endregion 
  private void AddButton_Click(object sender, System.EventArgs e)
  {
     //get the setting value
     IPortletContext portletContext =  
     PortletContextFactory.CreatePortletContext(Request,Response);
     portletRequest = portletContext.GetRequest();
     portletResponse = portletContext.GetResponse();
     settingValue = portletRequest.GetSettingValue(SettingType.Portlet,settingKey);

     //set the label with the retrieved value 
     //(if it has already been set)
     if (null != settingValue)
     {
         settingsDisplay.Text = "Old preference value is " + Server.HtmlEncode(settingValue) + "!";          
     }
     if (PrefName.Text != "")
     {
         settingsDisplay.Text += "\New preference value is " + Server.HtmlEncode(PrefName.Text)+ "!";
         portletResponse.SetSettingValue(SettingType.Portlet, settingKey,PrefName.Text);
      }
  }
}

After you have completed the portlet code, deploy your custom project as described in .NET: Deploying a Custom Oracle WebCenter Interaction Development Kit (IDK) Project in IIS.

Oracle WebCenter Interaction Development Kit (IDK) Proxy API

This section provides an introduction to the Oracle WebCenter Interaction Development Kit (IDK) Proxy API. For more details on objects and methods, see the API documentation. For details on Oracle WebCenter Interaction-specific portlet interfaces, see the Oracle Fusion Middleware Web Service Developer's Guide for Oracle WebCenter Interaction.

The bea.alui.proxy package/namespace includes the following interfaces:

In general, these interfaces are called in the following order:

  1. A pagelet uses ProxyContextFactory.getInstance().createProxyContext to initiate a connection for communicating with Oracle WebCenter Ensemble.

  2. The IProxyContext object returned allows the pagelet to access information about the request and response, the current user, and the session. The pagelet uses this information as needed, in arbitrary order, to generate a proper response. Using IProxyContext, the pagelet can access IProxyRequest, IProxyUser, IRemoteSession and IProxyResponse.

  3. The pagelet retrieves parameters from the request using IProxyRequest.

  4. The pagelet retrieves user information and preferences from IProxyUser.

  5. The pagelet can access functionality in Oracle WebCenter Interaction applications using IRemoteSession. For details, see Adaptive Portlet Design Patterns.

  6. The pagelet constructs a response using IProxyResponse. The response includes content to be displayed and any settings to be stored or removed.

For examples of using IProxy interfaces in a pagelet, see Creating a Custom Pagelet with the Java Oracle WebCenter Interaction Development Kit (IDK) Proxy API and Creating a Custom Pagelet with the .NET Oracle WebCenter Interaction Development Kit (IDK) Proxy API.

Creating a Custom Pagelet with the Java Oracle WebCenter Interaction Development Kit (IDK) Proxy API

This example creates a simple pagelet that displays information from the proxy, including setting values.

  1. Before writing any code, create a new Oracle WebCenter Interaction Development Kit (IDK) project as described in Java: Setting Up a Custom Oracle WebCenter Interaction Development Kit (IDK) Project in Eclipse.

  2. In the new project, create a new JSP page for the pagelet (pagelet.jsp).

  3. Implement your code. The pagelet code shown below instantiates the Oracle WebCenter Interaction Development Kit (IDK) and uses the IProxyContext interface to retrieve IProxyRequest and IProxyUser objects to access information about the user and the settings associated with the pagelet.

    Note:

    There is no need to include html, head and body tags; the display is handled by the Consumer resource.

<%@ page language='java' import='com.bea.alui.proxy.*' %>
<%
String Att1 = 'no setting';
String Att2 = 'no setting';
String sessionVariable = 'no setting';

//get the idk
IProxyContext proxyContext = ProxyContextFactory.getInstance().createProxyContext(request, response);
IProxyRequest proxyRequest = proxyContext.getProxyRequest()

IProxyUser proxyUser = proxyRequest.getUser();
String userName = proxyUser.getUserName(); 
int userID = proxyUser.getUserID();

Att1 = proxyRequest.getSetting('Att1')
Att2 = proxyRequest.getSetting('Att2');
sessionVariable = proxyRequest.getSetting('sessionVar');

byte[] payload = proxyRequest.getPayload().getText();
String payloadStr = new String(payload)
%>

<p>User name: <%=userName%><br/> 
User ID: <%=userID%><br/> 
Attribute 1: <%=Att1%><br/> 
Attribute 2: <%=Att2%><br/> 
Session variable: <%=sessionVariable%><br/> 
Payload: <textarea name=xml cols=80 rows=6> <%=payloadStr%> </textarea>
</p>

Creating a Custom Pagelet with the .NET Oracle WebCenter Interaction Development Kit (IDK) Proxy API

This example creates a simple pagelet that displays information from the proxy, including setting values. .NET pagelets use a code-behind page (.aspx.cs) to retrieve settings and a Web form (.aspx) to display the pagelet content.

  1. Before writing any code, create a new Oracle WebCenter Interaction Development Kit (IDK) project as described in .NET: Setting Up a Custom Oracle WebCenter Interaction Development Kit (IDK) Project in Visual Studio.

  2. In the new project, implement your code. The example below uses a code-behind page and a web form.

The code-behind page (IDKPagelet.aspx.cs) instantiates the Oracle WebCenter Interaction Development Kit (IDK) and uses the IProxyContext interface to retrieve IProxyRequest and IProxyUser objects to access information about the user and the settings associated with the pagelet.

using System; 
using System.Collections; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Web; 
using System.Web.SessionState; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.HtmlControls; 
using Plumtree.Remote.Portlet; 
using System.Xml; 
using System.Text; 
using Bea.Alui.Proxy;

namespace IDKProxyWS
{
/// <summary>
/// Hello World Pagelet
/// </summary>
   public class IDKPagelet : System.Web.UI.Page 
   {
      public String name; 
      public bool isGuest; 
      public int userID; 
      public String envType; 
      public String payload; 
      public String Att1,Att2; 
      public String SessionVar;
      private void Page_Load(object sender, System.EventArgs e
      {
         // Put user code to initialize the page here
         InitializeCSP();
      }
      private void InitializeCSP()
      {
         IProxyRequest proxyRequest; 
         IProxyResponse proxyResponse; 
         IProxyUser proxyUser; 
         IProxyContext proxyContext; 
         ProxyContextFactory factory; 
         HttpRequest request = HttpContext.Current.Request; 
         HttpResponse response = HttpContext.Current.Response;

         try
         {
            factory = ProxyContextFactory.getInstance(); 
            proxyContext = factory.CreateProxyContext(request, response); 
            proxyRequest = proxyContext.GetProxyRequest(); 
            proxyResponse = proxyContext.GetProxyResponse(); 
            envType = proxyRequest.GetEnvironment().GetType().ToString();
            proxyUser = proxyRequest.GetUser(); 
            isGuest = proxyUser.IsAnonymous(); 
            name= proxyUser.GetUserName(); 
            userID = proxyUser.GetUserID();

            Att1 = (String)proxyRequest.GetSetting('attr1');
            Att2 = (String)proxyRequest.GetSetting('attr2');
            Att2 = (String)proxyRequest.GetSetting('SessionVar');

            byte[] bpayload = proxyRequest.GetPayload().GetText()
            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding()
            payload = enc.GetString(bpayload)
         }  
         catch(Bea.Alui.Proxy.NotGatewayedException e)
         {
         }
      }
   }
#region Web Form Designer generated code
... 
#endregion
}

The Web form that displays the pagelet (IDKPagelet.aspx) displays the information retrieved by the code-behind page above.

<%@ Page Language='c#' runat='server' CodeBehind='IDKPagelet.aspx.cs' AutoEventWireup='false' inherits='IDKProxyWS.IDKPagelet' %>
<%@ import Namespace='System.Collections' %> 
<%@ import Namespace='System.Web' %> 
<%@ import Namespace='System.Web.UI' %>

<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN' >
<html>
<head>
<title>IDKPagelet</title>
<meta name='GENERATOR' Content='Microsoft Visual Studio .NET 7.1'>
<meta name='CODE_LANGUAGE' Content='C#'>
<meta name='vs_defaultClientScript' content='JavaScript'>
<meta name='vs_targetSchema' content='http://schemas.microsoft.com/intellisense/ie5'>
</head>

<body MS_POSITIONING='GridLayout'> 
<span xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>

Proxy Pagelet <BR>
<%
   Response.Write('IDK Proxy Pagelet<BR>');  
   Response.Write('Environment Type ' + envType + '<BR>'); 
   Response.Write('Guest User? ' + isGuest + '<BR>'); 
   Response.Write('User Name: ' + name + '<BR>'); 
   Response.Write('User ID: ' + userID + '<BR>'); 
   Response.Write('<P>');

   Response.Write('Pagelet Attributes:<BR>');
   Response.Write('Attribute1: ' + Att1 + '<BR>');
   Response.Write('Attribute2: ' + Att2 + '<BR>')
   Response.Write('SessionVar: ' + SessionVar + '<BR>')
   Response.Write('<P>')

   Response.Write('Pagelet XML Payload:<BR>'); 
   Response.Write('<textarea name=xml cols=80 rows=6>' + payload + '</textarea>'); 
   Response.Write('<P>');
%>
</span>
</body>
</html>

Using Programmable Remote Client (PRC) Remote APIs

The plumtree.remote.prc package includes a collection of APIs that provide access to functionality within Oracle WebCenter Interaction, Oracle WebCenter Collaboration, and the portal Search Service. These APIs are supported by Oracle WebCenter Ensemble, and can be used by any pagelet deployed in an environment with access to these applications.

PRC APIs free you from serializing SOAP messages and minimize the amount of data that travels between the portal and other servers, improving performance.

The PRC is included with both the Java and .NET versions of the Oracle WebCenter Interaction Development Kit (IDK). The Java version includes Apache AXIS 1.0; the .NET version uses the platform-native SOAP client stack. Java clients can call .NET portals and vice-versa; the PRC takes care of the communication between AXIS and .NET. Pagelets that use the PRC can be deployed in either Oracle WebCenter Interaction or Oracle WebCenter Ensemble. For details on using the PRC, see the Oracle Fusion Middleware Web Service Developer's Guide for Oracle WebCenter Interaction.

Oracle WebCenter Interaction Development Kit (IDK) Programmable Remote Client (PRC) Remote APIs

The Oracle WebCenter Interaction Development Kit (IDK) Programmable Remote Client (PRC) provides an object-oriented way to call into Oracle WebCenter Interaction SOAP APIs. The PRC can be used to write applications that access the Oracle WebCenter Interaction and search, and Oracle WebCenter Collaboration.

PRC APIs free you from serializing SOAP messages and minimize the amount of data that travels between the portal and the remote server, improving performance.

The PRC is included with both the Java and .NET versions of the Oracle WebCenter Interaction Development Kit (IDK). The Java version includes Apache AXIS 1.0; the .NET version uses the platform-native SOAP client stack. Java clients can call .NET portals and vice-versa; the PRC takes care of the communication between AXIS and .NET.

The PRC provides access to functionality in a range of Oracle WebCenter products:

For an introduction to using the PRC, see the following sections:

The PRC Session Object

When using Oracle WebCenter Interaction Development Kit (IDK) remote APIs. the Session object is the master object; most other portal objects must be derived from it.

A Session object is created whenever any user logs in to the Oracle WebCenter Interaction system through the web or a client application. All subsequent access is made in the security context of the connected user. Users in the Administrators group have superuser access. Users in Content Manager and Content Maintainer groups also have privileged access. For details on portal groups and specific privileges, see the Administrator Guide for Oracle WebCenter Interaction.

The Session object supports the IPTSession interface, represented in the PRC by the IRemoteSession interface. The Session object is comprised of:

  • A set of Object Managers for the objects of the Oracle WebCenter Interaction system. An Object Manager is like a super collection. It provides advanced querying capabilities as well as create, delete, and clone methods. The Session object includes managers for almost every Oracle WebCenter Interaction portal, Search Service, and Oracle WebCenter Collaboration object. Managers are added as new object classes are introduced.

  • A User object representing the current user of the system.

  • A Catalog object representing the structure of the Oracle WebCenter Interaction catalog.

  • Version information.

  • Access to global Oracle WebCenter Interaction objects such as the MyPortal object, the scheduler, and global mapping objects.

Initiating a session is the first step in any implementation of the PRC.

Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To use the Oracle WebCenter Interaction Development Kit (IDK) Programmable Remote Client (PRC) Remote APIs, you must first establish a session with Oracle WebCenter Interaction.

The session is used to manipulate objects via the PRC. Once you have initiated a session, you can use PRC methods to manipulate Oracle WebCenter Interaction objects.

Note:

Before writing any code, you must prepare a custom project that references the standard Oracle WebCenter Interaction Development Kit (IDK) library (idk.jar/idk.dll).

To establish a session with the portal, acquire a reference to an IRemoteSession object. The simple code examples below do the following:

  1. Create a new class (HelloWorldSession).

  2. Create a new remote session using RemoteSessionFactory. The code below logs in with a user name of "administrator" and no password. You can also access an IRemoteSession through the IDK portlet and proxy APIs (IPortletContext.GetRemoteSession or IProxyContext.GetRemoteSession).

    Note:

    You must configure Oracle WebCenter Interaction to send a login token to any portlet that uses the PRC by selecting the login token option on the Advanced Settings page of the Web Service editor.

  3. Print out the portal API version from the remote session.

Java:

import java.net.URL;
import com.plumtree.remote.prc.*;
public class HelloWorldSession
{
public static void main(String[] args) throws Exception
{
try
{
IRemoteSession session = RemoteSessionFactory.getExplicitLoginContext(
new URL("http://portalserver/ptapi/services/QueryInterfaceAPI"),
 "administrator","");

 System.out.println(session.getAPIVersion());
 }
   catch(Exception e)
 {
   System.err.println(e.getMessage());
   e.printStackTrace(System.err);
 }
 }
}

.NET (C#):

using System;
using Plumtree.Remote.PRC;
public class HelloWorldSession
{
 public static void Main(string[] args)
 {
 try
 {
   IRemoteSession session = RemoteSessionFactory.GetExplicitLoginContext(
   new Uri("http://portalserver/ptapi/services/QueryInterfaceAPI"), "administrator","");

   Console.Out.WriteLine(session.GetAPIVersion());
 }
   catch(Exception e)
   {
     Console.Error.WriteLine(e.Message);
     Console.Error.WriteLine(e.StackTrace); 
   }
 }
}

.NET (VB):

Imports System
Imports Plumtree.Remote.PRC
Module HelloWorldSession

 Sub Main()
 Try
 Dim session As IRemoteSession
 session = RemoteSessionFactory.GetExplicitLoginContext( _
 New Uri("http://portalserver/ptapi/services/QueryInterfaceAPI"), _
 "administrator", _"")
 Console.Out.WriteLine(session.GetAPIVersion())
 Catch e As Exception
 Console.Error.WriteLine(e.Message)
 Console.Error.WriteLine(e.StackTrace)
 End Try
 End Sub

End Module

Oracle WebCenter Interaction Development Kit (IDK) PRC Remote API Development Tips

These development tips apply to any application that uses the Oracle WebCenter Interaction Development Kit (IDK) PRC remote APIs.

  • You must configure Oracle WebCenter Interaction or Oracle WebCenter Ensemble to send a login token to any portlet that uses the PRC. In Oracle WebCenter Interaction, the login token option is on the Advanced Settings page of the Web Service editor. In Oracle WebCenter Ensemble, this option is on the CSP tab in Resource configuration.

  • Perform expensive processing outside the interface method, in a separate thread, or use back-end caching such that the interface method can respond in a timely fashion. For example, an Active Directory Authentication Source Identity Service might employ user signatures to minimize reads/writes from the AD database during remote calls like IProfileProvider.attachToUser. The Oracle WebCenter Interaction Development Kit (IDK) PRC manager interfaces generally make remote calls. PRC object interfaces are normally local accessors/mutators and do not make remote calls (with the exception of store methods). Avoid unnecessary, repeated use of manager interface methods and maximize your application's use of PRC object methods. Avoid looping remote calls wherever possible. Maintaining local copies of PRC objects can improve your application's performance but be aware that your local state may not match the server state if another application modifies server state after you receive your local copy. For example, a portlet using PRC Collaboration to display the current user's personal Oracle WebCenter Collaboration project area corresponding to “Username-Project” ensures that IProjectManager.queryProjects is used once. The resulting IProject object can be cached by the portlet per user session rather than performing a query on every portlet refresh. The user's project is never deleted, so the local caching is “safe.”

Remote Oracle WebCenter Interaction APIs

The portal provides the framework for applications and integrates Oracle WebCenter Interaction components into a cohesive web work environment. Administration is the core of the portal, where all portal objects and operations are configured.

The Oracle WebCenter Interaction Development Kit (IDK) PRC's remote Oracle WebCenter Interaction APIs provide access to key administrative components, as explained in the following sections:

  • Remote Object Management: Everything in the portal, except users and documents, is represented by a portal object stored in the portal database. This includes portlets, content crawlers, authentication sources, profile sources, remote servers, and content sources. The IObjectManager interface allows you to access portal objects from your remote services. You can look up information about a specific object, or query for objects using a range of methods, including location, class, and custom filters. You can also query and manipulate the security for portal objects.

  • Remote Portlet Operations: There are many settings and options that apply only to portlets. In addition to manipulating portlet objects via IObjectManager, the PRC supports advanced portlet operations. Using the IPortlet* interfaces, you can create and edit portlets and portlet templates, and manage administrative and communityportlet preferences for a specific portlet instance.

  • Remote Directory Operations: The portal directory stores links to documents in a hierarchical structure of folders and subfolders. These documents can be external or internal web pages, Office documents, or essentially any file of interest. The IDocument* interfaces allow you to query for documents and document properties, create new documents, and edit the properties for existing documents.

  • Remote User Operations: Portal users are organized into groups and sub-groups. This role-based hierarchy allows administrators to customize the portal display for specific audiences and assign object security for collections of users. The IUserManager and IUserGroupManager interfaces allow you to leverage the portal's user hierarchy. You can query for the current user's ID and group information, create new groups, and manage group membership.

  • Remote Search Operations: Using the PRC search API, you can query document, folder, user and Community objects using a standard request-response model. The API allows you to add multiple constraints and filter searches by location or object type.

  • Starting Portal Jobs Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs: A job is a collection of related portal operations. Each operation is one task, such as a crawl for documents, an import of users, or one of the system maintenance tasks. To start an existing job from a remote application, use the IJobManager interface.

Remote Object Management

Everything in the portal, except users and documents, is represented by a portal object stored in the portal database. This includes portlets, content crawlers, authentication sources, profile sources, remote servers, and content sources. The PRC IObjectManager interface in the Oracle WebCenter Interaction Development Kit (IDK) allows applications to access portal objects from remote services.

Using the PRC, you can look up information about a specific object, or query for objects using a range of methods, including location, class, and custom filters. You can also query and manipulate the security for portal objects.

For details on using remote object management, see the following sections:

Retrieving Object Managers Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To access portal objects from a remote application, first retrieve an IObjectManager object from the IRemoteSession object.

To retrieve an IObjectManager object from the IRemoteSession object, follow the steps below.

  1. Create a session with the portal. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve an instance of IObjectManager from the IRemoteSession object, as shown in the sample code below. This example demonstrates how to retrieve an Object Manager to query communities, using an existing IRemoteSession instance. For a list of object types, see Oracle WebCenter Interaction Object Type Class IDs and Modes.

Java:

IObjectManager objectManager = session.getObjectManager(ObjectClass.Community);

.NET (C#):

IObjectManager objectManager = session.GetObjectManager(ObjectClass.Community);

.NET (VB):

Dim objectManager as IObjectManager
objectManager= session.GetObjectManager(ObjectClass.Community)
Querying Objects Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To query for portal objects from a remote application, use the IObjectManager interface in the Oracle WebCenter Interaction Development Kit (IDK).

The IObjectManager interface in the Oracle WebCenter Interaction Development Kit (IDK) PRC allows you to query for objects using a range of methods, including location, class, and custom filters. To query for portal objects, follow the steps below. You can also use the PRC Search API to query for portal objects; for details, see Remote Search Operations.

  1. Create a session with the portal. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve an Object Manager for the type of object you are querying. For details, see Retrieving Object Managers Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  3. Execute the query, as shown in the sample code below. This example demonstrates how to query for portal users matching specific criteria within the portal, using the following process:

    1. Declare and prepare all parameters to be passed to the query method. This example uses the most flexible query call, with the following parameters. If any of these parameters is omitted, the default value will be used. (There are simpler calls with fewer parameters; for details, see the IDK API documentation.)

      Parameter Description Default

      folderID

      The folder to search.

      all folders (folderID = -1)

      startRow

      The row on which to start the search.

      the initial row (startRow = 0)

      maxRows

      The maximum number of rows to search.

      unlimited (maxRow = -1)

      sortProperty

      The object property on which to sort results.

      object ID (sortProperty = ObjectProperty.ObjectID)

      ascending

      The sort order for results (ascending or descending).

      ascending (ascending = true)

      propsToReturn

      The properties to return.

      all properties

      filters

      The values on which to filter results.

      no filters


    2. Execute the query to retrieve an IObjectQuery instance.

    3. Enumerate through the query, displaying interesting information.

Java:

public static voidqueryObjects(String loginToken)
{
 IObjectManager objectManager = getSession(loginToken).getObjectManager(ObjectClass.User);

 int folderID = -1;  //search all folders
 int startRow = 0;  //start at the first found
 int maxRows = -1;  //return unlimited results
 ObjectProperty sortProperty = UserProperty.UniqueName;  //sort on the unique name
 boolean ascending = true;  //sort ascending

 ObjectProperty[] propsToReturn = new ObjectProperty[4];  //return specific properties
 propsToReturn[0] = UserProperty.SimpleName;
 propsToReturn[1] = UserProperty.UniqueName;
 propsToReturn[2] = UserProperty.AuthName;
 propsToReturn[3] = ObjectProperty.Created;

 QueryFilter[] filters = new QueryFilter[2];  //filter the results
 //simple name contains "user" 
 filters[0] = new StringQueryFilter(UserProperty.SimpleName, Operator.Contains,"user");  
 //created at most a day ago
 GregorianCalendar filterDate = new GregorianCalendar();
 filterDate.add(Calendar.DATE, -1);
 Date yesterday = filterDate.getTime();
 filters[1] = new DateQueryFilter(ObjectProperty.Created, Operator.GreaterThan, yesterday);
 try
 {
 IObjectQuery queryResults = objectManager.queryObjects(
 folderID,
 startRow,
 maxRows,
 sortProperty,
 ascending,
 propsToReturn,
 filters);

 for (int i = 0; i < queryResults.getRowCount(); i++)
 {
 IObjectQueryRow queryObject = queryResults.getRow(i);
 System.out.println(
 "User: " + queryObject.getStringValue(UserProperty.SimpleName) +
 ", Created:" + queryObject.getCreated());
 }
 }
 catch(Exception e)
 {
 System.err.println(e.getMessage());
 e.printStackTrace(System.err);
 }
}

.NET (C#):

public static voidQueryObjects(stringloginToken)
{
 IObjectManager objectManager = GetSession(loginToken).GetObjectManager(ObjectClass.User);

 int folderID = -1;  //search all folders
 int startRow = 0;  //start at the first found
 int maxRows = -1;  //return unlimited results
 ObjectProperty sortProperty = UserProperty.UniqueName;  //sort on the unique name
 bool ascending = true;  //sort ascending

 ObjectProperty[] propsToReturn = new ObjectProperty[4];  //return specific properties
 propsToReturn[0] = UserProperty.SimpleName;
 propsToReturn[1] = UserProperty.UniqueName;
 propsToReturn[2] = UserProperty.AuthName;
 propsToReturn[3] = ObjectProperty.Created;

 DateTime yesterday =  new DateTime();
 yesterday = DateTime.Now.AddDays(-1); 

 QueryFilter[] filters = new QueryFilter[2];  //filter the results
 //simple name contains "user"
 filters[0] = new StringQueryFilter(UserProperty.SimpleName, Operator.Contains, "user");
 //created at most a day ago
 filters[1] = new DateQueryFilter(ObjectProperty.Created, Operator.GreaterThan, yesterday);

 try
 {
 IObjectQuery queryResults = objectManager.QueryObjects(
 folderID,
 startRow,
 maxRows,
 sortProperty,
 ascending,
 propsToReturn,
 filters);

 for (int i = 0; i < queryResults.GetRowCount(); i++)
 {
 IObjectQueryRow queryObject = queryResults.GetRow(i);
 Console.Out.WriteLine(
 "User: " + queryObject.GetStringValue(UserProperty.SimpleName) +
 ", Created:" + queryObject.GetCreated());
 }
 }
 catch(Exception e)
 {
 Response.Write(e.Message + "<br>");
 Response.Write(e.StackTrace + "<br><br>");
 }
}

.NET (VB):

Public Shared SubQueryObjects(ByVal loginToken As String)

 Dim objectManager As IObjectManager
 Dim session As IRemoteSession = portletContext.GetRemotePortalSession

 objectManager = session.GetObjectManager(ObjectClass.User)

 Dim folderID As Integer
 folderID = -1 'search all folders

 Dim startRow As Integer
 startRow = 0 'start at the first found

 Dim maxRows As Integer
 maxRows = -1 'return unlimited results

 Dim sortProperty As ObjectProperty
 sortProperty = UserProperty.UniqueName 'sort on the unique name

 Dim ascending As Boolean
 ascending = True 'sort ascending

 Dim propsToReturn(4) As ObjectProperty 'return specific properties
 propsToReturn(0) = UserProperty.SimpleName
 propsToReturn(1) = UserProperty.UniqueName
 propsToReturn(2) = UserProperty.AuthName
 propsToReturn(3) = ObjectProperty.Created

 Dim yesterday As DateTime
 yesterday = DateTime.Now.AddDays(-1)

 Dim filters(2) As QueryFilter 'filter the results
 'simple name contains "user"
 filters(0) = New StringQueryFilter(UserProperty.SimpleName, _Operator.Contains, _"user") 
 'created at most a day ago
 filters(1) = New DateQueryFilter(ObjectProperty.Created, _Operator.GreaterThan, yesterday) 

 Try

 Dim queryResults As IObjectQuery
 queryResults = objectManager.QueryObjects(folderID, startRow, maxRows, sortProperty,
ascending, propsToReturn, filters)

 Dim i As Integer
 Dim queryObject As IObjectQueryRow
 For i = 0 To queryResults.GetRowCount()-1

 queryObject = queryResults.GetRow(i)
 Response.Write(_ "User: " & queryObject.GetStringValue(UserProperty.SimpleName)& _
 ", Created:" & queryObject.GetCreated() + "<br>")
 Next 

 Catch e As Exception
 Response.Write(e.Message + "<br>")
 Response.Write(e.StackTrace)

 End Try
EndSub
Oracle WebCenter Interaction Object Type Class IDs and Modes

This table lists class IDs for all Oracle WebCenter Interaction object types and describes how modes are implemented by each.

Object Type Class ID Mode 1:Open Mode 2:View Mode 3:View Metadata

Administrative Folder

20

Edit

View Contents

View properties

Authentication Source

3

Edit

-

View properties

Community

512

Edit

Preview community

View properties

Community Page

514

Edit

Preview community page

View properties

Community Template

54

Edit

-

View properties

Content Crawler

38

Edit

-

View properties

Content Source

35

Edit

-

View properties

Directory Link

18

Edit

-

View properties

Directory Folder

17

Edit

View contents

View properties

Content Type

37

Edit

-

View properties

Experience Definition

8

Edit

-

View properties

External Operation

58

Edit

-

View properties

Federated Search

46

Edit

-

View properties

Filter

32

Edit

-

View properties

Invitation

44

Edit

-

View properties

Job

256

Edit

-

View properties

Page Template

56

Edit

-

View properties

Portlet

43

Edit

Preview portlet

View properties

Portlet Bundle

55

Edit

-

View properties

Portlet Template

61

Edit

-

View properties

Profile Source

7

Edit

-

View properties

Property

36

Edit

-

-

Remote Server

48

Edit

-

View properties

Site Map Folder

515

Edit

-

View properties

Smart Sort

42

Edit

-

View properties

Snapshot Query

33

Edit

-

View properties

User

1

Edit

View user profile

View properties

User Group

2

Edit

-

View properties

Web Service

47

Edit

-

View properties


Querying Object Properties Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To query the properties of a specific portal object from a remote application, use the instance of IObjectQueryRow that represents the portal object.

To query the properties of a specific portal object, follow the steps below.

  1. Create a session with the portal. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve an Object Manager for the type of object you are querying. For details, see Retrieving Object Managers Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  3. Use the Object Manager to query for the object. For details, see Querying Objects Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

    Note:

    You must include the properties you want to query in the propsToReturn parameter when you query for the object.

  4. Use the instance of IObjectQueryRow that represents the portal object to query for object properties or for custom properties. The code below uses the getValue call to retrieve object property values. The IObjectQueryRow interface also provides methods that cast the requested property to a known data type. Attempting to retrieve a property as an incorrect data type will result in an exception.

    Note:

    If you attempt to retrieve a property that was not specified as a field in the propsToReturn parameter in the query for the object, a PropertyNotRequestException will be thrown.

The following sample code demonstrates how to query the object properties of a specific community. This example prints out most of the standard properties available on community objects, including generic object properties and all community-specific properties (all fields in CommunityProperty).

Java

public static void printCommunityProperties(IObjectQueryRow communityObject) throws
PropertyNotRequestedException
{
    System.out.println("Object ID is " + communityObject.getID());
    System.out.println("Created Date is " + communityObject.getCreated());
    System.out.println("Description is " + communityObject.getDescription());
    System.out.println("Name is " + communityObject.getName());
    System.out.println("Last Modified Date is " + communityObject.getLastModified());
    System.out.println("Owner ID is " + communityObject.getOwner());
    System.out.println("Parent folder ID is " + communityObject.getParentFolderID());
 
    if (communityObject.getObjectClass() == ObjectClass.Community) //only one instance so reference comparison is ok
    {
        System.out.println("Template ID is " + communityObject.getValue(CommunityProperty.CommunityTemplateID));
        System.out.println("Footer ID is " + communityObject.getValue(CommunityProperty.FooterID));
        System.out.println("Header ID is " + communityObject.getValue(CommunityProperty.HeaderID));
        System.out.println("MandatoryTabOrder is " + communityObject.getValue(CommunityProperty.MandatoryTabOrder));
        System.out.println("OwnerInfo is " + communityObject.getValue(CommunityProperty.OwnerInfo));
        System.out.println("SiteMapRoot ID is " + communityObject.getValue(CommunityProperty.SiteMapRootID));
    }
    else System.out.println("Not a community object!");
}

.NET (C#)

public static void PrintCommunityProperties(IObjectQueryRow communityObject)
{
    Console.Out.WriteLine("Object ID is " + communityObject.GetID());
    Console.Out.WriteLine("Created Date is " + communityObject.GetCreated());
    Console.Out.WriteLine("Description is " + communityObject.GetDescription());
    Console.Out.WriteLine("Name is " + communityObject.GetName());
    Console.Out.WriteLine("Last Modified Date is " + communityObject.GetLastModified());
    Console.Out.WriteLine("Owner ID is " + communityObject.GetOwner());
    Console.Out.WriteLine("Parent folder ID is " + communityObject.GetParentFolderID()); 

    if (communityObject.GetObjectClass() == ObjectClass.Community) //only one instance so reference comparison is ok
    {
        Console.Out.WriteLine("Template ID is " + communityObject.GetValue(CommunityProperty.CommunityTemplateID));
        Console.Out.WriteLine("Footer ID is " + communityObject.GetValue(CommunityProperty.FooterID));
        Console.Out.WriteLine("Header ID is " + communityObject.GetValue(CommunityProperty.HeaderID));
        Console.Out.WriteLine("MandatoryTabOrder is "+ communityObject.GetValue(CommunityProperty.MandatoryTabOrder));
        Console.Out.WriteLine("OwnerInfo is " + communityObject.GetValue(CommunityProperty.OwnerInfo));
        Console.Out.WriteLine("SiteMapRoot ID is " + communityObject.GetValue(CommunityProperty.SiteMapRootID));
    }
    else Console.Out.WriteLine ("Not a community object!");
}

.NET (VB)

Public Shared Sub PrintCommunityProperties(ByVal communityObject As IObjectQueryRow) 

    Console.Out.WriteLine("Object ID is " & communityObject.GetID())
    Console.Out.WriteLine("Created Date is " & communityObject.GetCreated())
    Console.Out.WriteLine("Description is " & communityObject.GetDescription())
    Console.Out.WriteLine("Name is " & communityObject.GetName())
    Console.Out.WriteLine("Last Modified Date is " & communityObject.GetLastModified())
    Console.Out.WriteLine("Owner ID is " & communityObject.GetOwner())
    Console.Out.WriteLine("Parent folder ID is " & communityObject.GetParentFolderID()) 

    If communityObject.GetObjectClass() = ObjectClass.Community Then 'only one instance so reference comparison is ok
        Console.Out.WriteLine("Template ID is " & communityObject.GetValue(CommunityProperty.CommunityTemplateID))
        Console.Out.WriteLine("Footer ID is " & communityObject.GetValue(CommunityProperty.FooterID))
        Console.Out.WriteLine("Header ID is " & communityObject.GetValue(CommunityProperty.HeaderID))
        Console.Out.WriteLine("MandatoryTabOrder is " & communityObject.GetValue(CommunityProperty.MandatoryTabOrder))
        Console.Out.WriteLine("OwnerInfo is " & communityObject.GetValue(CommunityProperty.OwnerInfo))
        Console.Out.WriteLine("SiteMapRoot ID is " & communityObject.GetValue(CommunityProperty.SiteMapRootID))
    Else
        Console.Out.WriteLine("Not a community object!")
    End If
EndSub

To query for custom properties of an object, use the IExtendedData interface. This example prints out all the custom properties available on a portal object by enumerating through the available properties and printing out their name and value. To retrieve property IDs, use the standard object manager object querying method with ObjectClass.Property, and use the ID on the object returned to query for the properties you need.

Java

public static void printCustomProperties(IObjectQueryRow portalObject)
    throws PortalException, MalformedURLException, RemoteException
{
    IExtendedData customProperties = portalObject.getExtendedData();
    Enumeration propertyNames = customProperties.getNames();
    String propertyName;
    while(propertyNames.hasMoreElements())
    {
        propertyName = (String)propertyNames.nextElement();
        System.out.println("Property "+ propertyName + " is "+ customProperties.getValue(propertyName));
    }
}

.NET (C#)

public static void PrintCustomProperties(IObjectQueryRow portalObject)
{
    IExtendedData customProperties = portalObject.GetExtendedData(); 
    IEnumerator propertyNames = customProperties.GetNames();
       string propertyName;       
    while(propertyNames.MoveNext())
    {
        propertyName = (string)propertyNames.Current;
        Console.WriteLine("Property " + propertyName + " is " + customProperties.GetValue(propertyName));
    }
}

.NET (VB)

Public Shared Sub PrintCustomProperties(ByVal portalObject As IObjectQueryRow) 
    Dim customProperties As IExtendedData = portalObject.GetExtendedData() 
    Dim propertyNames As IEnumerator = customProperties.GetNames()
    Dim propertyName As String 
    While propertyNames.MoveNext() 
        propertyName = propertyNames.Current
        Console.WriteLine("Property " & propertyName & " is " & customProperties.GetValue(propertyName))

    End While
EndSub
Managing Object Security (ACLs) Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To manipulate object security, use the IACL interface in the Oracle WebCenter Interaction Development Kit (IDK).

The IACL interface provides full access to object security, allowing you to add and remove users from an object's Access Control List. To access an ACL using the PRC, follow the steps below.

  1. Create a session with the portal. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve an object manager for the type of object you are querying. For details, see Retrieving Object Managers Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  3. Use the Object Manager to query for the object and use the instance of IObjectQueryRow that represents the portal object to determine the object ID. For details, see Querying Objects Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs and Querying Object Properties Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  4. Use IACL to query the ACL of the object and enumerate or modify entries. The following sample code demonstrates how to edit the ACL of a specific portal object. The code accesses the ACL, removes an existing entry, adds a new entry, and saves the updated ACL. It then enumerates the users with admin access to the object.

Java

public static void updateACL(IObjectManager objectManager, int objectID)
 throws PortalException, MalformedURLException, RemoteException
{
 IACL acl = objectManager.queryACL(objectID);

 // Remove user with ID 101 from the ACL - will be ignored if the user is not present 
 acl.removeUserEntry(101);

 // Add user with ID 10 to the ACL with Admin access 
 acl.addUserGroupEntry(10, AccessLevel.ADMIN); 

 //store changes to the portal
 objectManager.updateACL(objectID, acl);
 IACLEntry[] entries = acl.entries();
 for (int i = 0; i < entries.length; i++)
 {
 if (entries[i].getAccessLevel().equals(AccessLevel.ADMIN))
 System.out.println(
 entries[i].getPrincipalObjectClass() + " with ID " +
 entries[i].getPrincipalID() + " has admin access");
 }
}

.NET (C#)

public static void UpdateACL(IObjectManager objectManager, int objectID)
{
 IACL acl = objectManager.QueryACL(objectID);

 // Remove user with ID 101 from the ACL - will be ignored if the user is not present 
 acl.RemoveUserEntry(101);

 // Add user with ID 10 to the ACL with Admin access 
 acl.AddUserGroupEntry(10, AccessLevel.ADMIN);

 //store changes to the portal
 objectManager.UpdateACL(objectID, acl);

 IACLEntry[] entries = acl.Entries();

 for (int i = 0; i < entries.Length; i++)
 {
 if (entries[i].GetAccessLevel().equals(AccessLevel.ADMIN))
 Console.WriteLine(
 entries[i].GetPrincipalObjectClass() + " with ID " +
 entries[i].GetPrincipalID() + " has admin access");
 }
}

.NET (VB)

PublicShared Sub UpdateACL(ByVal objectManager As IObjectManager, ByVal objectID
As Integer)

 Dim acl As IACL = objectManager.QueryACL(objectID)

 ' Remove user with ID 101 from the ACL - will be ignored if the user is not present
 acl.RemoveUserEntry(101)

 ' Add user with ID 10 to the ACL with Edit access
 acl.AddUserGroupEntry(10, AccessLevel.EDIT)

 ' store changes to the portal
 objectManager.UpdateACL(objectID, acl)

 Dim entries() As IACLEntry = acl.Entries()
 Dim i As Integer

 For i = 0 To entries.Length
 If entries(i).GetAccessLevel() Is AccessLevel.ADMIN Then
 Console.WriteLine( _
 entries(i).GetPrincipalObjectClass() & " with ID " & _
 entries(i).GetPrincipalID() & " has admin access")
 End If
 Next i

EndSub
Access Control List (ACL) Privileges

Security for portal objects is implemented using Access Control Lists (ACLs) that can be applied to folders or individual objects. The ACL defines the access privileges for portal users and groups.

Users in the Administrators group have full access to allportal objects. Other users can be assigned the following access privileges.

Privilege Description

Read

Allows users or groups to see an object.

Select

Allows users or groups to add an object to other objects. For example, it allows users to add portlets to their My Pages, add users to groups, or associate Remote Servers with Web Services. Object selection lists display only those objects to which you have Select access.

Edit

Allows users or groups to modify an object, including moving or copying an object.

Admin

Allows users or groups full administrative control of an object, including deleting the object or approving it for migration.


Remote Portlet Operations

There are many settings and options that apply only to portlets. In addition to manipulating portlet objects via IObjectManager, the Oracle WebCenter Interaction Development Kit (IDK) supports advanced remote portlet operations. Using the PRC IPortlet* interfaces, you can create and edit portlets and portlet templates, and manage Administrative and CommunityPortlet preferences for a specific portlet instance.

Note:

The PRC IPortlet* interfaces in the Oracle WebCenter Interaction Development Kit (IDK) (com.plumtree.remote.prc) are different from the Oracle WebCenter Interaction Development Kit (IDK) portlet API (com.plumtree.remote.portlet). The interfaces in the portlet API are used to manage communication between a portlet and the portal, while the PRC IPortlet* interfaces provide access to administrative functionality related to the portlet objects stored in the portal.

Creating Portlets and Portlet Templates Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To manipulate portlet and portlet template objects in Oracle WebCenter Interaction Administration from a remote application, use the IPortlet* interfaces in the Oracle WebCenter Interaction Development Kit (IDK).

Creating portlets and portlet templates is very similar; if you create a portlet from a portlet template, it inherits the settings and properties from the template. There is no further relationship between the two objects; changes in a template are not reflected in individual portlet instances made from that template. To create a new portlet or portlet template, follow the steps below.

  1. Create a session with the portal. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve an IPortletManager IPortletTemplateManager object by calling IRemoteSession.getPortletManager or getPortletTemplateManager.

  3. Create the portlet or portlet template as shown in the sample code below.

    1. Create a new method to create a new portlet template or portlet.

    2. Create the portlet template object using the parent folder ID and the web service ID (to create a portlet, you would provide the portlet template ID).

      • There are three ways to retrieve an administrative folder ID: (1) Use PRC search to perform a search for administrative folder objects, (2) Query for an existing portlet or portlet template and use its parent folder ID (available from the IPortlet or IPortletTemplate object), or (3) Let the user select a folder by using a pt:treeLink tag with classID = 20. (There is no Object Manager for administrative folders.) For details on tags, see Adaptive Tags.

      • To query for the web service ID, execute a standard object query using ObjectClass.WebService.

    3. Set the name and description for the portlet template or portlet object.

    4. Save the portlet template or portlet.

    5. Return the ID for the newly created portlet template or portlet.

This example demonstrates how to create a new portlet template based on a web service. To create a new Portlet, replace all instances of "PortletTemplate" with "Portlet" and pass in a Portlet Template ID instead of the Web Service ID.

Java

public static int createPortletTemplate(IPortletTemplateManager portletTemplateManager,
int parentfolderID, int webserviceID)
    throws PortalException, MalformedURLException, RemoteException
{
    IPortletTemplate portletTemplate = portletTemplateManager.createPortletTemplate(parentFolderID, webserviceID);
    portletTemplate.setName("IDK Test Template");
    portletTemplate.setDescription("Created in IDK example");
    int portletTemplateID = portletTemplate.save();
    return portletTemplateID;
}

.NET (C#)

public static int CreatePortletTemplate(IPortletTemplateManager portletTemplateManager,
int parentfolderID, int webserviceID)
{
    IPortletTemplate portletTemplate = portletTemplateManager.CreatePortletTemplate(parentFolderID, webserviceID);
    portletTemplate.SetName("IDK Test Template");
    portletTemplate.SetDescription("Created in IDK example");
    int portletTemplateID = portletTemplate.Save();
    return portletTemplateID;
}

.NET (VB)

Public Shared Function CreatePortletTemplate( _
    ByVal portletTemplateManager As IPortletTemplateManager, ByVal parentfolderID
As Integer, ByVal webserviceID As Integer) As Integer

    Dim portletTemplate As IPortletTemplate = portletTemplateManager.CreatePortletTemplate(parentfolderID,webserviceID)
    portletTemplate.SetName("IDK Test Template");
    portletTemplate.SetDescription("Created in IDK example");
    Dim portletTemplateID As Integer = portletTemplateID = portletTemplate.Save()

    Return portletTemplateID

End Function
Editing Portlets and Portlet Templates Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To modify settings for a Portlet or Portlet Template object from a remote application, use the IPortlet and IPortletTemplate interfaces in the Oracle WebCenter Interaction Development Kit (IDK).

The IPortlet* interfaces allow you to set the name, description and alignment for a portlet or portlet template. You can also edit Administrative settings for a portlet or portlet template, or modify CommunityPortlet settings for a portlet. To edit an existing portlet or portlet template, follow the steps below.

  1. Create a session with the portal. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve an IPortletManager or IPortletTemplateManager object by calling IRemoteSession.getPortletManager or getPortletTemplateManager.

  3. Retrieve an existing portlet or portlet template using IPortletManager. getPortlet or IPortletTemplateManager. getPortletTemplate. (To query for the portlet or portlet template ID, execute a standard object query.)

  4. Edit the portlet or portlet template as shown in the sample code below.

This example demonstrates how to change the alignment, name and description, and edit a administrative setting for a portlet template. To make the same changes to a portlet, replace all instances of "portletTemplate" with "portlet".

Java

public static void editPortletTemplate(IPortletTemplate portletTemplate)
 throws PortalException, MalformedURLException, RemoteException
{
 portletTemplate.setAlignment(Alignment.Narrow);
 portletTemplate.setName("IDK Test Document EDITED"); 
 portletTemplate.setDescription("Edited by IDK example"); 
 portletTemplate.save();
}

public static void addAdminSetting(IPortletTemplate portletTemplate,
String settingName, String settingValue)
 throws PortalException, MalformedURLException, RemoteException
{
 portletTemplate.addAdminSetting(settingName, settingValue);
 portletTemplate.save();
}

.NET (C#)

public static void EditPortletTemplate(IPortletTemplate portletTemplate)
 throws PortalException, MalformedURLException, RemoteException
{
 portletTemplate.SetAlignment(Alignment.Narrow);
 portletTemplate.SetName("IDK Test Document EDITED"); 
 portletTemplate.SetDescription("Edited by IDK example"); 
 portletTemplate.Save();
}

public static void AddAdminSetting(IPortletTemplate portletTemplate,
string settingName, string settingValue)
{
 portletTemplate.AddAdminSetting(settingName, settingValue);
 portletTemplate.Save();
}

.NET (VB)

Public Shared Sub EditWebLinkDocument(ByVal portletTemplateManager As IPortletTemplate)

 portletTemplate.SetAlignment(Alignment.Narrow)
 portletTemplate.SetName("IDK Test Document EDITED")
 portletTemplate.SetDescription("Edited by IDK example")
 portletTemplate.Save()

EndSub

Public Shared Sub AddAdminSetting(ByRef portletTemplateManager As IPortletTemplate, 
ByVal settingName As String, ByVal settingValue As String)

 portletTemplate.AddAdminSetting(settingName, settingValue)
 portletTemplate.Save()

EndSub

Remote Directory Operations

The PRC IDocument* interfaces in the Oracle WebCenter Interaction Development Kit (IDK) allow you to query for documents and document properties, create new documents, and edit the properties for existing documents.

The portal directory displays links to documents in a hierarchical structure of folders and subfolders. These documents can be external or internal web pages, Office documents, or essentially any file of interest. In Oracle WebCenter Interaction, documents are referenced by document ID. File metadata is interpreted based on the Content Type. For details on Content Types, see the Administrator Guide for Oracle WebCenter Interaction or the online help.

The documents displayed in the dirctory are not stored in the portal; the portal database contains only the file properties, including a link to the source file.

Note:

The folders in the portal directory are different from the folders in portal administration. For information on manipulating the portal objects found in administrative folders, see Remote Object Management.

Querying Documents in the Directory Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To query for documents in the portal Directory from a remote application, use the IDocumentManager interface in the Oracle WebCenter Interaction Development Kit (IDK).

To query for documents, follow the steps below. You can also query documents using the PRC Search API; for details, see Remote Search Operations.

  1. Create a session with the portal. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve an IDocumentManager object by calling IRemoteSession.getDocumentManager.

  3. Execute the query, as shown in the sample code below.

    1. Create a new method to print out information about new documents in a folder.

    2. Create a query within the specified folder. There are two ways to retrieve a KD folder ID: (1) Use the PRC search API to perform a search for document folder objects, or (2) Let the user select a folder by using a pt:treeLink tag with classID = 17. (There is no Object Manager for document folders.) For details on tags, Adaptive Tags.

    3. Set up a query filter with the appropriate parameters.

    4. Execute the query.

    5. Loop through the results and print out document details.

This example demonstrates how to query for documents matching specific criteria (new documents) within a specific folder.

Java

public static void printNewDocumentDetails(IDocumentManager documentManager, int
folderID, int daysOld) throws PortalException, RemoteException
{
 IDocumentQuery documentQuery = documentManager.createQuery(folderID);

 // Set up a filter to query only documents up to the specified age
 GregorianCalendar createdAge = new GregorianCalendar();
 createdAge.add(Calendar.DATE, -daysOld);
 QueryFilter ageFilter = new DateQueryFilter(ObjectProperty.Created, Operator.GreaterThan, createdAge.getTime());
 documentQuery.setFilters(new QueryFilter[]{ageFilter});

 IObjectQuery queryResults = documentQuery.execute();
 for (int i = 0; i < queryResults.getRowCount(); i++)
 {
  IObjectQueryRow document = queryResults.getRow(i); 
  //Print out standard properties
  System.out.println("Document: " + document.getName());
  System.out.println("Created: " + document.getCreated());
  System.out.println("Description" + document.getDescription());
  //Print out a Document-specific property
  System.out.println("Located at URL: " + document.getStringValue(DocumentProperty.URL));
 }
}

.NET (C#)

public static void PrintNewDocumentDetails(IDocumentManager documentManager, int
folderID, int daysOld)
{
 IDocumentQuery documentQuery = documentManager.CreateQuery(folderID);

 // Set up a filter to query only documents up to the specified age
 DateTime createdAge = DateTime().AddDays(-daysOld);
 QueryFilter ageFilter = new DateQueryFilter(ObjectProperty.Created, Operator.GreaterThan, createdAge);
 documentQuery.SetFilters(new QueryFilter[]{ageFilter});
 IObjectQuery queryResults = documentQuery.Execute();
 for (int i = 0; i < queryResults.GetRowCount(); i++)
 {
  IObjectQueryRow document = queryResults.GetRow(i); 
  //Print out standard properties
  Console.WriteLine("Document: " + document.GetName());
  Console.WriteLine("Created: " + document.GetCreated());
  Console.WriteLine("Description" + document.GetDescription());
  //Print out a Document-specific property
  Console.WriteLine("Located at URL: " + document.GetStringValue(DocumentProperty.URL));
 }
}

.NET (VB)

Public Shared SubPrintNewDocumentDetails (ByVal documentManager As IDocumentManager,
ByVal folderID As Integer, ByVal daysOld As Integer)

 Dim documentQuery As IDocumentQuery = documentManager.CreateQuery(folderID)

 ' Set up a filter to query only documents up to the specified age
 Dim createdAge As DateTime = New DateTime().AddDays(-daysOld)
 Dim ageFilter As QueryFilter = New DateQueryFilter(ObjectProperty.Created, Operator.GreaterThan,createdAge)
 Dim ageFilters() As QueryFilter = {ageFilter} 'Put the filter into an array 

 documentQuery.SetFilters(ageFilters)

 Dim queryResults As IObjectQuery = documentQuery.Execute()
 Dim i As Integer
 For i = 0 To queryResults.GetRowCount -1 
Dim document As IObjectQueryRow = queryResults.GetRow(i)
'Print out standard properties 
Console.WriteLine("Document: " + document.GetName())
Console.WriteLine("Created: " + document.GetCreated())
Console.WriteLine("Description: " + document.GetDescription())
'Print out a Document-specific property
Console.WriteLine("Located at URL:"+ document.GetStringValue(DocumentProperty.URL))
 Next

EndSub
Creating Documents in the Directory Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To create new remote documents in the portal Directory from a remote application, use the IRemoteDocument and IWebLinkDocument interfaces in the Oracle WebCenter Interaction Development Kit (IDK).

The IWebLinkDocument interface can only be used for HTML pages. To create a remote document of another type, use IRemoteDocument and set the content type. To create a new document, follow the steps below.

  1. Create a session with the portal. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve an IDocumentManager object by calling IRemoteSession.getDocumentManager.

  3. Create the document, as shown in the sample code below.

    1. Create a new method to create a new Web Link document.

    2. Create the document with the specified parameters: the folder ID, Content Source ID, and the URL to the html page.

      • There are two ways to retrieve a folder ID: (1) Use the PRC search API to perform a search for document folder objects, or (2) Let the user select a folder by using a pt:treeLink tag with classID = 17. (There is no Object Manager for document folders.). For details on tags, see Adaptive Tags .

      • This example uses the standard World Wide Web Content Source (ID 104). To query for available Content Sources, execute a standard object query using ObjectClass.DataSource.

    3. Override the document name.

    4. Save the document.

    5. Return the newly created document ID.

This example demonstrates how to create a new Web Link document (HTML page). The implementation of IRemoteDocument is identical to the sample code shown below with one exception: you must set the Content Type. To query for available Content Types, execute a standard object query using ObjectClass.DocumentType.

Java

public static void createWebLinkDocument(IDocumentManager documentManager, int folderID, String URL)
 throws PortalException, MalformedURLException, RemoteException
{
 IWebLinkDocument webLinkDocument =
  documentManager.createWebLinkDocument(folderID,104, URL);// 104 is WWW Content Source
 webLinkDocument.setOverrideName("EDK Test Document"); // overrride intrinsic name
 int documentID = webLinkDocument.save();
 return documentID;
}

.NET (C#)

public static void CreateWebLinkDocument(IDocumentManager documentManager, int folderID, string URL)
 throws PortalException, MalformedURLException, RemoteException
{
 IWebLinkDocument webLinkDocument =
  documentManager.CreateWebLinkDocument(folderID,104, URL);// 104 is WWW Content Source
 webLinkDocument.SetOverrideName("EDK Test Document"); // overrride intrinsic name
 int documentID = webLinkDocument.Save();
 return documentID;
}

.NET (VB)

Public Shared Function CreateWebLinkDocument( _
 ByVal documentManager As IDocumentManager, ByVal folderID As Integer, ByVal URL As String)As Integer

 Dim webLinkDocument As IWebLinkDocument =
  documentManager.CreateWebLinkDocument(folderID,104, URL)' 104 is WWW ContentSource
 webLinkDocument.SetOverrideName("EDK Test Document")' overrride intrinsic name
 Dim documentID As Integer = webLinkDocument.Save()
 Return documentID

EndFunction
Editing Document Properties in the Directory Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To edit properties for existing documents in the portal directory from a remote application, use the IDocumentManager interface in the Oracle WebCenter Interaction Development Kit (IDK).

To edit an existing document, follow the steps below.

  1. Create a session with the portal. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve an IDocumentManager object by calling IRemoteSession.getDocumentManager.

  3. Edit the document, as shown in the sample code below.

This example demonstrates how to edit the document name, title, description and last modified date for an existing Web Link document (HTML page).

Note:

This example uses integers to set properties on the document, in contrast with the ObjectProperty parameters used to retrieve information about general objects. This is because document properties can contain custom properties defined in the portal, for which there are no standard ObjectProperty parameters. To retrieve property IDs to use for this API, use the standard object querying method with ObjectClass.Property, and use the ID on the object returned to query for the properties you need.

Java

public static void editWebLinkDocument(IDocumentManager documentManager, int documentID)
throws PortalException, RemoteException
{
        IDocumentProperties documentProperties = documentManager.queryDocumentProperties(documentID);
        documentProperties.setStringValue(1, "IDK Document EDITED"); // 1 = name
        documentProperties.setStringValue(105, "IDK Document Title EDITED"); // 105 = title
        documentProperties.setStringValue(2, "Edited in IDK example "); // 2 = description
        documentProperties.setDateValue(112, newDate()); // 112 = last modified date
        documentManager.updateDocumentProperties(documentID, documentProperties);
}

.NET (C#)

public static void EditWebLinkDocument(IDocumentManager documentManager, int documentID)
{
        IDocumentProperties documentProperties = documentManager.QueryDocumentProperties(documentID);
        documentProperties.SetStringValue(1, "IDK Document EDITED"); // 1 = name
        documentProperties.SetStringValue(105, "IDK Document Title EDITED"); // 105 = title
        documentProperties.SetStringValue(2, "Edited in IDK example "); // 2 = description
        documentProperties.SetDateValue(112, newDateTime()); // 112 = last modified date
        documentManager.UpdateDocumentProperties(documentID, documentProperties);
}

.NET (VB)

Public Shared Sub EditWebLinkDocument(ByVal documentManager As IDocumentManager,
ByVal folderID As Integer)

Dim documentProperties As IDocumentProperties = documentManager.QueryDocumentProperties(documentID)
        documentProperties.SetStringValue(1, "IDK Document EDITED")' 1 = name
        documentProperties.SetStringValue(105, "IDK Document Title EDITED") ' 105 = title
        documentProperties.SetStringValue(2, "Edited in IDK example ") ' 2 = description
        documentProperties.SetDateValue(112, NewDateTime()) ' 112 = last modified date
        documentManager.UpdateDocumentProperties(documentID, documentProperties)

EndSub

Remote User Operations

The PRC IUserManager and IUserGroupManager interfaces in the Oracle WebCenter Interaction Development Kit (IDK) allow you to leverage the portal's user hierarchy. You can query for the current user's ID and group information, create new groups, and manage group membership.

Portal users are organized into groups and sub-groups. This hierarchy allows administrators to customize the portal display for specific audiences and assign object security for collections of users.

Note:

The PRC IUser* interfaces provide access to administrative functionality related to users in the portal. To access user settings and user profile information, use the methods in the com.plumtree.remote.portlet and com.plumtree.remote.util packages. To manipulate user objects, create an Object Manager of type ObjectClass.User.

Querying Users Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To query for the current user's ID and group information from a remote application, use the IUserManager interface in the Oracle WebCenter Interaction Development Kit (IDK).

The IUserManager interface only provides access to user-specific administrative functionality. To access user settings and user profile information, use the methods in the com.plumtree.remote.util package. To manipulate user objects, create an Object Manager of type ObjectClass.User. For details, see Remote Object Management.To query for the properties for an existing user, follow the steps below. (To retrieve a user ID, you can also execute a standard object query with type ObjectClass.User.)

  1. Create a session with the portal. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve an IUserManager by calling IRemoteSession.getUserManager.

  3. Query the current user's groups, as shown in the sample code below.

    Note:

    The current user is the user initially used to create the PRC session, the user associated with the login token.

This example retrieves the current user's group associations and prints out the group IDs.

Note:

To print out the names of groups, you must look up each group using an IUserGroupManager (IObjectManager with ObjectClass.UserGroup); group names are available on each IObjectQueryRow.

Java

public static void printGroupIDs(IUserManager userManager)
 throws PortalException, MalformedURLException, RemoteException
{
 int[] ids = userManager.getCurrentUserGroups();
 for (int i = 0 ; i < ids.length ; i++)
 {
  System.out.println("Current user belongs to group with ID: " + ids[i]);
 } 
}

.NET (C#)

public static void PrintGroupIDs(IUserManager userManager)
 throws PortalException, MalformedURLException, RemoteException
{
 int[] ids = userManager.GetCurrentUserGroups();
 for (int i = 0 ; i < ids.length ; i++)
 {
  Console.WriteLine("Current user belongs to group with ID: " + ids[i]);
 } 
}

.NET (VB)

Public Shared Sub PrintGroupIDs(ByVal userManager As IUserManager)

 Dim ids() As Integer = userManager.GetCurrentUserGroups()

 Dim i As Integer 
 For i = 0 To ids.Length
  Console.WriteLine("Current user belongs to group with ID: " & ids[i])

EndSub
Creating Groups and Adding Users Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To create new groups and manage group membership from a remote application, use the IUserGroupManager interface in the Oracle WebCenter Interaction Development Kit (IDK).

To create a new group and add a user, follow the steps below.

Note:

The PRC IUserGroupManager interface only provides access to group-specific administrative functionality. To manipulate group objects, create an Object Manager of type ObjectClass.UserGroup.

  1. Create a session with the portal. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve an IUserGroupManager by calling IRemoteSession.getUserGroupManager.

  3. Create a new method to create a group.

  4. Create a new group using the folder ID as shown in the sample code below. There are two ways to retrieve an administrative folder ID: (1) Use PRC search to perform a search for administrative folder objects, or (2) Let the user select a folder by using a pt:treeLink tag with classID = 20. (There is no IObjectManager for administrative folders.) For details on tags, see Adaptive Tags.

  5. Return the group ID for the newly created group.

  6. Create a new method to add a user.

  7. Add the user to the new group, using the group ID returned in the previous method. (To query for an existing group ID, execute a standard object query using ObjectClass.Group.)

Java

public static int createEmptyGroup(IUserGroupManager userGroupManager, int adminFolderID)
 throws PortalException, RemoteException
{
 int newGroupID = userGroupManager.createGroup(
  "IDK Group",
  "Created in IDK example",
  adminFolderID,
  new int[0], //no member users
  new int[0]); //no member groups
 return newGroupID;
}

public static void addUserToGroup(IUserGroupManager userGroupManager, int userIDToAdd,
int newGroupID)
 throws PortalException, RemoteException
{
 userGroupManager.addMemberUsers(newGroupID, new int[]{userIDToAdd});
}

.NET (C#)

public static int CreateEmptyGroup(IUserGroupManager userGroupManager, int adminFolderID)
{
 int newGroupID = userGroupManager.CreateGroup(
  "IDK Group",
  "Created in IDK example",
  adminFolderID,
  new int[0], //no member users
  new int[0]); //no member groups
 return newGroupID;
}

public static void AddUserToGroup(IUserGroupManager userGroupManager, int userIDToAdd,
int newGroupID)
{
 userGroupManager.AddMemberUsers(newGroupID, new int[]{userIDToAdd});
}

.NET (VB)

Public Shared Function CreateEmptyGroup(ByVal userGroupManager As IUserGroupManager,
ByVal adminFolderID As Integer)

 Dim emptyIntegerArray(0) As Integer
 Dim newGroupID As Integer = userGroupManager.CreateGroup( _
  "IDK Group", _
  "Created in IDK example", _
  adminFolderID, _
  emptyIntegerArray, _
  emptyIntegerArray) 'no member users or groups
 Return newGroupID

EndFunction

Public Shared Sub AddUserToGroup( _
 (ByVal userGroupManager As IUserGroupManager, ByVal userIDToAdd As Integer, ByVal newGroupID As Integer)

 Dim singleUserArray() As Integer= {userIDToAdd}

 userGroupManager.AddMemberUsers(newGroupID, singleUserArray)

EndSub

Remote Search Operations

The Oracle WebCenter Interaction Development Kit (IDK) remote search API (com.plumtree.remote.prc.search) provides a generic interface to portal search operations.

Using the PRC search API, you can query document, folder, user and Community objects using a standard request-response model. The API allows you to add multiple constraints and filter searches by location or object type.

Note:

The portal Search Service is a full-text search engine optimized for dealing with text; it should not be used for precise storage of numeric values, such as currency values.

Portal properties are represented as standard fields that can be accessed in search results by name or by iteration. By default, searches return a set of standard properties; you can choose to retrieve additional properties.

For information on remote search services, see Oracle WebCenter Interaction Federated Search Services.

Querying Objects Using the Oracle WebCenter Interaction Development Kit (IDK) Remote Search API

To search for portal objects and documents from a remote application, use the IPortalSearchRequest interface in the Oracle WebCenter Interaction Development Kit (IDK).

To construct a query, follow the steps below.

  1. Create a session with the portal. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve an ISearchFactory from the session by calling IRemoteSession.getSearchFactory.

  3. Create a new IPortalSearchRequest to represent your query.

  4. Create a new method and construct the query, as shown in the sample code that follows.

The sample code below demonstrates how to query for a folder ID by folder name. The folder ID is required to execute other PRC functionality, including creating portlets, documents and groups. This example uses query constraints; for more information, see Using Query Constraints with the Oracle WebCenter Interaction Development Kit (IDK) Remote Search API.

Java

//set the endpoint to the value of web services server
String endpoint = "http://IP-GW-AS08:9080/ptapi/services/QueryInterfaceAPI";
URL url = new URL(endpoint);

//set username and password to log in
//hard-coding the values is only for demo purposes
String username = "Administrator";
String password = "";
IRemoteSession prcSession = RemoteSessionFactory.getExplicitLoginContext(url, username, password);
ISearchFactory searchFactory = prcSession.getSearchFactory();
IPortalSearchRequest searchRequest = searchFactory.createPortalSearchRequest();
public static int getFolderId(IPortalSearchRequest searchRequest, String folderName)
 throws Exception
{
        int folderId = -1;

        //search for the given folder name
        searchRequest.setQuery(folderName);

        // only search for folders
        ObjectClass[] objectTypes = {ObjectClass.DocumentFolder};
        searchRequest.setObjectTypesToSearch(objectTypes);

        ISearchResponse searchResponse = searchRequest.execute();
        ISearchResultSet resultSet = searchResponse.getResultSet();
        int numResults = searchResponse.getReturnedCount();

        if (numResults > 0)
                {
                Enumeration results = resultSet.getResults(); //just get the first element
                IPortalSearchResult result = (IPortalSearchResult) results.nextElement();
                folderId = result.getObjectID();
                }
        returnfolderId;
}

.NET (C#)

//set the endpoint to the value of web services server
String endpoint = "http://IP-GW-AS08:9080/ptapi/services/QueryInterfaceAPI";

//set username and password to log in
//hard-coding the values is only for demo purposes
String username = "Administrator";
String password = "";
IRemoteSession session = RemoteSessionFactory.GetExplicitLoginContext(new System.Uri(endpoint), username, password);
ISearchFactory searchFactory = session.GetSearchFactory();
IPortalSearchRequest searchRequest = searchFactory.CreatePortalSearchRequest();

public static int GetFolderId(IPortalSearchRequest searchRequest, String folderName)
{
        int folderId = -1;

        //search for the given folder name
        searchRequest.SetQuery(folderName);

        // only search for folders
        ObjectClass[] objectTypes = {ObjectClass.DocumentFolder};
        searchRequest.SetObjectTypesToSearch(objectTypes);

        ISearchResponse searchResponse = searchRequest.Execute();
        ISearchResultSet resultSet = searchResponse.GetResultSet();
        int numResults = searchResponse.GetReturnedCount();

        if (numResults > 0)
                {
                Enumeration results = resultSet.GetResults(); //just get the first element
                IPortalSearchResult result = (IPortalSearchResult) results.Current;
                folderId = result.GetObjectID();
                }
        returnfolderId;
}

.NET (VB)

//set the endpoint to the value of web services server
String endpoint = "http://IP-GW-AS08:9080/ptapi/services/QueryInterfaceAPI"

//set username and password to log in
//hard-coding the values is only for demo purposes
String username = "Administrator"
String password = ""

Dim session As IRemoteSession = RemoteSessionFactory.GetExplicitLoginContext(New
System.Uri(endpoint), username, password)
Dim searchFactory As ISearchFactory = session.GetSearchFactory()
Dim searchRequest As IPortalSearchRequest = searchFactory.CreatePortalSearchRequest()

Public Shared Function GetFolderID(ByVal searchRequest As IPortalSearchRequest, ByVal
folderName As String)

        Dim folderID As Int32 = -1
        searchRequest.SetQuery(folderName)

        Dim objectTypes() As ObjectClass = {ObjectClass.DocumentFolder}
        searchRequest.SetObjectTypesToSearch(objectTypes)

        Dim searchResponse As ISearchResponse = searchRequest.Execute()
        Dim resultSet As ISearchResultSet = searchResponse.GetResultSet()
        Dim numResults As Int32 = searchResponse.GetReturnedCount()

        If (numResults > 0) Then

                Dim results As IEnumerator = resultSet.GetResults()
                results.MoveNext()
                Dim result As IPortalSearchResult = DirectCast(results.Current, IPortalSearchResult)
                folderId = result.GetObjectID()

        End If
        Return folderId
End Function
Using Query Constraints with the Oracle WebCenter Interaction Development Kit (IDK) Remote Search API

To limit search results to an object type or filter on a specific object property, use constraints.

Portal properties are represented as standard fields (PortalField, PlumtreeField) that can be accessed in search results by name or by iteration. By default, searches return a set of standard properties; you can choose to retrieve additional properties. To find the property ID, edit the property and note the ObjectID in the query string (for example, &in_hi_ObjectID=206).

This example sets constraints to limit the results to documents that are less than a year old.

Note:

The code below should be executed within a method that can throw a SearchException and a RemoteException.

Java

... 
//add a property field to the search
//SetFieldsToReturn adds fields to the existing default fields
//make the PortalField based on the property ID
int propertyID = 206;
Field[] fieldsToReturn = new Field[] {PortalField.forID(propertyID)};
searchRequest.setFieldsToReturn(fieldsToReturn);

//constrain the results to documents
ObjectClass[] objectClasses = new ObjectClass[] {ObjectClass.Document};
searchRequest.setObjectTypesToSearch(objectClasses);

//return only documents that are less than a year old
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, -1);
Date createdDate = cal.getTime();
IFilterClause filterClause = searchFactory.createAndFilterClause();
filterClause.addStatement(PlumtreeField.CREATED, Operator.GreaterThan, createdDate);
searchRequest.setQuery(searchString, filterClause);

//execute the query and display the results
DisplayResults(searchRequest, propertyID);
...  


.NET (C#)

... 
//add a property field to the search
//SetFieldsToReturn adds fields to the existing default fields
//make the PortalField based on the property ID
int propertyID = 206;
Field[] fieldsToReturn = new Field[] {PortalField.ForID(propertyID)};
searchRequest.SetFieldsToReturn(fieldsToReturn);

//constrain the results to documents
ObjectClass[] objectClasses = new ObjectClass[] {ObjectClass.Document};
searchRequest.SetObjectTypesToSearch(objectClasses);

//return only documents that are less than a year old
DateTime createdDate = DateTime.Today.AddYears(-1);
IFilterClause filterClause = searchFactory.CreateAndFilterClause();
filterClause.AddStatement(PlumtreeField.CREATED, Operator.GreaterThan, createdDate);
searchRequest.SetQuery(searchString, filterClause);

//execute the query and display the results
DisplayResults(searchRequest, propertyID);
...

.NET (VB)

...
'add a property field to the search
'note that SetFieldsToReturn only adds fields to the existing default fields
'make the PortalField based on the property ID
Dim propertyID As Int32 = 206
Dim fieldsToReturn(0) As Field
fieldsToReturn(0) = PortalField.ForID(propertyID)
searchRequest.SetFieldsToReturn(fieldsToReturn)

'constrain the results to documents
Dim objectClasses(0) As ObjectClass
objectClasses(0) = ObjectClass.Document
searchRequest.SetObjectTypesToSearch(objectClasses)

'return only documents that are less than a year old
Dim createdDate As DateTime = DateTime.Today.AddYears(-1)
Dim filterClause As IFilterClause = searchFactory.CreateAndFilterClause()
filterClause.AddStatement(PlumtreeField.CREATED, Operator.GreaterThan, createdDate)
searchRequest.SetQuery(searchString, filterClause)

'execute the query and display the results
DisplayResults(searchRequest, propertyID)
...
Managing Search Results Using the Oracle WebCenter Interaction Development Kit (IDK) Remote Search API

To manage the results returned from a search in a remote application, use the IPortalSearchResult interface.

Oracle WebCenter Interaction Search stores numeric and date fields (properties) as 32-bit floats. This means that any prc.search method that returns the value of a numeric field is potentially subject to roundoff. getFieldAsInt is converted to a float and then converted back to an int. getFieldAsFloat rounds the original value to return it as a float.

This example continues the sample code from Querying Objects Using the Oracle WebCenter Interaction Development Kit (IDK) Remote Search API. The code samples below print out a result summary and display the returned properties.

Note:

To access the additional property referenced in the setFieldsToReturn method of IPortalSearchRequest, this example uses getFieldAsString. This is because the field type is unknown; if you know the type of property being returned, use the appropriate type-specific field (e.g., getFieldAsDate, getFieldAsFloat).

Java

public static void displayResults(IPortalSearchRequest searchRequest, int propertyID)
    throws SearchException, RemoteException
{

        //execute the search
        ISearchResponse searchResponse = searchRequest.execute();

        //get information about the number of results returned
        System.out.println("Total matches is " + searchResponse.getTotalCount());
        System.out.println("First result is " + searchResponse.getFirstResultIndex());
        System.out.println("Number returned is " + searchResponse.getReturnedCount());

        //write out any warnings
        SearchWarning warning = searchResponse.getWarning();
        if (null != warning)
        {
                if (warning.getCode() == (SearchWarning.PROCESSING_TIMED_OUT.getCode()))
                {
                        System.out.println("Search Warning: Timed out when processing search request; a partial search result was returned");
                }
                if (warning.getCode == (SearchWarning.TOO_MANY_WILDCARD_EXPANSIONS.getCode())
                {
                        System.out.println("Search Warning: A wildcard query, such as \"a*\", matched a large number of patterns, only some of which were used for your search.");
                }
        }

        //make the PortalField based on the property ID (from IPortalSearchRequest.SetFieldsToReturn)
        Field propField = PortalField.forID(propertyID);

        //iterate through the results
        ISearchResultSet resultSet = searchResponse.getResultSet();
        IEnumerator results = resultSet.getResults();
        while (results.hasMoreElements())
        {
                System.out.println("--------------------------------------------------");
                IPortalSearchResult result = (IPortalSearchResult) results.nextElement();
                System.out.println("name is " + result.getName());
                System.out.println("class id is " + result.getClassID());
                System.out.println("created is " + result.getCreated());
                System.out.println("excerpt is " + result.getExcerpt());
                System.out.println("last modified is " + result.getLastModified());
                System.out.println("object id is " + result.getObjectID());
                System.out.println("url is " + result.getURL());
                System.out.println("icon url is " + result.getIconURL());
                System.out.println("rank is " + result.getRank());
                //write out the property if the field exists
                Object value = result.getFieldAsObject(propField);
                if (null != value)
                {
                        //use GetFieldAsString because type of field is unknown
                        String propResult = result.GetFieldAsString(propField);
                        System.out.println("property field is " + propResult);
                }
        }
}

.NET (C#)

public static void DisplayResults(IPortalSearchRequest searchRequest, int propertyID)
{

        //execute the search
        ISearchResponse searchResponse = searchRequest.Execute();

        //get information about the number of results returned
        Console.WriteLine("Total matches is " + searchResponse.GetTotalCount());
        Console.WriteLine("First result is " + searchResponse.GetFirstResultIndex());
        Console.WriteLine("Number returned is " + searchResponse.GetReturnedCount());

        //write out any warnings
        SearchWarning warning = searchResponse.GetWarning();
        if (null != warning)
        {
                if (warning.GetCode().Equals(SearchWarning.PROCESSING_TIMED_OUT.GetCode()))
                {
                        Console.WriteLine("Search Warning: Timed out when processing search request; a partial search result was returned");
                }
                if (warning.GetCode().Equals(SearchWarning.TOO_MANY_WILDCARD_EXPANSIONS.GetCode())
                {
                        Console.WriteLine("Search Warning: A wildcard query, such as \"a*\", matched a large number of patterns, only some of which were used for your search.");
                }
        }

        //make the PortalField based on the property ID (from IPortalSearchRequest.SetFieldsToReturn)
        Field propField = PortalField.ForID(propertyID);

        //iterate through the results
        ISearchResultSet resultSet = searchResponse.GetResultSet();
        IEnumerator results = resultSet.GetResults();
        while (results.MoveNext())
        {
                Console.WriteLine("--------------------------------------------------");
                IPortalSearchResult result = (IPortalSearchResult) results.Current;
                Console.WriteLine("name is " + result.GetName());
                Console.WriteLine("class id is " + result.GetClassID());
                Console.WriteLine("created is " + result.GetCreated());
                Console.WriteLine("excerpt is " + result.GetExcerpt());
                Console.WriteLine("last modified is " + result.GetLastModified());
                Console.WriteLine("object id is " + result.GetObjectID());
                Console.WriteLine("url is " + result.GetURL());
                Console.WriteLine("icon url is " + result.GetIconURL());
                Console.WriteLine("rank is " + result.GetRank());
                //write out the property if the field exists
                Object value = result.GetFieldAsObject(propField);
                if (null != value)
                {
                        //use GetFieldAsString because type of field is unknown
                        String propResult = result.GetFieldAsString(propField);
                        Console.WriteLine("property field is " + propResult);
                }
        }
}

.NET (VB)

Public Shared Sub DisplayResults(ByVal searchRequest As IPortalSearchRequest, ByVal
propertyID As Int32)

        //execute the search
        Dim searchResponse As ISearchResponse = searchRequest.Execute()

        'get information about the number of results returned
        Console.WriteLine("Total matches is "& searchResponse.GetTotalCount())
        Console.WriteLine("First result is "& searchResponse.GetFirstResultIndex())
        Console.WriteLine("Number returned is "& searchResponse.GetReturnedCount())

        'write out any warnings 
        Dim warning AsSearchWarning = searchResponse.GetWarning()
        If Notwarning IsNothing Then

                If (warning.GetCode().Equals(SearchWarning.PROCESSING_TIMED_OUT.GetCode())) Then
                        Console.WriteLine("Search Warning: Timed out when processing search request; a partial search result was returned")
        End If

                If (warning.GetCode().Equals(SearchWarning.TOO_MANY_WILDCARD_EXPANSIONS.GetCode()))
                Then
                        Console.WriteLine("Search Warning: A wildcard query, such as a*, matched a large number of patterns, only some of which were used for your search.")
                End If

        End If

        'make the PortalField based on the property ID (from IPortalSearchRequest.SetFieldsToReturn)
        Dim propField As Field = PortalField.ForID(propertyID)

        'iterate through the results
        Dim resultSet AsISearchResultSet = searchResponse.GetResultSet()
        Dim results AsIEnumerator = resultSet.GetResults()
        While(results.MoveNext())

                Console.WriteLine("--------------------------------------------------")
                Dim result As IPortalSearchResult = DirectCast(results.Current, IPortalSearchResult)
                Console.WriteLine("name is " + result.GetName())
                Console.WriteLine("class id is " + result.GetClassID())
                Console.WriteLine("created is " + result.GetCreated())
                Console.WriteLine("excerpt is " + result.GetExcerpt())
                Console.WriteLine("last modified is " + result.GetLastModified())
                Console.WriteLine("object id is " + result.GetObjectID())
                Console.WriteLine("url is " + result.GetURL())
                Console.WriteLine("icon url is " + result.GetIconURL())
                Console.WriteLine("rank is " + result.GetRank())
                'write out the property if the field exists
                Dim value As Object = result.GetFieldAsObject(propField)
                If Not value Is Nothing Then
                        'use GetFieldAsString because type of field is unknown
                        Dim propResult As String = result.GetFieldAsString(propField)
                        Console.WriteLine("property field is " + propResult)
                End If

        End While

End Sub

Starting Portal Jobs Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To start an existing Oracle WebCenter Interaction job from a remote application, use the IJobManager interface in the Oracle WebCenter Interaction Development Kit (IDK).

A job is a collection of related portal operations. Each operation is one task, such as a crawl for documents, an import of users, or one of the system maintenance tasks. The return code from starting a job indicates whether or not the call was successful (whether or not the object is locked). See the Oracle WebCenter Interaction Development Kit (IDK) API documentation for LockStatus for more information on what each return value indicates. To start a portal job, follow the steps below.

  1. Create a session with the portal. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve an IJobManager by calling IRemoteSession.getJobManager.

  3. Query for the objectID of the job. For details, see Querying Object Properties Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  4. Create a new method to start a job and start the job as shown in the code below. It is a best practice to check the return code in the response and print out a description.

    Note:

    The startJob method does not technically start the portal job; it sets the start time for the job to the current time. If there are problems that prevent the job from running once it is rescheduled, they are not accessible from this call.

This example checks to see if the job object is locked. If it is unlocked, the code assumes that the job will start.

Java

public static voidstartJob(IJobManager jobManager, int jobID)
{
 int status = jobManager.startJob(jobID);

 if (status == LockStatus.UNLOCKED) //LockStatus.UNLOCKED = 0
 System.out.println("Job started successfully");
 else
 System.out.println("Job failed to start"); 
}

.NET (C#)

public static voidStartJob(IJobManager jobManager, int jobID)
{
 int status = jobManager.startJob(jobID);

 if (status == LockStatus.Unlocked) //LockStatus.Unlocked = 0
 Console.WriteLine("Job started successfully");
 else
 Console.WriteLine("Job failed to start"); 
}

.NET (VB)

Public Shared SubStartJob ByVal jobManager As IJobManager, ByVal jobID As Integer)

 Dim objectManager As Integer = jobManager.StartJob(jobID)

 If status = LockStatus.UnlockedThen 'LockStatus.Unlocked = 0
 Console.WriteLine "Job started successfully");
 Else
 Console.WriteLine("Job failed to start"); 
 End If
End Sub

Remote Oracle WebCenter Collaboration APIs

The Oracle WebCenter Interaction Development Kit (IDK) remote Collaboration API (com.plumtree.remote.prc.collaboration) provides programmatic access to many of the objects stored within Oracle WebCenter Collaboration. Use this remote programming interface to embed collaborative components and functions into any web application delivered through the Oracle WebCenter Interaction framework.

The PRC Collaboration API can be used to access existing Oracle WebCenter Collaboration objects. Each object interface provides a GetDetailsURL method that returns the URL to the associated detail page in Oracle WebCenter Collaboration. To create a URL to a component, first obtain an instance of the associated object, then call the getDetailsURL method.

For details on remote PRC Collaboration APIs, see the following sections:

Each object interface allows you to determine a user's permissions for a specific Oracle WebCenter Collaboration object in two ways:

  • Get the access level for each role (getAccessLevel).

  • Determine whether a specific action is permitted (isActionAllowed).

For details, see Oracle WebCenter Collaboration Access Levels.

For more details on Oracle WebCenter Collaboration functionality, see the Administrator Guide for Oracle WebCenter Collaboration and the online help.

Remote Oracle WebCenter Collaboration Project Operations

Every Oracle WebCenter Collaboration task, document and discussion is associated with a project; the project must exist before you can create any component objects. Using the PRC Collaboration API in the Oracle WebCenter Interaction Development Kit (IDK), you can query, create and modify projects, and manage project security and subscriptions from a remote application.

Each Oracle WebCenter Collaboration project has its own set of objects and properties that are not shared with other projects. The PRC Collaboration API provides access to the following project functionality:

  • Collaboration Workspace: Create, copy, modify, and delete projects.

  • Subscriptions: Provide users with e-mail notifications when an activity occurs in a project, such as adding a folder or modifying a document.

  • Search: Search projects, and create filters for focused results.

Querying Existing Oracle WebCenter Collaboration Projects Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To search for Oracle WebCenter Collaboration projects by name from a remote application, use the IProjectManager interface in the Oracle WebCenter Interaction Development Kit (IDK).

Results can be filtered in a variety of ways. The IProjectManager query method takes in an IProjectFilter object that allows you to set the following search options:

Search Option Description

Search Text (Name)

Sets the string that will be used to search project names. If you do not set a search string, all projects will be returned. The name search string is case-insensitive by default; all projects will be returned that contain the text using the form *text*.

Maximum Results

Sets the maximum number of results returned. The default is to return all results.

Order-By Fields and Sort Order

Sets the fields to be displayed with an order-by functionality (name or last modified date) and sets the sort order (ascending or descending).

Security

Enables or disables the security filter that applies security to the result set with respect to the user that submitted the query. If the filter is enabled, the query result will only include objects for which the querying user has appropriate permission. The default is false (disabled); all objects matching the query criteria will be returned.

Result Filter: Project Type

Limits the query to those projects for which the current user is a project leader, or extend the search to all projects. For details on project roles, see Managing Oracle WebCenter Collaboration Project Roles Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.


The code samples below are simplified for illustration.

  1. Create a session with the portal. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Query for a project as shown in the code below.

    1. Retrieve an IProjectManager.

    2. Implement IProjectFilter to filter results and define the query.

    3. Execute the search and display results in table format.

Java

...

//perform the search
IProjectManager projectManager = getProjectManager(request, response, out);
IProjectFilter projectFilter = projectManager.createProjectFilter();

//hard-code the max results to 10
projectFilter.setMaximumResults(10);

//set the query
projectFilter.setNameSearchText(searchText);

//execute the search and print out the results
IProject[] projects = projectManager.queryProjects(projectFilter);
if (projects.length > 0)
{
        %>
        <table>
        <tr>
                <td>
                Search Results
                </td>
        </tr>
        <tr>
                <td>
                Project Name
                </td>
                <td>
                Project ID
                </td>
        </tr>
        <%
        for (int i = 0; i < projects.length; i++)
        {
                IProject project = projects[i];
                %>
                <tr>
                        <td>
                        <%out.println(project.getName());%>
                        </td>
                        <td>
                        <%out.println(project.getID());%>
                        </td>
                </tr>
                <%
        }
}
else
{
        %>
        <tr>
                <td colspan="2">
                <%out.println("No projects found using search query of " + searchText);%>
                </td>
        </tr>
        </table>
...

.NET (C#)

...

//perform the search
Plumtree.Remote.PRC.Collaboration.Project.IProjectManager projectManager = GetProjectManager(Request, Response);
Plumtree.Remote.PRC.Collaboration.Project.IProjectFilter projectFilter = projectManager.CreateProjectFilter();

//hard-code the max results to 10
projectFilter.MaximumResults = 10;

//set the query
projectFilter.NameSearchText = searchText;

//execute the search and print out the results
Plumtree.Remote.PRC.Collaboration.Project.IProject[] projects = projectManager.QueryProjects(projectFilter);
if (projects.Length > 0)
{
        %>
        <table>      
        <tr>
                <td>
                Search Results
                </td>
        </tr>
        <tr>
                <td>
                Project Name
                </td>
                <td>
                Project ID
                </td>
        </tr>
        <%
        for (int i = 0; i < projects.Length; i++)
        {
                Plumtree.Remote.PRC.Collaboration.Project.IProject project = projects[i];
                %>
                <tr>
                        <td>
                        <%Response.Write(project.Name);%>
                        </td>
                        <td>
                        <%Response.Write(project.ID);%>
                        </td>
                </tr>
                <%
        }
}
else
{
        Response.Write("No projects found using search query of " + searchText);
}
... 

.NET (VB)

...

'perform the search
dim projectManager as Plumtree.Remote.PRC.Collaboration.Project.IProjectManager = GetProjectManager(Request, Response)
dim projectFilter as Plumtree.Remote.PRC.Collaboration.Project.IProjectFilter = projectManager.CreateProjectFilter()

'hard-code the max results to 10
projectFilter.MaximumResults = 10

'set the query
projectFilter.NameSearchText = searchText

'execute the search and print out the results
dim projects() as Plumtree.Remote.PRC.Collaboration.Project.IProject = projectManager.QueryProjects(projectFilter)
if projects.Length > 0 then
        %>
        <tr>
                <td>
                Search Results
                </td>
        </tr>
        <tr>
                <td>
                Project Name
                </td>
                <td>
                Project ID
                </td>
        </tr>
        <%
        dim i as Integer
        for i = 0 to projects.Length -1
                dim project as Plumtree.Remote.PRC.Collaboration.Project.IProject = projects(i)
                %>
                <tr>
                        <td>
                        <%Response.Write(project.Name) %>
                        </td>
                        <td>
                        <%Response.Write(Cstr(project.ID)) %>
                        </td>
                </tr>
                <%
        next
else
        Response.Write("No projects found using search query of " + searchText)
...
Creating Oracle WebCenter Collaboration Projects Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To create a new Oracle WebCenter Collaboration project from a remote application, use the IProjectManager interface in the Oracle WebCenter Interaction Development Kit (IDK).

The IProjectManager interface provides a factory method for creating new projects that takes in a name and description, and returns an IProject object with a corresponding object ID and associated properties. The sample code below provides a simple example of creating a new project. The IProjectManager interface also provides methods for copying content and metadata from existing collaboration projects. Prior to the call, both the source and target project must be a persisted IProject, and both projects must have a set start date. The user must be a Project Leader and have READ access in both the source and target projects.

Method Description Copies

copyProjectContent

Copies all project content from the source project to the target project. The copied project will be stored permanently. Security is mapped isomorphically from the source project to the target project; if the ProjectMember role in the source project has access level 1 on object X, and object X is copied to object Y, then the ProjectMember role in the target project will have access level 1 on object Y.

  • All document folders

  • All documents

  • All discussions (not messages)

  • All task lists

  • All tasks

copyProjectMetadata

Copies the basic metadata and all IRole objects from the source project to the target project. The copied project will be stored permanently. No store method is required. The old roles in the target project will be overwritten with the copied roles from the source project.

  • Project description

  • All IRole objects

  • Start date information (if the target project's start date is not set and the source project's start date is available)


For details on these methods, see the IDK API documentation.

Note:

Before writing any code, you must prepare a custom development project that references the standard IDK library (idk.jar/idk.dll).

The code samples below implement the following steps:

  1. Initiate a PRC session. This example retrieves a login token using IPortletContext; you can also use IRemoteSession. (For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.)

  2. Get the Project Manager.

  3. Create a project with name and description.

  4. Get the ID for the new project.

Java

<%@page import="com.plumtree.remote.prc.IRemoteSession, com.plumtree.remote.prc.RemoteSessionFactory,
com.plumtree.remote.prc.collaboration.*,com.plumtree.remote.prc.collaboration.project.*,
com.plumtree.remote.portlet.*,java.util.*,java.text.*" %>

<%
//get the project manager
private IProjectManager getProjectManager(HttpServletRequest req, HttpServletResponse
res, JspWriter pout) throws Exception
{

        IProjectManager projectManager = null;
        IPortletContext portletContext = PortletContextFactory.createPortletContext(req, res);
        IPortletRequest portletRequest = portletContext.getRequest();
        String loginToken = portletRequest.getLoginToken();
        if (null == loginToken)
        {
                pout.println("Unable to retrieve the login token. Confirm that the login token has been checked in the Advanced Settings page of the Web Service.");
        }

        //get the remote session
        com.plumtree.remote.prc.IRemoteSession portalSession = portletContext.getRemotePortalSession();

        //get a collab factory and a project manager
        ICollaborationFactory collabFactory = portalSession.getCollaborationFactory();
        projectManager = collabFactory.getProjectManager();

        return projectManager;

}

//create a project and print out the project id
name = (null == name) ? "ExampleProject" : name;
description = (null == description) ? "ExampleProjectDescription" : description;

//create the project
IProjectManager projectManager = getProjectManager(request, response, out);
IProject project = projectManager.createProject(name, description);

//to set additional properties, you must call store() after making changes
//for example:
/*
project.setStatus(ProjectStatus.NOT_STARTED);
project.setStartDate(new Date());
*/

//call store before asking for the ID.
project.store();

//get the new project ID
project.getID()

%>

.NET (C# - Project Page)

<%@ Page language="c#" Codebehind="ProjectSample.aspx.cs" AutoEventWireup="false"
Inherits="WebProjectSample.ProjectSample" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<html>
<body>

//create a project and print out the project id
<%
{
        name = (null == name) ? "ExampleProject" : name;
        description = (null == description) ? "ExampleProjectDescription" : description;

        //create the project
        Plumtree.Remote.PRC.Collaboration.Project.IProjectManager projectManager = GetProjectManager(Request, Response);
        Plumtree.Remote.PRC.Collaboration.Project.IProject project =
        projectManager.CreateProject(name, description);

        //to set additional properties, you must call store() after making changes
        //for example:
        /*
        project.Status = ProjectStatus.NotStarted;
        project.StartDate = new Date();
        */

        //call store before asking for the id.
        project.Store();
}
%>

<table>
        <tr>
                <td>
                <%
                Response.Write("ID of newly created project is " + project.ID);
                %>
                </td>
        </tr>
</table>
</body>
</html>

.NET (C# - Code-Behind Page)

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Plumtree.Remote.PRC;
using Plumtree.Remote.PRC.Collaboration;
using Plumtree.Remote.PRC.Collaboration.Project;
using Plumtree.Remote.Portlet;

namespace WebProjectSample
{
        public class ProjectSample: System.Web.UI.Page
        {
                //name and description for new project
                public String name = "ExampleProject";
                public String description = "ExampleProjectDescription";

                //get the Project Manager
                public IProjectManager GetProjectManager(HttpRequest req, HttpResponse res)
                {
                        IProjectManager projectManager = null;
                        IPortletContext portletContext = PortletContextFactory.CreatePortletContext(req, res);
                        IPortletRequest portletRequest = portletContext.GetRequest();
                        String loginToken = portletRequest.GetLoginToken();
                        if (null == loginToken)
                        {
                                res.Write("Unable to retrieve the login token. Confirm that the login token has been checked in the Advanced Settings page of the Web Service.");
                        }
                        //get the remote session
                        Plumtree.Remote.PRC.IRemoteSession portalSession = portletContext.GetRemotePortalSession();

                        //get a collab factory and a project manager
                        ICollaborationFactory collabFactory = portalSession.GetCollaborationFactory();
                        projectManager = collabFactory.GetProjectManager();
                        return projectManager;
                }
        }
}

.NET (VB - Project Page)

<%@ Page Language="vb" AutoEventWireup="false" Codebehind="ProjectSample.aspx.vb"
Inherits="TestProjectVB.ProjectSample"%>
<!DOCTYPE HTML PUBLIC "-'W3C'DTD HTML 4.0 Transitional'EN" >
<html>
<body>
<%
        'create a project and print out the project id
        name = "ExampleProject"
        description = "ExampleProjectDescription"

        'create the project
        dim projectManager as Plumtree.Remote.PRC.Collaboration.Project.IProjectManager =
        GetProjectManager(Request, Response)
        dim project as Plumtree.Remote.PRC.Collaboration.Project.IProject = projectManager.CreateProject(name, description)

        'to set additional properties, you must call store() after making changes
        'for example:
        'project.Status = ProjectStatus.NotStarted
        'project.StartDate = new Date()

        'call store before asking for the id.
        project.Store()
%>
<table>
        <tr>
                <td>
                <%
                        Response.Write("ID of newly created project is " + Cstr(project.ID))
                %>
                </td>
        </tr>
</table>
</body>
</html>

.NET (VB - Code-Behind Page)

Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Web
Imports System.Web.SessionState
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.HtmlControls
Imports Plumtree.Remote.PRC
Imports Plumtree.Remote.PRC.Collaboration
Imports Plumtree.Remote.PRC.Collaboration.Project
Imports Plumtree.Remote.Portlet 

Public Class ProjectSample
Inherits System.Web.UI.Page

        'get the project manager
        Public Function GetProjectManager(ByVal req As HttpRequest, ByVal res As HttpResponse)
        As IProjectManager
        Dim projectManager As IProjectManager = Nothing
        Dim portletContext As IPortletContext = PortletContextFactory.CreatePortletContext(req, res)
        Dim portletRequest As IPortletRequest = portletContext.GetRequest()
        Dim loginToken As String = portletRequest.GetLoginToken()
        If loginToken Is Nothing Then
                res.Write("Unable to retrieve the login token. Confirm that the login token has been checked in the Advanced Settings page of the Web Service.")
        End If

        'get the remote session
        Dim portalSession As Plumtree.Remote.PRC.IRemoteSession = portletContext.GetRemotePortalSession()

        'get a collab factory and a project manager
        Dim collabFactory As ICollaborationFactory = portalSession.GetCollaborationFactory()
        projectManager = collabFactory.GetProjectManager()

        Return projectManager

End Function

End Class

The IProjectManager also allows you to remove projects. The removeProject method takes in an IProject object and removes the associated project from the system.

Note:

This action cannot be undone. No call to store is required.

Editing Oracle WebCenter Collaboration Project Properties Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To query or modify Oracle WebCenter Collaboration project metadata from a remote application, use the IProject interface in the Oracle WebCenter Interaction Development Kit (IDK).

Each Oracle WebCenter Collaboration project has its own set of objects and properties that are not shared with other projects. The IProject interface provides access to the following project properties:

Property Name Description API Access

ID

The object ID for the current project.

Read Only

Name

The name of the current project.

Read/Write

Description

The description for the current project.

Read/Write

Details

The URL to the details page for the current project.

Read Only

Created Date

The date the current project was created (this information might not be available).

Read Only

Last-Modified Date

The date the current project was last updated (this information might not be available).

Read Only

Owner ID

The user ID of the project owner.

Read Only

Access Level

The permissions for the current user (edit, delete, edit security).

Read Only

Start Date

The start date for the current project.

Read/Write

Status

The status of the current project (not started, 25% complete, 50% complete, 75% complete, or completed).

Read/Write


The IProject interface also allows you to modify user access levels. For details, see Managing Oracle WebCenter Collaboration Project Roles Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.To edit settings for an existing project, follow the steps below.

  1. Create a session with the portal. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve the project ID. For details, see Querying Existing Oracle WebCenter Collaboration Projects Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  3. Edit the properties as shown in the code below.

    1. Retrieve an IProjectManager.

    2. Change the settings. The simplified sample code below changes the name, description, start date, and current status.

    3. Store the settings.

Java

...

//get the project
IProjectManager projectManager = getProjectManager(request, response, out);
IProject project = projectManager.getProject(projectID);

//set the name, description, start date and status
project.setName() = "Updated Name";
project.setDescription() = "Updated description";
project.setStatus(ProjectStatus.TWENTY_FIVE_PERCENT_COMPLETED);

//you must call store to persist changes.
project.store();

...

.NET (C#)

...

//get the project
Plumtree.Remote.PRC.Collaboration.Project.IProjectManager projectManager = GetProjectManager(Request,Response);
IProject project = GetProject(projectID);

//set project metadata
project.Name = "Updated Name";
project.Description = "Updated Description";
project.Status = ProjectStatus.TwentyFivePercentCompleted;

//you must call store to persist changes
project.Store();

...

.NET (VB)

...

'get the project
dim projectManager as Plumtree.Remote.PRC.Collaboration.Project.IProjectManager =
GetProjectManager(Request, Response)
dim project as Plumtree.Remote.PRC.Collaboration.Project.IProject = projectManager.GetProject(-1)

'set project properties
project.Name = "Updated Name"
project.Description = "Updated Description
project.Status = ProjectStatus.TwentyFivePercentCompleted

'you must call store to persist changes
project.Store()

...
Managing Oracle WebCenter Collaboration Project Roles Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To assign users to Oracle WebCenter Collaboration project roles from a remote application, use the IRole interface in the Oracle WebCenter Interaction Development Kit (IDK).

The project role defines the actions that users are able to perform in a given project. The default Collaboration roles are defined as follows:

  • Project Leaders have Admin control over project objects, which includes Read, Write, and Edit permission for all objects, as well as the ability to set role permissions (access levels) for each object.

  • Project Members have Write access to project objects and can participate in the project. This role can create tasks, add documents, attach links, and check files in and out. The access privileges for this role are configured by the Project Leader.

  • Project Guests have Read access to project objects. This role cannot create objects; it is intended for users who simply want to monitor projects but not participate actively. The access privileges for this role are configured by the Project Leader.

The IRole interface allows you to assign users to each project role. Each instance of IRole applies to a specific role within a specific project. You can assign roles to individual users, or to all the users that fulfill a specific role in a community. Once you have defined roles, you can modify the default access levels for a project, or for an individual object in the project (task list, task, folder, document, or discussion). For a list of access levels for Collaboration components, see Oracle WebCenter Collaboration Access Levels.The IProject.getRole method takes in the role type (guest, member or leader) and returns the associated IRole object for the project. To define roles for a project, follow the steps below.

  1. Create a PRC session. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Get the project ID and retrieve the associated object.

  3. Get the role to assign.

  4. Add users to the role.

  5. Set any specific access level restrictions.

    Note:

    You must call store after making any changes or they will not be persisted.

Java

...

//get the project
IProjectManager projectManager = getProjectManager(request, response, out);
IProject project = projectManager.getProject(projectID);

//get the guest role for the project
IRole guestrole = project.getRole(RoleType.GUEST);

//add the guests from a community and an individual user to the role
guestrole.addCommunityMember(CommunityID, COMMUNITY_GUEST);
guestrole.addMember(UserID, USER);

//set the access level for discussions to write
guestrole.setAccessLevel(FunctionalArea.DISCUSSION, AccessLevel.WRITE);

//call store to persist the changes
guestrole.store()

...

.NET (C#)

...

//get the project
Plumtree.Remote.PRC.Collaboration.Project.IProjectManager projectManager = GetProjectManager(Request, Response);
IProject project = GetProject(projectID);

//get the guest role for the project
IRole guestrole = project.GetRole(RoleTypes.Guest);

//add the guests from a community and an individual user to the role
guestrole.AddCommunityMember(CommunityID, CommunityGuest);
guestrole.AddMember(UserID, User);

//set the access level for discussions to write
guestrole.SetAccessLevel(FunctionalAreas.Discussion, AccessLevels.Write);

//call store to persist the changes
guestrole.Store();

...

.NET (VB)

...

//get the project
dim projectManager As Plumtree.Remote.PRC.Collaboration.Project.IProjectManager = GetProjectManager(Request, Response)
dim project As IProject = GetProject(projectID)

//get the guest role for the project
dim guestrole As IRole = project.GetRole(RoleTypes.Guest)

//add the guests from a community and an individual user to the role
guestrole.AddCommunityMember(CommunityID, CommunityGuest)
guestrole.AddMember(UserID, User)

//set the access level for discussions to write
guestrole.SetAccessLevel(FunctionalAreas.Discussion, AccessLevels.Write)

//call store to persist the changes
guestrole.Store()

...
Managing Oracle WebCenter Collaboration Subscriptions Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To provide users with e-mail notifications when an activity occurs in Collaboration, use a subscription. The IProjectManager interface allows you to query current subscriptions, and subscribe and unsubscribe users to Collaboration projects. You can also subscribe users to individual project components.

The IProjectManager allows you to manage subscriptions for a project. To manage subscriptions for individual project components (folders, documents, task lists and discussions), use the associated component manager:

  • The ITaskListManager interface allows you to query current subscriptions, and subscribe and unsubscribe users to collaboration task lists.

  • The IDocumentManager interface allows you to query current subscriptions, and subscribe and unsubscribe users to collaboration folders and documents.

  • The IDiscussionManager interface allows you to query current subscriptions, and subscribe and unsubscribe users to collaboration discussions.

The subscription methods within each interface are identical aside from the type of object passed into the method as a parameter. The sample code below uses the ITaskListManager subscription methods as an example.To subscribe a user to a project or project component, follow the steps below.

  1. Create a PRC session. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Get the project or project component ID and retrieve the associated object manager.

  3. Get the IDs of any users to be subscribed. (To retrieve the users that are currently subscribed, use the getSubscribedUserIDs method.)

  4. Add users to a role if they are not already assigned one.

    Note:

    The users to be subscribed must be in at least GUEST role, and the calling user has to have ADMIN access to the project, or else an exception will be thrown.

  5. Subscribe the users to the project or project component..

Java

...

//userID1 and userID2 are both valid int user IDs that have not been added to any project roles
int[] validUserIDs = new int(userID1, userID2);
IRole guestRole = project.getRole(RoleType.GUEST);

//Add the two users to the GUEST role.
guestRole.addMember(userID1, MemberType.USER);
guestRole.addMember(userID2, MemberType.USER);
guestRole.store();

//Subscribe the two users to the task list.
//No store() needs to be called after the call to subscribeUsers.
tasklistManager.subscribeUsers(tasklist, validUserIDs);

...

.NET (C#)

...

//userID1 and userID2 are both valid int user IDs that have not been added to any project roles
int[] validUserIDs = new int(userID1, userID2);
IRole guestRole = project.GetRole(RoleTypes.Guest);

//Add the two users to the GUEST role
guestRole.AddMember(userID1, MemberTypes.User);
guestRole.AddMember(userID2, MemberTypes.User);
guestRole.Store();

//Subscribe the two users to the project, set notifyForAllCreation setting to true,
//so the two subscribed users will get notified upon all new object creations in this project.
//No Store needs to be called on the project after the call to SubscribeUsers.
projectManager.SubscribeUsers(project, validUserIDs, true);
...

Remote Oracle WebCenter Collaboration Discussion Operations

Oracle WebCenter Collaboration discussions provide a virtual forum where project users hold online conversations on subjects of interest. The PRC Collaboration API in the IDK (com.plumtree.remote.prc.collaboration.discussion ) allows you to manage discussions remotely and embed discussion functionality in your remote applications.

The PRC Collaboration API provides access to the following discussion functionality:

  • Collaboration Workspace: Query, create, approve, and delete discussions and messages.

  • User Assignment: Add users to discussions, and assign moderators who approve messages before they are published.

  • Subscriptions: Provide users with e-mail notifications when a new subject of conversation is started or when a new message is added to an existing subject.

Querying Existing Oracle WebCenter Collaboration Discussions Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To query Oracle WebCenter Collaboration discussions and messages from a remote application, use the IDiscussionManager interface in the Oracle WebCenter Interaction Development Kit (IDK).

The PRC Collaboration API allows you to query existing collaboration discussions and messages. Results can be filtered in a variety of ways.

  • To query for existing discussions in a project, use IDiscussionManager.queryDiscussions using the project instance.

  • To query for existing messages in a discussion, use IDiscussionManager.queryDiscussionMessages using the discussion instance.

  • To query for existing messages in a project, use IDiscussionManager.queryDiscussionMessages using the project instance.

For any of these queries, the IDiscussionFilter/IDiscussionMessageFilter interfaces allow you to set the following search options:

Search Option Description

Maximum Results

Sets the maximum number of results returned. The default is to return all results.

Order-By Fields and Sort Order

Messages only. Sets the fields to be displayed with an order-by functionality, and sets the sort order (ascending or descending). The following fields support the order-by option: created, most recent, last modified, project, replies, and owner.

Security

Enables or disables the security filter that applies security to the result set with respect to the user that submitted the query. If the filter is enabled, the query result will only include objects for which the querying user has appropriate permission. The default is false (disabled); all objects matching the query criteria will be returned.

Result Filter: Status

Messages only. Limits queries by status (approved or unapproved).

Result Filter: Moderator Type

Messages only. Limits queries to those discussions for which the current user is a moderator, or extends the search to all discussions.


To query for discussions and messages, follow the steps below.

  1. Create a PRC session. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Get the project or discussion ID and retrieve the associated object.

  3. Create a new method to query for discussions or messages.

  4. Get the Discussion Manager.

  5. Create a query filter and execute the query as shown in the code samples below.

Java

...

//perform the search
IDiscussionManager discussionManager = getDiscussionManager(request, response);
IDiscussionMessageFilter discussionMessageFilter = discussionManager.createDiscussionMessageFilter();

//disable security checking on the returned objects against the user who performs this query,
//so that all objects will be returned
messageFilter.setRestoreSecurity(false);

//hard-code the max results to 10; setting to 0 will return all results
discussionMessageFilter.setMaximumResults(10);

//search for ALL messages; other options include searching for APPROVED or UNAPPROVED messages
messageFilter.setMessageStatusType(DiscussionMessageStatusFilterType.ALL);

//optionally, set the query orders
//example below sorts returned messages by CREATED date in descending order
DiscussionMessageQueryOrder messageQueryOrder = new DiscussionMessageQueryOrder(DiscussionMessageAttribute.CREATED, false);
messageFilter.setQueryOrders(new DiscussionMessageQueryOrder(messageQueryOrder));

//execute the search and print out the results
IDiscussionMessage[] discussionMessages = discussionManager.queryDiscussionMessages(project,
discussionMessageFilter);
if (discussionMessages.length > 0)
{
        %>
        <tr>
                <td colspan="2">
                Search Results
                </td>
        </tr>
        <tr>
                <td>
                Discussion Message Name- Link to Discussion Message
                </td>
                <td>
                Discussion ID
                </td>
        </tr>
        <%
        for (int i = 0; i < discussionMessages.length; i++)
        {
                IDiscussionMessage discussionMessage = discussionMessages[i];
                int id = discussionMessage.getID();
                name = discussionMessage.getSubject();
                String url = discussionMessage.getDetailsURL();
                %>
        <tr>
                <td>
                <%out.print("<a href=\"" + url + "\">" + name + "</a>");%>
                </td>
                <td>
                <%out.print(id);%>
                </td>
        </tr>

...

.NET (C#)

...

//get the project ID out of session- this should never be null as it is added in the page load event
Plumtree.Remote.PRC.Collaboration.Project.IProject project = (Plumtree.Remote.PRC.Collaboration.Project.IProject)
Session[SESSION_PROJECT_KEY];

//perform the search
Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussionManager discussionManager = GetDiscussionManager(Request, Response);
Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussionMessageFilter discussionMessageFilter = discussionManager.CreateDiscussionMessageFilter();

//disable security checking on the returned objects against the user who performs this query,
//so that all objects will be returned
messageFilter.RestoreSecurity = false;

//hard-code the max results to 10
discussionMessageFilter.MaximumResults = 10;

//search for ALL messages; other options include searching for Approved or Unapproved messages
messageFilter.MessageStatusType = DiscussionMessageStatusFilterTypes.All;

//optionally, set the query orders
//example below sorts returned messages by CREATED date in descending order
DiscussionMessageQueryOrder messageQueryOrder = new DiscussionMessageQueryOrder(DiscussionMessageAttributes.Created, false);
messageFilter.setQueryOrders(new DiscussionMessageQueryOrder(messageQueryOrder));

//execute the search and print out the results
Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussionMessage[] discussionMessages
= discussionManager.QueryDiscussionMessages(project, discussionMessageFilter);
if (discussionMessages.Length > 0)
{
        %>
        <tr>
                <td colspan="2">
                Search Results
                </td>
        </tr>
        <tr>
                <td>
                Discussion Message Name- Link to Discussion Message
                </td>
                <td>
                Discussion ID
                </td>
        </tr>
        <%
        for (int i = 0; i < discussionMessages.Length; i++)
        {
                Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussionMessage discussionMessage = discussionMessages[i];
                int id = discussionMessage.ID;
                String name = discussionMessage.Subject;
                String url = discussionMessage.DetailsURL;
                %>
                <tr>
                        <td>
                        <%Response.Write("<a href=\"" + url + "\">" + name + "</a>");%>
                        </td>
                        <td>
                        <%Response.Write(id);%>
                        </td>
                </tr>
                <%
        }
}
else
{
        Response.Write("No discussion messages found.");
}
...

.NET (VB)

...

'get the project ID out of session- this should never be Nothing as it is added in the page load event
dim project as Plumtree.Remote.PRC.Collaboration.Project.IProject = CType(Session.Item(SESSION_PROJECT_KEY),Plumtree.Remote.PRC.Collaboration.Project.IProject)

'perform the search
dim discussionManager as Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussionManager = GetDiscussionManager(Request, Response)
dim discussionMessageFilter as Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussionMessageFilter = discussionManager.CreateDiscussionMessageFilter()

//disable security checking on the returned objects against the user who performs this query,
//so that all objects will be returned
messageFilter.RestoreSecurity = false

'hard-code the max results to 10; setting to 0 will return all messages
discussionMessageFilter.MaximumResults = 10

//search for ALL messages; other options include searching for Approved, or Unapproved messages
messageFilter.MessageStatusType = DiscussionMessageStatusFilterTypes.All

'optionally, set the query orders
'example below sorts returned messages by CREATED date in descending order
DiscussionMessageQueryOrder messageQueryOrder = new DiscussionMessageQueryOrder(DiscussionMessageAttributes.Created, false)
messageFilter.setQueryOrders(new DiscussionMessageQueryOrder(messageQueryOrder))
 
'execute the search and print out the results
dim discussionMessages() as Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussionMessage
= discussionManager.QueryDiscussionMessages(project, discussionMessageFilter)
if discussionMessages.Length > 0 then
        %>
        <tr>
                <td colspan="2">
                Search Results
                </td>
        </tr>
        <tr>
                <td>
                Discussion Message Name- Link to Discussion Message
                </td>
                <td>
                Discussion Message ID
                </td>
        </tr>
        <%
        dim i as Integer
        for i = 0 to discussionMessages.Length -1
                dim discussionMessage as Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussionMessage = discussionMessages(i)
                dim id as Integer = discussionMessage.ID
                dim name as String = discussionMessage.Subject
                dim url as String = discussionMessage.DetailsURL
                %>
                <tr>
                        <td>
                        <%Response.Write("<a href=""" & url & """>" & name & "</a>") %>
                        </td>
                        <td>
                        <%Response.Write(CStr(id)) %>
                        </td>
                </tr>
                <%
        next
else
        Response.Write("No discussion messages found.")
end if
...
Creating Oracle WebCenter Collaboration Discussions Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To create Oracle WebCenter Collaboration discussions from a remote application, use the IDiscussionManager interface in the Oracle WebCenter Interaction Development Kit (IDK).

The IDiscussionManager interface allows you to create new discussions in an existing project. To create a new discussion, follow the steps below.

  1. Create a PRC session. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve the project ID (a source project must exist before you can create any Collaboration component objects). For details, see Querying Existing Oracle WebCenter Collaboration Projects Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  3. Get the Discussion Manager and create a new discussion as shown in the code samples below.

    Note:

    You must call store after creating a discussion, or it will not be persisted.

Java

...

//create the discussion
IDiscussionManager discussionManager = getDiscussionManager(request, response);
IDiscussion discussion =
discussionManager.createDiscussion(project, name, description);

//call store before asking for the ID
discussion.store();
String url = discussion.getDetailsURL();
int id = discussion.getID();
String detailsUrl = "DiscussionMessage.jsp?" + SESSION_DISCUSSION_KEY + "=" + id;

...

.NET (C#)

...

//get the project ID out of session- this should never be null as it is added in the page load event
Plumtree.Remote.PRC.Collaboration.Project.IProject project = (Plumtree.Remote.PRC.Collaboration.Project.IProject)
Session[SESSION_PROJECT_KEY];

//create the discussion
Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussionManager discussionManager = GetDiscussionManager(Request, Response);
Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussion discussion =
discussionManager.CreateDiscussion(project, name, description);

//call store before asking for the id.
discussion.Store();
String url = discussion.DetailsURL;
int id = discussion.ID;
String detailsUrl = "DiscussionMessage.aspx?" + SESSION_DISCUSSION_KEY + "=" + id;

...

.NET (VB)

...

'get the project ID out of session- this should never be Nothing as it is added in the page load event
dim project as Plumtree.Remote.PRC.Collaboration.Project.IProject = CType(Session.Item(SESSION_PROJECT_KEY),Plumtree.Remote.PRC.Collaboration.Project.IProject)

'create the discussion
dim discussionManager as Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussionManager = GetDiscussionManager(Request, Response)
dim discussion as Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussion = discussionManager.CreateDiscussion(proje ct, name, description)

'call store before asking for the id.
discussion.Store()
dim url as String = discussion.DetailsURL
dim id as Integer = discussion.ID
dim detailsUrl as String = "DiscussionMessage.aspx?" & SESSION_DISCUSSION_KEY & "=" & CStr(id )

...
Creating Oracle WebCenter Collaboration Discussion Messages Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To create Oracle WebCenter Collaboration discussion messages and reply messages from a remote application, use the IDiscussion interface in the Oracle WebCenter Interaction Development Kit (IDK).

Messages and replies are structured in a tree hierarchy. Each message and reply in the hierarchy is represented by an instance of IDiscussionMessage.

  • To create a new message thread in a discussion, use the IDiscussion.createMessage method to create a new IDiscussionMessage object.

  • To create a reply to a message, use the associated IDiscussionMessage.createDiscussionReplyMessage method. This creates a child message (reply) that is also represented by an instance of IDiscussionMessage. You can create a reply at any level in the hierarchy (the root message, the latest message, or a specific message in the thread).

These methods use the same syntax, and take in the subject and body for the message. You can also set the description and approval status when you create a message. To create a new discussion message, follow the steps below.

  1. Create a PRC session. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve the discussion ID and retrieve the discussion instance.

  3. Create a new discussion message as shown in the code samples below.

    Note:

    You must call store after creating a discussion message, or it will not be persisted.

Java

...

//create the discussion message
IDiscussionMessage discussionMessage = discussion.createDiscussionMessage(subject, body);

//call store before asking for the id.
discussionMessage.store();
int id = discussionMessage.getID();
String url = discussionMessage.getDetailsURL();

%>
<tr>
        <td>
        <%
        out.println("<a href=\"" + url + "\">Link to collab message " + id + "</a>");
        %>
        </td>
</tr>

...

.NET (C#)

...

//create the discussion message
Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussionMessage discussionMessage = discussion.CreateDiscussionMessage(subject, body);

//call store before asking for the id.
discussionMessage.Store();
int id = discussionMessage.ID;
String url = discussionMessage.DetailsURL;

%>
<tr>
        <td colspan="6">
        <%
        Response.Write("<a href=\"" + url + "\">Link to collab message " + id + "</a>");
        %>
        </td>
</tr>
...

.NET (VB)

...

'create the discussion message
dim discussionMessage as Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussionMessage = discussion.CreateDiscussionMessage(subject, body)

'call store before asking for the id.
discussionMessage.Store()
dim id as Integer = discussionMessage.ID
dim url as String = discussionMessage.DetailsURL

%>
<tr>
        <td colspan="6">
        <%
        Response.Write("<a href=""" & url & """>Link to collab message " & Cstr(id) & "</a>")
        %>
        </td>
</tr>
...
Editing Oracle WebCenter Collaboration Discussion Properties Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To query and modify Oracle WebCenter Collaboration discussion and message properties from a remote application, use the IDiscussion and IMessage interfaces in the Oracle WebCenter Interaction Development Kit (IDK).

The IDiscussion and IMessage interfaces allow you to change the subject, description, and body of the message before approving it. These interfaces provide access to the following metadata:

Property Name Description API Access

ID

The object ID for the current discussion or message.

Read Only

Name

The name of the current discussion or message.

Read/Write

Subject

Messages only. The subject of the current message

Read/Write

Description

The description for the current discussion or message.

Read/Write

Details

The URL to the details page for the current discussion or message.

Read Only

Created Date

The date the current discussion or message.was created (this information might not be available).

Read Only

Read Only

Last-Modified Date

The date the current discussion or message.was last updated (this information might not be available).

Approval Status

Messages only. The approval status of the message.

Read/Write

Owner ID

The user ID of the message owner.

Read Only

Moderators

Discussions only. The user IDs of the dicussion moderators (if any).

Read/Write

Access Level

The permissions for the defined roles on the current discussion or message (edit, delete, edit security). You can only change permissions for the folder if the default project security is set to false.

Read/Write

Permissions

The permissions for the current user on the current discussion or message (post, attach links, create, edit, edit security, delete).

Read Only

Discussion

Messages only. The discussion that contains the current message.

Read Only

Project

The parent project that contains the current discussion or message.

Read Only

Default Project Security

Whether or not default project security should be applied to the discussion or message. If default project security is enabled, you cannot change the security for the folder.

Read/Write


To modify discussion or message properties, follow the steps below.

  1. Initiate a PRC session. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Get the Discussion Manager.

  3. Get the discussion or message and modify properties as shown in the code samples below.

    Note:

    You must call store after making any changes or they will not be persisted.

Java

...

//get the discussion message
IDiscussionManager discussionManager = getDiscussionManager(request, response);
IDiscussion discussionMessage = discussionManager.getDiscussionMessage(messageID);

//update properties
discussionMessage.setName() = "Updated Name";
discussionMessage.setDescription() = "Updated Description";

//approve the message
discussionMessage.setApproved();

//call store to persist your changes
discussionMessage.store();

...

.NET (C#)

...

//get the discussion message
Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussionManager discussionManager = GetDiscussionManager(Request, Response);
Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussionMessage discussionMessage = discussionManager.GetDiscussionMessage(messageID);

//update properties
discussionMessage.Name = "Updated Name";
discussionMessage.Description = "Updated Description";

//approve the message
discussionMessage.Approved = true;

//call store to persist your changes
discussionMessage.Store();

...

.NET (VB)

...

'get the discussion message
dim discussionManager as Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussionManager = GetDiscussionManager(Request, Response)
dim discussion as Plumtree.Remote.PRC.Collaboration.Discussion.IDiscussionMessage = discussionManager.GetDiscussionMessage(messageID)

'update properties
discussionMessage.Name = "Updated Name"
discussionMessage.Description = "Updated Description"

'approve the message
discussionMessage.Approved = true

'call store to persist your changes
discussionMessage.Store()

...

Remote Oracle WebCenter Collaboration Document and Folder Operations

Documents are any kind of file uploaded to a Oracle WebCenter Collaboration project, including spreadsheets, presentations, images, and PDF files. Documents are organized in a standard folder taxonomy. The PRC Collaboration API in the Oracle WebCenter Interaction Development Kit (IDK) provides full access to documents and folders, allowing you to query, create, or modify these objects.

The PRC Collaboration API provides access to the following document functionality:

  • Collaboration Workspace: Query, create, copy, modify, and delete documents and folders in Collaboration projects.

  • Folder Organization: Create new folders and subfolders, copy existing folders and documents, and insert new documents.

  • Version Control: Check in and check out documents, and query version information. The system retains a history of all versions.

  • Subscriptions: Provide users with e-mail notifications when an activity occurs, such as deleting or modifying a document.

Querying Oracle WebCenter Collaboration Folders and Documents Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To query existing Oracle WebCenter Collaboration documents and folders from a remote application, use the IDocumentManager interface in the Oracle WebCenter Interaction Development Kit (IDK).

The PRC Collaboration API allows you to query existing folders or documents in a given project or folder. Results can be filtered in a variety of ways.

  • To query for existing folders in a parent folder, use IDocumentManager.queryFolders using the parent folder instance. To return all folders in a project, get the top level document folder for the project using getTopLevelFolder, then query the top level document folder for all the document folders it contains.

  • To query for existing documents in a folder, use IDocumentManager.queryDocuments using the folder instance.

  • To query for existing documents in a project, use IDocumentManager.queryDocuments using the project instance.

For any of these queries, the IDocumentFolderFilter/IDocumentFilter interfaces allow you to set the following search options:

Search Option Description

Maximum Results

Sets the maximum number of results returned. The default is to return all results.

Order-By Fields and Sort Order

Sets the fields to be displayed with an order-by functionality (name or last modified date), and sets the sort order (ascending or descending). The following fields support the order-by option for documents: name, author, project, parent folder, content type, size (bytes), timestamp, last modified, last check in user, check out user.

Security

Enables or disables the security filter that applies security to the result set with respect to the user that submitted the query. If the filter is enabled, the query result will only include objects for which the querying user has appropriate permission. The default is false (disabled); all objects matching the query criteria will be returned.

Result Filter: Checkin Status

Documents only. Limits queries by document status (checked in or checked out).


To query for folders or documents in a folder or project, follow the steps below.

  1. Create a PRC session. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Get the Document Manager.

  3. Get the ID of the parent folder or project. To query all the folders in a project, get the top level document folder for the project using getTopLevelFolder.

  4. Create a query filter and execute the query as shown in the code samples below.

The examples below query a project for all checked-out documents and order results by size and then last-modified date.

Java

...
//create a query filter
IDocumentFilter filter = manager.createDocumentFilter();

//set to only search for checked-out documents
filter.filterType = DocumentFilterTypes.checkedOutByCurrentUser;

//order results by size, then last modified date
DocumentQueryOrder sizeOrder = new DocumentQueryOrder(DocumentFolderAttribute.NUMBYTES, true);
DocumentQueryOrder lastModifiedOrder = new DocumentQueryOrder(DocumentFolderAttribute.LASTMODIFIED, true);
DocumentQueryOrder[] orders = new DocumentQueryOrder(sizeOrder, lastModifiedOrder);
filter.setQueryOrders(orders);

//perform the query
IDocument[] foundDocuments = manager.queryDocuments(project, filter);
...

.NET (C#)

...
//create a query filter
IDocumentFilter filter = documentManager.CreateDocumentFilter();

//set to only search for checked-out documents
filter.FilterType = DocumentFilterTypes.CheckedOutByCurrentUser;

//order results by size, then last modified date
DocumentQueryOrder sizeOrder = new DocumentQueryOrder(DocumentAttributes.NumBytes, true);
DocumentQueryOrder lastModifiedOrder = new DocumentQueryOrder(DocumentAttributes.LastModified, true);
DocumentQueryOrder[] orders = new DocumentQueryOrder(sizeOrder, lastModifiedOrder);
filter.QueryOrders = orders;

//perform query
IDocument[] foundDocuments = documentManager.QueryDocuments(project, filter);
...

.NET (VB)

...
'create a query filter
dim filter As IDocumentFilter = documentManager.CreateDocumentFilter()

'set to only search for checked-out documents
filter.FilterType = DocumentFilterTypes.CheckedOutByCurrentUser;

'order results by size, then last modified date
dim sizeOrder As DocumentQueryOrder = new DocumentQueryOrder(DocumentAttributes.NumBytes, true)
dim lastModifiedOrder As DocumentQueryOrder = new DocumentQueryOrder(DocumentAttributes.LastModified, true)
dim orders As DocumentQueryOrder[] = new DocumentQueryOrder(sizeOrder, lastModifiedOrder)
filter.QueryOrders = orders

'perform query
dim foundDocuments As IDocument[] = documentManager.QueryDocuments(project, filter)
...
Managing Oracle WebCenter Collaboration Documents Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To check in and check out Oracle WebCenter Collaboration documents from a remote application, use the IDocumentManager interface in the Oracle WebCenter Interaction Development Kit (IDK).

Only one person can check out a document at a time. To check out a document, the current user must have at least WRITE access to the document.Checking in a document saves a new version of the document, increments the current version number, and makes a new entry in the document's history. When you check in a document, you can set the following properties:

Property Description

Check in comment

Required. A string that will be added as the first check in comment for the new document.

Input stream

Required. An InputStream from which the contents of the new document can be read.

Language

The ISO 639-1 language code for the content in the document (for example, en for english). If null, the language is set to that of the current user.

Keep checked out

If set to true, the document will be checked in and automatically checked out again. The default is false.


To check out or check in documents, follow the steps below.

  1. Initiate a PRC session. This example retrieves a login token using the IPortletContext; you can also use IRemoteSession. (For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.)

  2. Get the Document Manager.

  3. Get the document ID and retrieve the document.

    • To check out the document, pass in the document instance.

    • To check in the document, pass in the document instance, the check in comment, the input stream, language (optional) and whether or not the file should be checked out again as shown in the code samples below.

Java

...
IRemoteSession remoteSession = portletContext.getRemotePortalSession();
IDocumentManager documentManager = remoteSession.getCollaborationFactory().getDocumentManager();

//get the document
IDocument checkedOutDocument = documentManager.getDocument(documentID);

//Open an inputstream for the document contents - this can be any InputStream
InputStream fileInputStream = new FileInputStream("c:\\myNewDocument.doc");

//Check in the new version
documentManager.checkInDocument(checkedOutDocument, "updated version of the document", fileInputStream, "en", false);
...


.NET (C#)

...
remoteSession = portletContext.GetRemotePortalSession();
documentManager = remoteSession.GetCollaborationFactory().GetDocumentManager();

//get the document
IDocument checkedOutDocument = documentManager.GetDocument(documentID);

//open an inputstream for the document contents - this can be any readable Stream
Stream fileInputStream = File.OpenRead("c:\\MyNewDocument.doc");

//check in the new version
documentManager.CheckInDocument(checkedOutDocument, "updated version of the document", fileInputStream, "en", false);
...

.NET (VB)

...
dim documentManager As IDocumentManager
dim remoteSession As Plumtree.Remote.PRC.IRemoteSession
remoteSession = portletContext.GetRemotePortalSession()
documentManager = remoteSession.GetCollaborationFactory().GetDocumentManager()

'get the document
IDocument checkedOutDocument = documentManager.GetDocument(documentID)

'Open an inputstream for the document contents - this can be any readable Stream
dim fileInputStream As Stream = File.OpenRead("c:\\MyNewDocument.doc")

'Check in the new version
documentManager.CheckInDocument(checkedOutDocument, "updated version of the document", fileInputStream, "en", false)
...
Creating Oracle WebCenter Collaboration Folders and Documents Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To create new Oracle WebCenter Collaboration folders and documents from a remote application, use the IDocumentManager interface in the Oracle WebCenter Interaction Development Kit (IDK).

The IDocumentManager interface allows you to create new folders, subfolders and documents. The IDocumentManager interface also allows you to copy existing documents and folders to target folders in any project.

  • To create a new folder, create it and insert it into an existing folder. The insertNewFolder method takes in the target parent folder, the new folder, and an optional third parameter to set the new folder to inherit security from the parent folder.

  • To create a new document, create it and insert it into an existing folder. The parameters in the insertNewDocument method allow you to set the following properties:

    Property Description

    Check in comment

    Required. A string that will be added as the first check in comment for the new document.

    Input stream

    Required. An InputStream from which the contents of the new document can be read.

    Language

    The ISO 639-1 language code for the content in the document (for example, "en" for english). If null, the language is set to that of the current user.

    Inherit security

    If set to true, the new document will inherit security from the parent folder.


    Note:

    If there is already a document or subfolder in the parent folder with the same name as a supplied document, the name of the newly inserted document will be changed. For example, if a document is submitted with a name of report.doc and a file with this name already exists, the name of the new file will be changed to report_1.doc (or report_2.doc if report_1.doc also already exists). You can check the name of the returned IDocument to see if it differs from the name in the document parameter.

  • To copy a folder or document, use the IDocumentManager.copyToFolder method and pass in the source folder, target folder, and document(s) or folder(s) to copy.

  • To create a new folder or document, follow the steps below.

  1. Create a PRC session. This example retrieves a login token using the IPortletContext; you can also use IRemoteSession. (For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.)

  2. Get the IDocumentManager.

  3. Get the ID of the parent folder. To insert a folder or document at the root level, get the top level document folder for the project using getTopLevelFolder.

  4. Create the folder or document and insert it in the parent folder as shown in the code samples below.

These examples create a new folder in the top level folder and a new document in the new folder.

Java

...
IRemoteSession remoteSession = portletContext.getRemotePortalSession();
IDocumentManager documentManager = remoteSession.getCollaborationFactory().getDocumentManager();

//get top level folder in project to create new root folder
topLevelFolder = documentManager.getTopLevelFolder(containingProject);

//create a new folder
newFolder = documentManager.createNewFolder("Example Name", "Example Description");

//insert the folder, set to inherit security from the top level folder
IDocumentFolder storedFolder = documentManager.insertNewFolder(topLevelFolder, newFolder, true);

//create the document
IDocument newDocument = documentManager.createNewDocument("Example Document Name", "Example Document Description");

//set additional properties before inserting the document or they will not be persisted
newDocument.setAuthor("joe bloggs");
newDocument.setContentType("text/vnd.ms-word");

//open an inputstream for the document contents
InputStream fileInputStream = new FileInputStream("c:\\report.doc");

//insert the document, inheriting the containing folder's security
documentManager.insertNewDocument(storedFolder, newDocument, "initial check-in", fileInputStream, "en", true);
...

.NET (C#)

...
remoteSession = portletContext.GetRemotePortalSession();
documentManager = remoteSession.GetCollaborationFactory().GetDocumentManager();

//get the top level folder for the project to create a root folder
IDocumentFolder rootFolder = documentManager.GetTopLevelFolder(project);

//create a new folder
IDocumentFolder newFolder = documentManager.CreateDocumentFolder("Example Name", "Example Description");

//insert the new folder into the top level folder, set to inherit security 
IDocumentFolder storedFolder = documentManager.InsertNewFolder(topLevelFolder, newFolder,true);

//create the document
IDocument newDocument = documentManager.CreateNewDocument("Example Document Name", "Example Document Description");

//set additional properties before inserting the document or they will not be persisted
newDocument.Author = "joe bloggs";
newDocument.ContentType = "text/vnd.ms-word";

//open a Stream for the document contents
Stream fileInputStream = new FileStream("c:\\report.doc");

//insert the document, set to inherit security from the parent folder
documentManager.InsertNewDocument(storedFolder, newDocument, "initial check-in", fileInputStream, "en", true);
...

.NET (VB)

...
dim documentManager As IDocumentManager
dim remoteSession As Plumtree.Remote.PRC.IRemoteSession
remoteSession = portletContext.GetRemotePortalSession()
documentManager = remoteSession.GetCollaborationFactory().GetDocumentManager()

'get the top level folder for the project to create a root folder
dim rootFolder As IDocumentFolder = documentManager.GetTopLevelFolder(project)

'create the new folder
dim newFolder As IDocumentFolder = documentManager.CreateDocumentFolder("Example Name", "Example Description")

'Insert the new folder into the top level folder, set to inherit security 
dim storedFolder As IDocumentFolder = documentManager.InsertNewFolder(topLevelFolder, newFolder, true)

'create the document
dim newDocument As IDocument = documentManager.CreateNewDocument("Example Document Name", "Example Document Description")

'set additional properties before inserting the document or they will not be persisted
newDocument.Author = "joe bloggs"
newDocument.ContentType = "text/vnd.ms-word"

'open a Stream for the document contents
dim fileInputStream as Stream = new FileStream("c:\\report.doc")

'insert the document, set to inherit security from the parent folder
documentManager.InsertNewDocument(storedFolder, newDocument, "initial check-in", fileInputStream, "en", true)
...
Editing Oracle WebCenter Collaboration Folder and Document Properties Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To query and modify Oracle WebCenter Collaboration folder and document properties from a remote application, use the IDocumentFolder and IDocument interfaces in the Oracle WebCenter Interaction Development Kit (IDK).

The IDocumentFolder and IDocument interfaces allow you to update metadata and manipulate security settings. These interfaces provide access to the following metadata:

Property Name Description API Access

ID

The object ID for the current folder or document.

Read Only

Read/Write

Name

The name of the current folder or document.

Description

The description for the current folder or document.

Read/Write

Details

The URL to the details page for the current folder or document.

Read Only

Content Type

Documents only. The Content Type of the current document.

Read/Write

Content URL

The URL at which the document content can be downloaded.

Read Only

Path

The path to the document (as a string).

Read Only

Author

Documents only. The user ID of the author of the current document.

Read Only

Created Date

The date the current folder or document was created (this information might not be available).

Read Only

Read Only

Last-Modified Date

The date the current folder or document was last updated (this information might not be available).

Checked-Out Date

The date the document was last checked out. (Returns null if the document is not checked out.)

Read Only

Owner

The user ID of the folder or document owner.

Read Only

Access Level

The permissions for the defined roles on the current folder or document (edit, delete, edit security). You can only change permissions for the folder if the default project security is set to false.

Read/Write

Permissions

Documents only. The permissions for the current user on the current document (check out, attach links, copy, edit, edit security, delete).

Read Only

Parent Folder

The parent folder that contains the current folder or document.

Read Only

Read Only

Project

The parent project that contains the current folder or document.

Default Project Security

Whether or not default project security should be applied to the folder or document. If default project security is enabled, you cannot change the security for the folder.

Read/Write


To modify folder or document properties, follow the steps below.

  1. Initiate a PRC session. This example retrieves a login token using the IPortletContext; you can also use IRemoteSession. (For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.)

  2. Get the Document Manager.

  3. Get the folder or document and modify properties as shown in the code samples below.

    Note:

    You must call store after making any changes or they will not be persisted.

Java

...
IRemoteSession remoteSession = portletContext.getRemotePortalSession();
IDocumentManager documentManager = remoteSession.getCollaborationFactory().getDocumentManager();

//get the document
IDocument document = documentManager.getDocument(documentID);

//set properties
document.setName() = "Updated Name";
document.setDescription() = "Updated Description ";

//update security
document.setAccessLevel(RoleType.MEMBER, AccessLevel.WRITE);

//call store to persist your changes
document.store();
...

.NET (C#)

...
remoteSession = portletContext.GetRemotePortalSession();
documentManager = remoteSession.GetCollaborationFactory().GetDocumentManager();

//get the document
IDocument document = documentManager.GetDocument(documentID);

//set properties
document.Name = "Updated Name";
document.Description = "Updated Description";

//update security
document.SetAccessLevel(RoleTypes.Member, AccessLevels.Write);

//call store to persist your changes
document.Store();
...

.NET (VB)

...
dim documentManager As IDocumentManager
dim remoteSession As Plumtree.Remote.PRC.IRemoteSession
remoteSession = portletContext.GetRemotePortalSession()
documentManager = remoteSession.GetCollaborationFactory().GetDocumentManager()

'get the document
dim document As IDocument = documentManager.GetDocument(documentID)

'set properties 
document.Name = "Updated Name"
document.Description = "Updated Description"

'update security
document.SetAccessLevel(RoleTypes.Member, AccessLevels.Write)

//call store to persist your changes
document.Store()
...

Remote Oracle WebCenter Collaboration Task Operations

Oracle WebCenter Collaboration tasks can be used to track workflow and process in a wide range of applications. Using the PRC Collaboration API in the Oracle WebCenter Interaction Development Kit (IDK), you can query, create, and modify tasks and task lists, as well as manage workflow and task dependencies.

Oracle WebCenter Collaboration tasks define work that needs to be done, who will do it, when it should be completed, and how it relates to other tasks. Individual tasks can contain up to three levels of subtasks, and you can set dependencies between tasks in the same project. Task lists serve as structured to-do lists of tasks to be completed for a project or a phase of a project. Security for tasks is implemented through the associated task list.

The PRC Collaboration API provides access to the following task functionality:

  • Collaboration Workspace: Query, create, copy, modify, and delete task lists, tasks and subtasks.

  • Workflow: Add subtasks and task dependencies, assign users, and track task status and risk.

  • Subscriptions: Provide users with e-mail notifications when an event occurs, such as when new task list is created or a task is assigned.

Querying Oracle WebCenter Collaboration Tasks and Task Lists Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To query Oracle WebCenter Collaboration task lists, tasks and subtasks from a remote application, use the ITaskListManager interface in the Oracle WebCenter Interaction Development Kit (IDK).

The PRC Collaboration API allows you to query existing collaboration tasks and task lists. Results can be filtered in a variety of ways.

  • To query for task lists in a given project, use ITaskListManager.queryTaskLists using the project instance.

  • To query for tasks in a given project, use ITaskListManager.queryTasks using the project instance.

  • To query for tasks in a given task list, use ITaskListManager.queryTasks using the task list instance.

For any of these queries, the ITaskListFilter/ITaskFilter interfaces allow you to set the following search options:

Search Option Description

Maximum Results

Sets the maximum number of results returned. The default is to return all results.

Order-By Fields and Sort Order

Sets the fields to be displayed with an order-by functionality, and sets the sort order (ascending or descending). The following fields support the order-by option: name, start date, end date, status, assigned to (tasks and subtasks only) and order (location of the task or subtask in the hierarchy - tasks and subtasks only).

Security

Enables or disables the security filter that applies security to the result set with respect to the user that submitted the query. If the filter is enabled, the query result will only include objects for which the querying user has appropriate permission. The default is false (disabled); all objects matching the query criteria will be returned.

Result Filter: Status

Limits queries by status (completed, pending or overdue).

Result Filter: User

Tasks and subtasks only. Limits queries to those tasks assigned to a specific user.

Result Filter: Assignment

Tasks and subtasks only. Limits queries to unassigned tasks.


To query for task lists, tasks and subtasks, follow the steps below.

  1. Create a PRC session. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Get the project or task list ID and retrieve the associated object.

  3. Create a new method to query for task lists or tasks.

  4. Get the Task List Manager.

  5. Create a query filter as shown in the code samples below.

  6. Execute the query.

The following examples query for task lists in a project. To create a query filter for tasks, replace ITaskListFilter with ITaskFilter.

Java

...
ITaskListFilter taskListFilter = tasklistManager.createTaskListFilter();

//set the query to search for all task lists
//options can be set to search for task lists that contain only pending tasks,
//completed tasks, or overdue tasks
taskListFilter.setCompletionType(TaskListCompletionFilterType.ALL);

//limit the return results to be 10
taskListFilter.setMaximumResults(10);

//disable security checking against the user who performs the query,
//so that all objects will be returned
taskListFilter.setRestoreSecurity(false);

//use TaskListQueryOrder to sort the query result by NAME in ascending order
TaskListQueryOrder taskListQueryOrder = new TaskListQueryOrder(TaskListAttribute.NAME, true);
taskListFilter.setQueryOrders(new TaskListQueryOrder(taskListQueryOrder));

//an array of ITaskList objects are returned from queryTaskLists(); 
// if no result is retrieved, a zero-length array will be returned
ITaskList[] retrievedTaskLists = tasklistManager.queryTaskLists(project, taskListFilter);
...

.NET (C#)

...
ITaskListFilter taskListFilter = tasklistManager.CreateTaskListFilter();

//set the query to search for all task list
//options can be set to search for task lists that contain only pending tasks,
//completed tasks, or overdue tasks. 
taskListFilter.CompletionType = TaskListCompletionFilterTypes.All;

//limit the return results to be 10
taskListFilter.MaximumResults = 10;

//disable security checking against the user who performs the query,
//so that all objects will be returned
taskListFilter.RestoreSecurity = false;

//use TaskListQueryOrder to sort the query result by NAME in ascending order
TaskListQueryOrder taskListQueryOrder = new TaskListQueryOrder(TaskListAttributes.Name, true);
taskListFilter.QueryOrders = new TaskListQueryOrder(taskListQueryOrder);

//an array of ITaskList objects are returned from queryTaskLists(); 
//if no result is retrieved, a zero-length array will be returned
ITaskList[] retrievedTaskLists = tasklistManager.QueryTaskLists(project, taskListFilter);
...

.NET (VB)

...
dim taskListFilter As ITaskListFilter = tasklistManager.CreateTaskListFilter();

'set the query to search for all task list
'options can be set to search for task lists that contain only pending tasks,
'completed tasks, or overdue tasks. 
taskListFilter.CompletionType = TaskListCompletionFilterTypes.All

'limit the return results to be 10
taskListFilter.MaximumResults = 10

'disable security checking against the user who performs the query,
'so that all objects will be returned
taskListFilter.RestoreSecurity = false

'use TaskListQueryOrder to sort the query result by NAME in ascending order
dim taskListQueryOrder As TaskListQueryOrder = new TaskListQueryOrder(TaskListAttributes.Name, true)
taskListFilter.QueryOrders(0) = taskListQueryOrder

'an array of ITaskList objects are returned from queryTaskLists()
'if no result is retrieved, a zero-length array will be returned
dim retrievedTaskLists() As ITaskList = tasklistManager.QueryTaskLists(project, taskListFilter)
...
Creating Oracle WebCenter Collaboration Tasks and Task Lists Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To create new Oracle WebCenter Collaboration task lists, tasks and subtasks from a remote application, use the ITask* interfaces in the Oracle WebCenter Interaction Development Kit (IDK).

The ITaskListManager.createTaskList method takes in a project ID, name and description, and returns an ITaskList object with a corresponding object ID and associated properties. In some cases, an existing task list can be used as a template. The ITaskListManager.copyTaskLists method allows you to copy existing task lists from one project to another. Once a task list is created, you can create tasks and subtasks. The ITaskList.createTask method takes in a name, description, start date and end date, and returns an ITask object with a corresponding object ID and associated properties. The ITask.createSubTask method allows you to create subtasks using the same parameters. Subtasks are represented by an instance of ITask. To create a new task list, follow the steps below.

  1. Create a session. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Retrieve the project ID (a source project must exist before you can create any Collaboration component objects). For details, see Querying Existing Oracle WebCenter Collaboration Projects Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  3. Create a new task list as shown in the code samples below.

  4. Use the new task list to add tasks and subtasks as shown in the code samples below.

Java

...
ICollaborationFactory collabFactory = portalSession.getCollaborationFactory();
ITaskListManager tasklistManager = collabFactory.getTaskListManager();

//create the task list
ITaskList tasklist = tasklistManager.createTaskList(project, name, description);

//call store() to persist the task list
tasklist.store();

//get the details URL and ID for the new task list
string url = tasklist.getDetailsURL();
int id = tasklist.getID();

//create the task
ITask task = tasklist.createTask(taskname, taskdescription, startTime, endTime);

//call store to persist the task
task.store();
......

.NET (C#)

...
//get the project ID out of session- this should never be null as it is added in the page load event
Plumtree.Remote.PRC.Collaboration.Project.IProject project = (Plumtree.Remote.PRC.Collaboration.Project.IProject)
Session[SESSION_PROJECT_KEY];

//create the task list
ITaskList tasklist = tasklistManager.CreateTaskList(project, name, description);

//call Store() to persist the task list
tasklist.Store();

//create the task
ITask task = tasklist.CreateTask(taskname, taskdescription, startTime, endTime);

//call Store() to persist the task
task.Store();
...

.NET (VB)

...
name = "ExampleTaskList"
description = "ExampleTaskListDescription"

'get the project ID out of session- this should never be Nothing as it is added in the page load event
dim project as Plumtree.Remote.PRC.Collaboration.Project.IProject = CType(Session.Item(SESSION_PROJECT_KEY),Plumtree.Remote.PRC.Collaboration.Project.IProject)

'create the task list
Dim tasklist As ITaskList = tasklistManager.CreateTaskList(project, name, description)

'call Store() to persist the task list
tasklist.Store()

'create the task
Dim tasklist As ITaskList = tasklistManager.CreateTaskList(project, name, description)

'call Store() to persist the task
task.Store()
...
Editing Oracle WebCenter Collaboration Task and Task List Properties Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To query and modify Oracle WebCenter Collaboration task list and task properties from a remote application, use the ITaskList and ITask interfaces in the Oracle WebCenter Interaction Development Kit (IDK).

The ITaskList interface allows you to query and update metadata and manipulate security settings for task lists. The ITask interface allows you to assign users and manipulate key settings for individual tasks, including start date, due date, status and risk. These interfaces provide access to the following metadata:

Property Name Description API Access

ID

The object ID for the current task list or task.

Read Only

Name

The name of the current task list or task.

Read/Write

Description

The description for the current task list.

Read/Write

Details

The URL to the details page for the current task list or task.

Read Only

Start Date

Tasks only. The assigned start date for the current task.

Read/Write

End Date

Tasks only. The assigned due date for the current task.

Read/Write

Created Date

The date the current task list or task was created (this information might not be available).

Read Only

Last-Modified Date

The date the current task list or task was last updated (this information might not be available).

Read Only

Owner

The user ID of the task list or task owner.

Read Only

Assigned Users

Tasks only. The IDs of the users assigned to the task.

Read/Write

Status

Tasks only. The status of the current task (pending, 25% complete, 50% complete, 75% complete, or completed).

Read/Write

Risk

Tasks only. The risk for the current task (high, low or medium).

Read/Write

Access Level

The permissions for defined roles on the current task list or task (edit, delete, edit security). You can only change permissions for the task list if the default project security is set to false.

Read/Write

Project

The ID of the project that contains the current task list.

Read Only

Default Project Security

Task lists only. Whether or not default project security should be applied to the task list. If default project security is enabled, you cannot change the security for the task list.

Read/Write

Task List

Tasks only. The ID of the task list that contains the current task.

Read Only

Level

Tasks only. The level of the task in the task hierarchy (0-3)

Read Only

Parent Task

Tasks only. The parent task for the current task (returns null if this is the root task).

Read Only

Subtasks

Tasks only. The subtasks of the current task.

Read/Write

Dependent Tasks

Tasks only. The tasks that are defined as dependent on the current task.

Read Only

Task Dependencies

Tasks only. The tasks for which the current task is defined as dependent.

Read/Write


To edit task list or task properties, follow the steps below.

  1. Create a PRC session. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Get the task or task list ID and retrieve the associated object.

  3. Edit the task or task list properties as shown in the code samples below.

    Note:

    You must call store after making any changes or they will not be persisted.

The following examples modify the status and risk for a task and assign a user.

Java

...
//get the task
ITask task = tasklistManager.getTask(taskID);

//set properties
task.setStatus(TaskStatus.TWENTY_FIVE_PERCENT_COMPLETED);
task.setRisk(TaskRisk.MEDIUM);

//assign the task
task.addAssignedUser(userID);

//call store() to persist the task
task.store();
...

.NET (C#)

...
//get the task
ITask task = tasklistManager.GetTask(taskID);

//set properties
task.Status = TaskStatus.TwentyFivePercentCompleted;
task.Risk = TaskRisk.Medium;

//assign the task
task.AddAssignedUser(UserID);

//call Store() to persist the task
task.Store();
...

.NET (VB)

...
'get the task
dim task As ITask = tasklistManager.GetTask(taskID)

'set properties
task.Status = TaskStatus.TwentyFivePercentCompleted
task.Risk = TaskRisk.Medium

'assign the task
task.AddAssignedUser(UserID)

'call Store() to persist the task
task.Store()
...
Managing Oracle WebCenter Collaboration Task Workflow Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs

To set dependencies between Oracle WebCenter Collaboration tasks and create subtasks from a remote application, use the ITask interface in the Oracle WebCenter Interaction Development Kit (IDK).

Almost every task can be broken up into detailed subtasks, and most tasks are related to other tasks in the same project. The PRC Collaboration API allows you to create up to three levels of subtasks, and set dependencies between tasks. You can also manipulate assignments, task status and risk settings. The ITask interface allows you to create subtasks for a given task and define the name, description, start date and due date. Subtasks are also represented by an instance of ITask. You can also manipulate dependencies between tasks in the same project using ITask.addDependentTask.

Note:

Tasks with subtasks cannot be added as dependents.

To add a subtask to an existing task, follow the steps below.

  1. Create a PRC session. For details, see Initiating a PRC Session to Use Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

  2. Get the task ID and retrieve the associated object.

  3. Create a subtask as shown in the code samples below.

    Note:

    The createSubTask method creates a persisted task, so no call to store is required unless you modify properties after creating the subtask.

Java

...
//get the parent task
ITask task = tasklistManager.getTask(taskID);

//create the subtask
ITask subtask = parentTask.createSubTask(name, description, startTime, endTime);

//to set additional properties, you must call store() to persist the subtask
subtask.AddAssignedUser(UserID);
subtask.store();
...

.NET (C#)

...
//get the parent task
ITask task = tasklistManager.GetTask(taskID);

//create a subtask
ITask subtask = parentTask.CreateSubTask(name, description, startTime, endTime);

//To set additional properties, make sure that Store() is called
subtask.Risk = TaskRisks.Low;
subtask.Status = TaskStatuses.FiftyPercentCompleted;
subtask.Store();
...

.NET (VB)

...
'get the parent task
dim task As ITask = tasklistManager.GetTask(taskID)

'create a subtask
Dim subtask As ITask = parentTask.CreateSubTask(name, description, startTime, endTime)

'To set additional properties, make sure that Store() is called
subtask.Risk = TaskRisks.Low
subtask.Status = TaskStatuses.FiftyPercentCompleted
subtask.Store()
...

Oracle WebCenter Collaboration Access Levels

The following matrix describes the default permissions for each access level and Oracle WebCenter Collaboration component.

By default, all objects within a project inherit the defaultproject security settings. You can override default project securityand define object-level permissions for each role. If default projectsecurity is enabled for the object, you cannot change the access levelsettings. (As with any security system, permissions are defined ina hierarchy; Admin permissions include Edit permissions,Edit permissions include Write permissions, etc.)

Collaboration Component Read Write Edit Admin

Projects

View project

View project

Save project, modify project properties

Save project, modify project properties

Tasks

View Tasks

Create tasks, update task status

Modify task list and task properties, create task lists, assign owners

Delete task lists and tasks, configure task list security

Folders

View folders

Add documents

Modify folder properties, rename folders, copy folders, create folders

Modify folder properties, rename folders, copy folders, create folders

Documents

View files

Check files in and out, undo check-out

Modify file properties, copy files

Delete files, move files, configure file security

Discussions

View Discussions

Post messages, reply to messages

Modify discussion properties, create new discussions

Delete discussions and messages, configure discussion security, edit messages, approve or reject messages


Adaptive Portlets

Adaptive portlets allow you to create a coordinated page with dynamic, interactive functionality comprised of cross-platform services that talk to multiple back-ends. For detailed examples, see Adaptive Portlet Design Patterns

Adaptive portlet tools include the following:

For additional information on adaptive portlets see Adaptive Portlet Development Tips.

The Oracle WebCenter Interaction Portlet Toolkit for .NET also provides useful tools for adaptive portlets. For installation instructions and development information, download the toolkit from the Oracle Technology Network (http://www.oracle.com/technology/index.html).

Adaptive Portlet Design Patterns

Adaptive portlet design patterns provide solutions for broad classes of problems, and provide the base for a range of cross-platform services.

The Master-Detail design pattern uses two portlet; users select an item from a list in one, and the details for that item are retrieved from the remote server and displayed in another. For example, a set of customers could be listed by name in the "master" portlet. When the user clicks a name in this portlet, the "detail" portlet presents details about the item. The detail portlet for a customer list could list all the important information about that customer, such as name, address, and phone number. This pattern assumes a tight coupling between the two portlet; both the master portlet and detail portlet must be displayed on the same page. For a looser coupling, use the Broadcast-Listener pattern. For details and sample code, see Using Session Preferences.

The Broadcast-Listener design pattern is similar to the Master-Detail pattern, but assumes a loose coupling between portlet. Users can select an item or perform some other action in a "broadcast" portlet, which causes the content in other related "listener" portlet to be redrawn. The major difference is that the Broadcast-Listener pattern relies on the Oracle WebCenter Interaction Scripting Framework to raise an event when an action is performed in the "broadcast" portlet. One or more "listener" portlet can respond to this event and update their content accordingly. For details and sample code, see Using Oracle WebCenter Interaction Scripting Framework Event Notification.

In Place Refresh allows you to refresh the content in a portlet without refreshing the page. For details and sample code, see Using In-Place Refresh.

The Structured Response design pattern handles structured HTTP responses, typically encoded as XML. In many cases it can be expensive and inefficient to send large amounts of HTML back in response to some HTTP request, if only a small part of the user interface needs to be changed. This is especially true with more complex user interfaces. In these cases, the response can be encoded in XML. The client-side response handler can then parse the XML, and update the user interface (or perform some other action) based on that response. Use the Structured Response design pattern to redraw a small area of the user interface after making an HTTP request, or to access a simple HTTP/URI type web service from a portlet. The example code below (structuredresponse_portlet.html) accesses an RSS feed from a selection of news sites.

<!-- jsxml includes -->
<a id="imgServerHref" href="pt://images/plumtree" style="display:none"></a>
<script type="text/javascript"
src="pt://images/plumtree/common/private/js/PTLoader.js"></script>
<script type="text/javascript">
var oImgServer = new Object();
oImgServer.location = document.getElementById('imgServerHref').href;
var imageServerURL = document.getElementById('imgServerHref').href;
var imageServerConnectionURL = oImgServer.location;
new PTLoader(imageServerURL, imageServerConnectionURL).include('jsxml','en');
</script>

<!-- jscontrols includes -->
<link rel="stylesheet" type="text/css" href="/portal-remote-server/js/jscontrols/styles/css/PTMenu.css"/>
<link rel="stylesheet" type="text/css" href="/portal-remote-server/js/jscontrols/styles/css/PTRichTextEditor.css"/>
<script type="text/javascript" src="/portal-remote-server/js/jscontrols/strings/PTControls-en.js"></script>
<script type="text/javascript" src="/portal-remote-server/js/jscontrols/PTControls.js"></script>

<!-- Inline JS helper functions -->
<!-- NOTE: It is standard practice to use namespace tokens (e.g., <pt:nameSpace pt:token="$$TOKEN$$" xmlns:pt="http://www.plumtree.com/xmlschemas/ptui/"/>) to ensure unique global JavaScript function and object names. For simplicity, we do not do that here.
-->

<script defer type="text/javascript" id="structured-response-portlet-A-script">
// Function that gets the RSS XML feed found at the specified url
getRSSFeed = function(url)
  {
  // First clear out any existing rows in the table
  channelTable.clearRows();

  // Force the transformer to fix up the url
  var oURL = new Object();
  oURL.location = url;

  // Do the http get
  var get = new PTHTTPGETRequest(oURL.location, handleRSSResponse);
  get.invoke();
  }

// Function that handles the RSS XML response and updates the table based on the RSS items
handleRSSResponse = function(response)
  {
  // Get the rss xml
  var xml = response.responseText;
  if (!xml || xml.indexOf('<?xml') == -1) { return; }

  // Parse into a dom, and get the channel node
  var xmlDOM = new PTXMLParser(xml);
  var rssNode = xmlDOM.selectSingleNode('rss');
  var channelNode = rssNode.selectSingleNode('channel');

  // Get the channel title and set the status bar text in the table
  var channelTitle = channelNode.selectSingleNode('title').getNodeValue();
  channelTable.statusBarText = '<b>Loaded Channel</b>: ' + channelTitle;

  // Get channel item nodes
  var itemNodes = channelNode.selectNodes('item');
  
  // Build table rows
  channelTable.rows = new Array();
  for (var i=0; i<itemNodes.length; i++)

    {
    var itemNode = itemNodes[i];

    // Get channel item properties
    var itemTitle = itemNode.selectSingleNode('title').getNodeValue();
    var itemLink = itemNode.selectSingleNode('link').getNodeValue();
    var itemDescription = itemNode.selectSingleNode('description').getNodeValue();
    if (itemNode.selectSingleNode('author'))
      var itemAuthor = itemNode.selectSingleNode('author').getNodeValue();
    if (itemNode.selectSingleNode('category'))
      var itemCategory = itemNode.selectSingleNode('category').getNodeValue();
    if (itemNode.selectSingleNode('pubDate'))
      var itemPubDate = itemNode.selectSingleNode('pubDate').getNodeValue();

    // Create a row and add it to the table
    var row = new PTRow();
    row.parent = channelTable;
    row.id = i;
    row.uid = i;
    row.previewText = itemDescription;
    row.link = itemLink;
    row.columnValues[0] = new PTTextColumnValue(itemTitle);
    row.columnValues[1] = new PTTextColumnValue(itemCategory);
    row.columnValues[2] = new PTTextColumnValue(itemAuthor);
    row.columnValues[3] = new PTTextColumnValue(itemPubDate);
    channelTable.rows[channelTable.rows.length] = row;
    }

  // Redraw the table
  channelTable.draw();
  }
</script>

<b>Select RSS Feed:</b>
<a href="#" onclick="getRSSFeed('http://www.wired.com/news/feeds/rss2/0,2610,,00.xml'); return false;">Wired News</a>
<a href="#" onclick="getRSSFeed('http://news.com.com/2547-1_3-0-5.xml'); return false;">CNET News.com</a>
<a href="#" onclick="getRSSFeed('http://partners.userland.com/nytRss/nytHomepage.xml'); return false;">NY Times</a>
<br><br>

<!-- Set up a table control to display channel items -->
<div id="channelTableContainer"></div>
<script defer type="text/javascript">
  var channelTable = new PTTableControl();
  channelTable.locale = 'en_US';
  channelTable.objName = 'channelTable';
  channelTable.container = 'channelTableContainer';
  channelTable.baseURL = '/imageserver/plumtree/common/private/portal-remote-server/js/jscontrols/1/';
  channelTable.statusBarText = 'No RSS Feed Selected';
  channelTable.rowDetailAction = new PTJavaScriptAction('window.open(\'${ROW.link}\');');
  channelTable.columns[0] = new PTColumn();
  channelTable.columns[0].name = 'Title';
  channelTable.columns[0].width = '40%';
  channelTable.columns[1] = new PTColumn();
  channelTable.columns[1].name = 'Category';
  channelTable.columns[1].width = '20%';
  channelTable.columns[2] = new PTColumn();
  channelTable.columns[2].name = 'Author';
  channelTable.columns[2].width = '20%';
  channelTable.columns[3] = new PTColumn();
  channelTable.columns[3].name = 'Publication Date';
  channelTable.columns[3].width = '20%';
  channelTable.areColumnsResizable = true;
  channelTable.clientSortEnabled = true;
  channelTable.scrollHeight = 250;

  channelTable.init();
  channelTable.draw();
</script>
</div>

Adaptive Tags

Oracle WebCenter Interaction provides a collection of useful XML tags that can be included in the markup returned by any gatewayed page, including portlets. These tag libraries include tags to display portal navigation components, portal UI components, and standard UI elements.

Using the attributes defined in the tag, the gateway transforms the XML and replaces it with standard HTML to be displayed in a browser. For example, when used in a banner portlet in the portal, the following code is replaced with the date and time in the current user's locale.

<pt:standard.currenttime xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>

The adaptive tag libraries provide access to a wide range of components.

The core tag library provides two basic tags to support core tag functionality:

  • pt:core.debugmode toggles debug mode.

  • pt:core.html allows you to use HTML tags within JavaScript, and supports attribute replacement.

The core tag library also includes tags that allow you to create and display custom tag definitions, including the pt:core.tagdef and pt:core.includetagdef tags. For details, see Creating Custom Adaptive Tags.

The tags in the constants library provide access to useful URLs, including the stylesheet, Image Service, and the correct return URL for the current user.

Note:

The tags in the constants library are the only adaptive tags that can be used as attribute values in html elements. They also use different syntax from other adaptive tags: "pt://styles" compared to "<pt:standard.currenttime ...>".

Tag Replaced with Example

pt://styles

The stylesheet URL in hosted pages and portlets

<link type="text/css" href="pt://styles" rel="StyleSheet"></link>

pt://images

The URL to the Image Service

<img src="pt://images/plumtree/portal/public/img/icon_help.gif">

pt://return

A URL that returns users to the page from which they came (the page on which the portlet that launched the page is hosted)

<a href="pt://return">Back</a>


The common tag library provides access to useful functionality, including URL transformation and namespace definition. This library also allows you to insert error information in the page, and CSS and JavaScript references in the Head element in a gatewayed HTML page. For details, see Common Adaptive Tag Library (pt:common).

The tags in the logic library handle basic logic, including creating data objects and collections, setting shared variables, and looping over a data collection. For details, see Logic Adaptive Tag Library (pt:logic).

In addition to the tags above, platform-specific tags are available to access additional information and functionality in Oracle WebCenter Interaction.

  • Navigation tags in the plugnav library are used with data tags in the ptdata library to build complete custom navigation solutions for the portal. For details, see Navigation Adaptive Tag Library (pt:plugnav).

  • The conditional tags in the ptcond library are used to perform logic to determine the current page. For details, see Conditional Adaptive Tag Library (pt:ptcond).

  • The tags in the ptui library allow you to add standard portal user interface components to any portlet, including search inputs and buttons, login components, access to account settings, error messages, and more. Tags from the standard tag library can be used to display instance-specific information, including the date and time and the page name and type. For details, see UI Adaptive Tag Library (pt:ptui).

  • The standard tag library includes tags for the following purposes:

    This package also contains most of the tags available in earlier versions, previously called "transformer tags." Legacy tags not included in the standard library are provided in the transformer tag library (6.1 and earlier) or the common tag library.

For important information about using tags, see the following sections:

For information on how Oracle WebCenter Interaction processes tags, see Adaptive Tag Control Flow.

You can also create custom tags; for details, see Creating Custom Adaptive Tags.

For a full list of tags and attributes, see the tagdocs.

Adaptive Tag Development Tips

These syntax rules and tips apply to all adaptive tags.

  • All tags are XML compliant. For example, only strings are allowed; you cannot use a tag within an attribute of another tag (<legal a=<illegal/>/>).

  • All adaptive tags belong to the namespace http://www.plumtree.com/xmlschemas/ptui/. The namespace prefix must be "pt" (xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/). To avoid including the namespace in every tag, enclose all tags in a span that defines the namespace.

  • All adaptive tag attributes require the "pt:" prefix. If you do not include the pt prefix, the portal will not return an error, but will replace the attribute with the default value when the tag is processed.

  • The adaptive tag framework displays tag errors as HTML comments. If you suspect that a tag error has occurred, simply view the HTML source for the page. If there was a problem, there should be an HTML comment where the adaptive tag would have been. Error messages are also displayed in Logging Spy.

  • Adaptive tags adhere to XHTML specifications. These specifications are not handled correctly by all HTML editors and IDEs. Some editors do not display tags correctly because of the required "pt:" prefix before tags and Oracle WebCenter Interaction attributes.

  • Use tag debug mode for additional insight into tag errors. Turning on Debug Mode causes the adaptive tag framework to output HTML comments declaring the start and end of each tag. This can be useful for determining whether a tag ran and did not output the expected result, or did not run at all, for example. Note: Standard HTML tags are not wrapped in HTML comments.

Using Internationalized Strings in Adaptive Tags

Adaptive tag attribute value replacement allows you to display localized content based on the current user's portal locale.

Oracle WebCenter Interaction stores internationalized strings in localized string files with different files for each supported language. The portal knows the locale of the current user and retrieves strings from the correct language folder automatically. To internationalize a portlet, move all strings into custom string files and translate them.

To display content in the portlet reference the strings using the value tag from the Logic tag library. Oracle WebCenter Interaction knows the locale of the current user and retrieves the string from the correct language folder automatically. For example, the HTML below retrieves the first string from a XML language file called my_message_file.xml.

<span xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
  <pt:logic.value pt:value="$#1.my_message_file"/>
</span>

For details on tags in the Logic tag library, see Logic Adaptive Tag Library (pt:logic).

Using Variables in Adaptive Tags

Adaptive tag attribute value replacement allows you to access data stored in memory.

The following simple example uses the variable and value tags from the logic tag library to store a value in memory and then display it in HTML.

<span xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
  <pt:logic.variable pt:key="test" pt:value="example text"/>
  <pt:logic.value pt:value="$test"/>
</span>

Attribute value replacement can also be used to display more complicated memory structures. Data objects can contain multiple name value pairs. The following example creates a data object with the name and URL of a link, and then displays the name.

<span xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
  <pt:logic.data pt:key="testdata" url="http://www.myco.com" name="My company"/>
  <pt:logic.value pt:value="$testdata.name"/>
</span>

Attribute value replacement cannot be used with tags outside the adaptive tag libraries. However, the pt.core.html tag supports attribute replacement within a tag and allows you to generate any HTML tag. Use the pt:tag attribute to specify the HTML tag and list the necessary HTML attributes as XML attributes. All non-adaptive tag attributes (attributes not prefixed with "pt:") are included automatically in the outputted HTML tag. For example, the following code creates an HTML anchor tag using an in-memory value for the "href" attribute.

<span xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
<pt:core.html pt:tag="a" href="$myurl" title="My title">My link</pt:core.html>
</span>

This code would be transformed to the following HTML: <a href="[data stored in the $myurl attribute]" title="My title">My link</a> .

The example below combines several different techniques and tags to show how to loop over a data collection and output HTML. This code outputs several HTML links with lines in between them.

<span xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
  <pt:logic.collection pt:key="testcollection">
    <pt:logic.data url="http://www.myco.com" name="My company"/>
    <pt:logic.data url="http://www.otherco.com" name="Other company"/>
  </pt:logic.collection>
  <pt:logic.foreach pt:data="testcollection" pt:var="link">
    <pt:core.html pt:tag="a" href="$link.url">
    <pt:logic.value pt:value="$link.name"/>
    </pt:core.html>
    <pt:logic.separator><br><br></pt:logic.separator>
  </pt:logic.foreach>
</span>

For details on logic tags, see Logic Adaptive Tag Library (pt:logic). For details on using localized strings in tags, see Using Internationalized Strings in Adaptive Tags.

Common Adaptive Tag Library (pt:common)

The Common tag library (pt:common) provides access to useful functionality, including URL transformation and namespace definition. This library also allows you to insert error information in the page, and CSS and JavaScript references in the Head element in a gatewayed HTML page.

The Common tag library is a cross-platform tag library that can be used in both Oracle WebCenter Interaction and Oracle WebCenter Ensemble.

For a full list of tags and attributes, see the tagdocs.

Table 2-1 Tags in the Common Adaptive Tag Library

Tag Function More Information

pt:common.namespace

Defines a token for use in JavaScript functions and HTML elements to ensure unique names in an aggregated page.

Defining a Unique Namespace Token Using Adaptive Tags

pt:common.url

Transforms URLs that should be gatewayed.

Transforming URLs Using Adaptive Tags

pt:common.transformer

Disables and enables transformation on a gatewayed page.

Transforming URLs Using Adaptive Tags

pt:common.error

Displays errors on the page so that they can be placed and formatted as desired.

Displaying Errors Using Adaptive Tags

pt:common.errorcode

Stores a collection of the current error codes in memory.

Displaying Errors Using Adaptive Tags

pt:common.errortext

Displays the current error text on the page so that it can be placed and formatted as desired. Only the first error message will be displayed. Used as singleton only (does not display the contents of the tag).

Displaying Errors Using Adaptive Tags

pt:common.headincludes

Allows JavaScript and Style Sheet include information to be added to a specific point in the Head element of an HTML page, as required by the XHTML specification.

Adding Header Content Using Adaptive Tags

pt:common.includeinhead

Marks JavaScript and CSS information to be included in the Head element of the HTML page by the pt:common.headincludes tag.

Adding Header Content Using Adaptive Tags

pt:common.userinfo

Displays a specific user information setting.

Accessing User Information Using Adaptive Tags


Accessing User Information Using Adaptive Tags

You can use the pt:common.userinfo tag to access specific user information settings.

The pt:common.userinfo tag is replaced with the value of the User Information setting specified in the pt:info attribute. The name attribute is case sensitive.

Note:

In earlier versions of the portal, this tag is implemented as pt:userInfo with the attribute pt:name. This syntax is also supported.

<pt:common.userinfo pt:info="FullName" xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>

Note:

You must configure the Web Service to send the appropriate user information settings to the portlet.

Adding Header Content Using Adaptive Tags

The pt:common.includeinhead and headincludes tags allow you to include custom JavaScript and CSS information in the Head element of the HTML page.

The pt:common.includeinhead tag marks the JavaScript and CSS information to be included in the Head element of the HTML page by the pt:common.headincludes tag. If a .js or .css file is marked for inclusion multiple times, it will only be included once. JavaScript generated by tags will also be included.

Note:

This tag will be ignored during automatic in-place refresh requests. Custom in-place refresh solutions must ensure that JavaScript gets included correctly.

<pt:common.includeinhead>
<script type="text/javascript"><!-- JavaScript --></script>
<script type="text/javascript" src="http://test.com/test.js"></script>
<link type="text/css" rel="stylesheet" href="http://test.com/test.css"></link>
</pt:common.includeinhead>

The pt:common.headincludes tag adds JavaScript and stylesheet include information defined by the pt:common.includeinhead tag to the Head element of the HTML page, as required by the XHTML specification. If no pt:common.headincludes tag is present, JavaScript will be included at the bottom of the Head element, and a Head element will be inserted if one does not exist.

<head>
<script type="text/javascript" src="http://test.com/main.js"></script>
</head>

The pt:common.jstransform tag inserts the Oracle WebCenter Interaction Scripting Framework headers into the Head element of the Oracle WebCenter Interaction portal page (cannot be used in Oracle WebCenter Ensemble).

Defining a Unique Namespace Token Using Adaptive Tags

It is an established best practice to include the portlet ID in the name of any Javascript functions and HTML elements to ensure unique names when the code is combined with markup from other portlet on an aggregated page.

The pt:common.namespace tag allows you to define your own token, which is replaced with the portlet ID. The token must follow these specifications:

  • Valid values for the token must be in the ASCII range 0x21 to 0x7E, excluding "<" (0x3C).

  • The scope of the token runs from the tag defining it to the end of the file; you cannot use a token prior to defining it.

  • A second pt:namespace tag with a different token redefines it; two tokens cannot be defined at the same time.

<pt:common.namespace pt:token="$$TOKEN$$" xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>
<a onclick="doStuff$$TOKEN$$();" href="#">do stuff</a>
<script>
function doStuff$$TOKEN$$() {
alert("hello");
}
</script>
Displaying Errors Using Adaptive Tags

The error* tags in the Common library allow you to insert and format error messages within the page that contains the tag(s).

The pt:common.error tag displays errors on the page, placed and formatted as desired. If the pt:common.errortext tag is included inside this tag, the contents of the tag will only be processed if there is an error. If the child tag is not present, any error messages will be formatted and displayed from this tag in the standard style.If the pt:common.errortext tag is included, only the first error message will be displayed. Other errors, as well as exception stack traces and extended error messages, will be ignored. The pt:common.errorcodes tag stores a collection of the current error codes in memory. If the error has already been displayed, no error codes will be available. These error codes can be accessed using the pt:logic.foreach tag as shown below.

Note:

If these tags are displayed on a page, errors will no longer be displayed in the normal error location and will not be available after the tag has been displayed.

<pt:common.errorcode pt:key="errorcodes"/>
<pt:logic.foreach pt:data="errorcodes" pt:var="code">
<pt:common.errortext/>
Transforming URLs Using Adaptive Tags

The pt:common.url and pt:common.transformer tags allow you to create and manipulate gatewayed URLs.

The pt:common.url tag is used to transform URLs that should be gatewayed. If the URL in the pt:href attribute is outside the gateway, it will be transformed to an absolute URL. This feature does not generate a link in HTML; it obtains the URL as a string and passes it to a client-side function, as shown in the following example.

<script>
function myFunction()
{
document.write("<pt:common.url pt:href="myURL" xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>");
}

The pt:common.transformer tag allows you to turn off JavaScript URL transformation in a gatewayed page. Set the pt:fixurl attribute to "off" as shown below.

<pt:common.transformer pt:fixurl="off" xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>

The transformer will not insert calls to the JavaScript URL transformation function for the rest of the file, unless you switch the feature back on in a subsequent directive (with a pt:fixurl attribute of "on").

Logic Adaptive Tag Library (pt:logic)

Logic tags handle basic logic, including creating data objects and collections, setting shared variables, evaluating expressions, and looping over a data collection.

The pt:logic tag library is a cross-platform tag library thatcan be used in both Oracle WebCenter Interaction and Oracle WebCenterEnsemble.

Note:

Many logic tags have a pt:scope attribute. The valid scope values are: tag, portlet request, http request, session, persistent session, and application. The default is portlet request scope.

For a full list of tags and attributes, see the tagdocs. For more information on using these tags, see the sections that follow.

Table 2-2 Tags in the Logic Adaptive Tag Library

Tag Function More Information

pt:logic.data

Creates a data object (collection of name=value pairs) and stores it in a shared variable using the key supplied.

Using Shared Variables in Adaptive Tags

pt:logic.concat

Concatenates two values into one and sets the new value in a variable with a specified name.

Using Shared Variables in Adaptive Tags

pt:logic.variable

Stores a shared variable using the key and value supplied. Designed for use with attribute replacement or with the pt:logic.value tag.

Using Shared Variables in Adaptive Tags

pt:logic.collection

Creates a collection of data objects and stores it in a shared variable using the key supplied.

Using Shared Variables in Adaptive Tags

pt:logic.collectionlength

Evaluates the length of a collection and stores the result in memory.

Using Shared Variables in Adaptive Tags

pt:logic.value

Evaluates an attribute and displays the referenced value. Used as singleton only (does not display the contents of the tag).

Using Shared Variables in Adaptive Tags

pt:logic.boolexpr

Evaluates a boolean expression and stores the result as a boolean in memory. Designed to work with the pt:logic.if tag.

Evaluating Expressions Using Adaptive Tags

pt:logic.intexpr

Evaluates an integer expression and stores the result as a boolean in memory. Designed to work with the pt:logic.if tag.

Evaluating Expressions Using Adaptive Tags

pt:logic.stringexpr

Evaluates whether or not two strings are equal and stores the result as a boolean in memory. The case must match. Designed to work with the pt:logic.if tag.

Evaluating Expressions Using Adaptive Tags

pt:logic.containsexpr

Checks if a collection contains a specific data element and sets a specified variable to true or false. Designed to work with the pt:logic.if tag.

Evaluating Expressions Using Adaptive Tags

pt:logic.if

Evaluates an expression and displays either the pt:logic.iftrue or pt:logic.iffalse tag contents.

Evaluating Expressions Using Adaptive Tags

pt:logic:iffalse

Displayed if the surrounding pt:logic.if tag evaluates to false.

Evaluating Expressions Using Adaptive Tags

pt:logic:iftrue

Displayed if the surrounding pt:logic.if tag evaluates to true.

Evaluating Expressions Using Adaptive Tags

pt:logic.foreach

Allows looping over a data collection. Supports tag and portlet request scope only.

Looping Over Data Collections Using Adaptive Tags

pt:logic.separator

Inserts a separator between the elements of a for each loop.

Looping Over Data Collections Using Adaptive Tags

pt:logic.appcache

Caches data set by data tags on the application. Note that there is no access control on cached data.

Caching Data

pt:logic.sessioncache

Caches data set by data tags on each user's session. Note that there is no access control on cached data.

Caching Data

pt:logic.apphierdata

Creates hierarchical data by appending child data or adding new child data if none exist.

Creating Hierarchical Data

pt:logic.replacehierdata

Creates or modifies hierarchical data by replacing child nodes with new data collections.

Creating Hierarchical Data


Using Shared Variables in Adaptive Tags

The pt:logic.data, variable, and collection tags allow you to store editable shared variables, which can be used in attribute value replacement or with the pt:logic.value tag.

The pt:logic.data tag stores a data object (a name=value pair) as an editable shared variable using the key passed in. The pt:logic.variable tag stores an editable shared variable using the key and value passed in. If either tag is used inside the pt:logic.collection tag, the variables are stored directly in the parent collection. If the tag is used alone, the key attribute is required. The variable is only stored after the tag is finished processing all its contents. A collection can only contain a single type of variable, such as string variables or data objects.

Note:

If a variable or collection with the same name already exists, it will be overwritten. If the preexisting variable is not editable, the tag will fail. Variable names cannot contain the reserved character '.'.

<pt:logic.variable pt:key="title" pt:value="Administrator"/>

<pt:logic.data pt:key="myurl" name="Home" url="http://edocs.bea.com"/>

<pt:logic.collection pt:key="testcollection">
<pt:logic.data url="http://www.myco.com" name="My company"/>
<pt:logic.data url="http://www.otherco.com" name="Other company"/>
</pt:logic.collection>

<pt:logic.collection pt:key="teststringcollection">
<pt:logic.variable pt:value="my string data"/>
<pt:logic.variable pt:value="my other string data"/>
</pt:logic.collection>

The pt:logic.value tag displays the value of the variable referenced by the pt:value attribute. Variables can be set using the pt:logic.data or pt:logic.variable tags as explained in the previous section. This tag can be used to reference localized strings in message files.

<pt:logic.value pt:value="$title"/>
<pt:logic.value pt:value="$myurl.Home"/> 

For details on referencing localized strings using tags, see Using Internationalized Strings in Adaptive Tags.

Evaluating Expressions Using Adaptive Tags

The pt:logic.boolexpr, intexpr, stringexpr and containsexpr tags work with the pt:logic.if tag to evaluate a range of expressions.

The sample code below determines whether the current value for the variable "title" is set to "Administrator". Variables can be set using the pt:logic.data or pt:logic.variable tags.

<pt:logic.stringexpr pt:expr="($title) == Administrator" pt:key="boolvalue"/>
<pt:logic.if pt:expr="$boolvalue">
<pt:logic.iftrue>
This is displayed if expr evaluates to true. 
</pt:logic.iftrue>
<pt:logic.iffalse>
This is displayed if expr evaluates to false. 
</pt:logic.iffalse>
</pt:logic.if>

For details on using shared variables, see Using Variables in Adaptive Tags.

Looping Over Data Collections Using Adaptive Tags

The pt:logic.foreach tag allows you to loop over collections of data.

The sample code below creates a table to store links for a navigation menu.

<span xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
<table cellpadding="5" cellspacing="0" width="100%" border="0">
<!-- loop starts here -->
<pt:logic.foreach pt:data="directorymenu" pt:var="temp">
<tr>
<td height="25" colspan="3" class="navSidebarText">
<pt:core.html pt:tag="img" src="$temp.img" alt="" border="0" align="absmiddle" height="20" width="20" />
<pt:core.html pt:tag="a" href="$temp.url">
<pt:logic.value pt:value="$temp.title" />
</pt:core.html>
</td>
</tr>
</pt:logic.foreach>
</table>
</span>

This table can then be populated with links using navigation tags. For details on navigation tags, see Common Adaptive Tag Library (pt:common).

Caching Data

The pt:logic.appcache and pt:logic.sessioncache tags allow you to cache the data set by data tags. Most data tags do not need to be cached. Data tags in the pt:data tag library already use server-side cached data. Suitable data tags to cache are ones that execute database or search queries every time they run.

Use the pt:logic.appcache tag to cache data that should be shared between multiple users on the application. Do not use this tag to cache data tags that return security filtered objects; there is no access control on cached data. Caching security filtered data bypasses security checks and all users using the cached data will see the view of the user who added the cache entry.

Use the pt:logic.sessioncache tag to cache data that is specific to each user on the user's session. The cached data is cleared after the user logs off.

To cache a data tag, define it normally and nest it inside of one of the cache tags above. Set the pt:data attribute of the cache tag to the pt:key attribute of the enclosed data tag. Set the datascope to the same scope as the data tag (not necessary if the data tag uses the default portlet request scope). Define the expiration duration for the cache entries using the expiration attribute. Use the optional contextid attribute to define the cache context. For example, to cache data in a Community, pass in the current Community ID. (To cache data per user, use the sessioncache tag, not a User context.)

<pt:logic.appcache pt:cachekey="cacheddata" pt:expiration="20" pt:data="datatocache" >
  <pt:custom.customquery pt:key="datatocache"/> // this tag is only run when cached data expired or none is found
</pt:logic.appcache>

To access the cached data, use the pt:logic.value tag.

<pt:logic.value pt:value="$cacheddata" pt:scope="application"> // accessing the cached data
Creating Hierarchical Data

The pt:logic.apphierdata and pt:logic.replacehierdata tags allow you to create hierarchical data. Hierarchical data is used by the tree and menu tags, which display hierarchical structure of resources such as communities, subcommunities and community pages.

Use the pt:logic.apphierdata tag to create new children or append data to existing children. If no children exists, the data is added as children. An index attribute with no value creates a new hierarchical data structure.

Use the pt:logic.replacehierdata tag to create or modify hierarchical data by replacing child nodes with new data collections.

The example below replaces the children of "topCommunities" at location 0,2 with the data in the "communityPages" tag variable. If topCommunities contains a list of Communities and their Subcommunities and "communityPages" contains a list of Community pages, the tag will replace the existing Community pages in the 3rd level Subcommunity (2 is the 3rd element in a 0-based index) of the first (top level) Community.

<pt:logic.replacehierdata pt:id="topCommunities" pt:dataid="communityPages" pt:index="0,2"/>

Standard Adaptive Tag Library (pt:standard)

Adaptive tags can be used to build links to a variety of Oracle WebCenter Interaction resources. The Standard tag library (pt:standard) allows you to create links to specific portal objects, the portal login page, or to specific portlets. You can also build gatewayed URLs, disable URL transformation, and enable Hosted Display Mode for gatewayed pages.

Note:

The transformer copies any attributes not in the PT namespace to the output link tag. These links are platform and version independent, and do not rely on particular ASP/JSP files or query string arguments.

The tables below summarize available standard tags. For a full list of tags and attributes, see the tagdocs.

Page Information: These tags display instance-specific information for use in portal navigation elements, including the date and time and the page name and type.

Tag Function Example

pt:standard.currenttime

Writes the current date and time according to the rules of the user's chosen locale. Only the full date and time can be displayed; there is no way to return just the date, just the time, or any other subset of information. This tag is recalculated every time the code is pulled out of the cache.

For example:

<pt:standard.currenttime xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>

pt:standard.pagename

Replaced with the name of the current portal page (My Page or Community) or left blank otherwise.

 

pt:standard.realmname

Replaced with the portal page type ("My Pages," "Documents," "Administration," or "Gateway").

For example, the code snippet below creates the portal banner (the pt://images constant is used to reference the portal Image Service).

<td align="left" colspan="1" id="pt-header-left">
  <!--portal banner -->
<img src="pt://images/plumtree/portal/public/img/PT_logo_sm_wht.gif" alt="Plumtree Logo" border="0" align="absmiddle" height="50" width="125" />

</td>
<td align="right" nowrap="nowrap" colspan="1" id="pt-header-right">

<h1 class="banHeader">
<pt:standard.realmname xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>
</h1>

<h2 class="banSubhead">
<pt:standard.pagename xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>
</h2>
</td>

URLs: These tags provide access to key portal components, including the stylesheet, portal objects, and the portal login pages. Additional tags allow you to create gatewayed links and control hosted display mode for gatewayed pages.

Tag Function Example

pt:standard.stylesheets

Allows you to enter the current portal stylesheet in the HEAD of any non-hosted gatewayed HTML page. (In previous versions, this tag was implemented as pt:styleSheets. This syntax is still supported.)

For example,

<HTML>
<HEAD>
  <pt:standard.stylesheets xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>
  ...
 </HEAD>
<BODY>
...

pt:standard.displaymode

Sets the header that tells the portal server to display a page in the style of the portal, with a portal banner. The tag can also set the title and subtitle of the page. The displaymode tag does not display any contents, and should only be used as a singleton. (Note: Pages in hosted display mode should not contain <HTML>, <HEAD>, <META>, <TITLE> or <BODY> tags.)

For example,

<pt:standard.displaymode pt:mode="Hosted" pt:title="My title" pt:subtitle="My subtitle"
xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>

pt:standard.loginlink

Creates a link to the portal login page. In previous versions, this tag was implemented as pt:loginLink. This syntax is still supported.

For example,

<pt:standard.loginlink xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>Log in
</pt:standard.loginlink>

pt:standard.openerlink

Creates a link that can open or view an object or properties of an object that already exists within the portal.

Accessing Oracle WebCenter Interaction Objects Using Adaptive Tags

pt:standard.gatewaylink

Allows you to buildgatewayed links to remote pages.

Building Gatewayed URLs Using Adaptive Tags


Constants are also available for useful URLs, including the Image Service, current stylesheet, and return URL For details, see Adaptive Tags.

User-Specific Information: These tags allow you to insert content on a page based on conditional statements of user and group membership. For details on implementing these tags, see Securing Content Based on User Permissions Using Adaptive Tags.

Tag Function

pt:standard.choose

Denotes the start of a secured content section.

pt:standard.when

Includes a test condition that defines who has access to the enclosed content.

pt:standard.otherwise

Includes content that should be displayed as default.


To access user settings stored in the portal database, use the pt:usersetting tag. The tag is replaced with the value of the user setting specified in the pt:name attribute. This tag will decode %uHHHH encoded values stored in the portal database. You must configure the Web Service object to send the appropriate settings. For details on Oracle WebCenter Interaction settings, see Oracle WebCenter Interaction Portlet Settings.

<pt:userSetting pt:name="myUserSetting" xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>

Tree Controls: These tags provide links to a popup window that allows users to select options from a structured list of objects. For details on implementing these tags, see Creating Tree Controls Using Adaptive Tags.

Tag Function

pt:standard.tree

Creates a form button to a popup window that allows users to select options from a structured list of objects.

pt:standard.treelink

Creates a link to a popup window that allows users to select options from a structured list of objects.

pt:standard.treeurl

Returns a URL to a popup window that allows users to select options from a structured list of objects (can be used in JavaScript). Does not display the contents of the tag and should only be used as a singleton tag (i.e. <pt:standard.treeurl/>), rather than as a tag with both an open and close tag.


Accessing Oracle WebCenter Interaction Objects Using Adaptive Tags

To create a link that can open or view an object or properties of an object that already exists within the portal, use the pt:standard.openerlink tag.

You can use the pt:standard.openerlink tag for a variety of purposes, including viewing the User Profile for a user (requires User ID), viewing a community page (requires Community ID), opening a Remote Server object to edit the base URL (requires Remote Server ID), and clicking through to a document in the Knowledge Directory (requires Document ID). The pt:standard.openerlink tag is primarily controlled by three attributes:

Value Attribute

pt:classid

The portal object type.

pt:objectid

The ID of the portal object referenced in the Class ID attribute (for example, the User or Community ID). To access the object ID, use the PRC. For details, see Querying Objects Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

pt:mode

The action of the link (open/edit, view and view metadata).


For a full list of class IDs and associated modes, see Oracle WebCenter Interaction Object Type Class IDs and Modes.

Note:

When you open an object in edit mode from a gatewayed page, clicking Finish or Cancel will close the window, so you should always use a popup window. When you open an object in edit mode from within a portal page (My Page or Community Page), clicking Finish or Cancel will redirect to the return URI within the same window, so using a popup window might not be necessary. Always test your code in the portal to make sure it functions as expected.

To open a link in a popup window, you must add attributes to the link to control the popup window. All attributes that are not in the PT namespace are passed through to the transformed link. The following example opens a community page in a separate window.

<pt:standard.openerlink xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/' pt:objectid='1'
pt:classid='512' pt:mode='2' target='myWindow' onclick=window.top.open ('','myWindow','height=800,width=700,status=no,toolbar=no,menubar=no,location=no');>View my Community.</pt:standard.openerlink>

Any time a user's name is displayed on a page, it is a best practice to display a clickable link to the user's profile page. The pt:standard.openerlink tag allows you to create links on demand using the User ID. (As noted above, use the PRC to access the object ID.) This example is not displayed in a popup window.

<pt:standard.openerlink xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/' pt:objectid='" & _ userID & "'
pt:classid='1' pt:mode='2'>"& LocRM.GetString("userName") & _ "</pt:standard.openerlink>
Building Gatewayed URLs Using Adaptive Tags

To buildgatewayed links to remote pages, use the pt:standard.gatewaylink tag.

Using attributes, you can include references to associated portal objects, usually a portlet or community. When the link is executed, the portal sends any preferences associated with the referenced object to the remote server. The pt:standard.gatewaylink tag supports the following attributes:

Attribute Value

pt:classid

The portal object type. The default is portlet (43). The pt:standard.gatewaylink tag also supports cards (18), Content Sources (35), and Web Services (47).

pt:objectid

The ID of the portal object referenced in the pt:classid attribute (e.g., the Portlet ID). To access the object ID, use the PRC. For details, see Querying Objects Using Oracle WebCenter Interaction Development Kit (IDK) Remote APIs.

pt:communityid

The ID of the associated Community.

pt:pageid

The ID of the associated page (can be positive or negative).

pt:href

The URL to the remote page. If you pass in a relative URL, the portal will use the configuration settings for the referenced portal object to create the gatewayed URL.


The sample code below creates a link to a remote page associated with the portlet with ID 201. The arguments in the resulting URL tell the portal to send the preferences associated with the portlet to the remote server.

<pt:standard.gatewaylink class="myStyle" xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'
pt:objectid='201' pt:href="doStuff.aspx?ID=5">Click here</pt:standard.gatewaylink>

The code below creates a link to a page associated with the Web Service with ID 200, and also sends the community preferences from the community with ID 301 to the remote server.

<pt:standard.gatewaylinkpt:href="http://myRemoteServer/myTestPage.jsp"pt:objectid="200"
pt:classid="47"pt:communityid="301"xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>
Click here</pt:standard.gatewaylink>

You can also use the pt:standard.gatewayLink tag to gateway documents that have not been crawled or uploaded to the portal using the ID for the associated WWW Content Source, as shown in the sample code below.

<pt:standard.gatewaylinkpt:href="http://myRemoteServer/mydocs/WhitePaper2002.doc"
pt:objectid="202"pt:classid="35"xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>
WhitePaper2002</pt:standard.gatewaylink>

You can also use the pt:common.url tag to transform URLs that should be gatewayed. For details, see Transforming URLs Using Adaptive Tags.

Creating Tree Controls Using Adaptive Tags

To create a form button or link to a popup window that allows users to select options from a structured list of objects, use the pt:standard.tree, pt:standard.treelink or pt:standard.treeurl tag.

The pt:standard.tree and pt:standard.treelink tags create a form button or link, and the pt:standard.treeurl tag returns a URL that can be used in JavaScript. All three tags use a selection of attributes to control the tree display. The first four attributes are required.

Attribute Description Default Syntax

pt:Class

The ID of the types of objects to display in the tree. Community pages are not supported. (REQUIRED)

value required

pt:Class='<classID1>,<classID2>,<classID3>,...'

pt:RootID

The ID of the root folder to be displayed in the tree. Use ID 1 for all folders. (REQUIRED)

value required

pt:RootID='<folderID>'

pt:SubmitMd

The mode in which the tree submits data to the opening page. Use mode 2 (javascript submit for remote development). When the data is submitted, the javascript function defined in pt:Submit is called on the main page. (REQUIRED)

value required (=2)

pt:SubmitMd='2'

pt:Submit

The name of the javascript function in the parent page to call when the tree is submitted (can take in an array of objects with name, Object ID, and Class ID). Do not include parentheses ("()") in the value of this attribute. (REQUIRED)

value required

pt:Submit='<javascriptFunctionName>'

pt:AllowEmpty

Allows users to click finish in a tree window with nothing selected: true=allow no selection; false=must select.

false

pt:AllowEmpty='true' or pt:AllowEmpty='false'

pt:Display

Limits the display to the selected objects, referenced by Class ID and Object ID. Cannot be used to display folders. The Class ID of each object must be included in pt:Class. The pt:RootID must be specified even though it will be ignored. Note: Do not include any folder Class IDs (17, 20, 515) in the pt:Class value or the tree will not display correctly.

n/a

pt:Display='<classID1>,<objectID1>,<classID2>,<objectID2>,...' pt:Class='<classID1>,<classID2>,...' pt:RootID='1'

pt:Form / pt:Input

Puts the AActivitySpace ID of the tree space into the target form input (used to reopen the tree after it has been created). The pt:Form attribute is the name of the parent form to which data will be passed back. The pt:Input attribute is the name of the target input in the parent form. The AActivitySpace ID of the tree space is placed in this input.

n/a

pt:Form='<formName>' pt:Input='in_hi_parentSpace'

pt:Hide

Hides the specified objects. (See pt:openerLink for a list of Class IDs.)

n/a

pt:Hide='<classID1>,<objectID1>,<classID2>,<objectID2>,...'

pt:Multi

Allows users to select multiple items: true=checkboxes, false=radio buttons.

false

pt:Multi='true' or pt:Multi='false'

pt:Select

The default selected item(s) in the tree, referenced by Class ID and Object ID.

none

pt:Select='<classID1>,<objectID1>,<classID2>,<objectID2>,...'

pt:SelectMd

The tree select mode: 1=compositeselect, 2=leafselect, 3=leafcompositeselect (1 = select folders; 2 = select objects; 3 = select folders and objects).

2

pt:SelectMd='<modeID>'

pt:ShowRoot

Allows you to hide the root folder: true=display root folder, false=hide root folder (if false, subfolders are displayed at the top level).

true

pt:ShowRoot='true' or pt:ShowRoot='false'

pt:SubTitle

Subtitle of the tree, for user instruction (e.g., "Choose a user.").

none

pt:SubTitle='<windowSubtitle>'

pt:Title

Title of the tree popup window.

none

pt:Title='<windowTitle>'

pt:windowFeatures

Allows you to define the features argument for the resulting window.open() function call, specifying the features for a standard browser window.

(see syntax)

pt:windowFeatures='location=no,menubar=no, resizable=yes,height=400,width=400'

pt:windowName

Window name of the popup tree, used in the resulting window.open() function call.

'_blank1'

pt:windowName='<windowName>'

pt:Access

Advanced attribute. Access level for the objects to be displayed: None=0, Read=1, Select =3, Edit=7, Admin=15 Note: For objects in the Knowledge Directory (folders and documents), only two levels of security are available (0 or 1). Use pt:Access='1' to allow users access to Knowledge Directory objects.

3

pt:Access='<accessLevel>'

pt:CommunityMode / pt:CommunityID

Advanced attribute. Specifies whether to include community objects in the tree: 1=no communities, 2=this community (specified community + all parent communities), 3=all communities. Note: If CommunityMode=2, you must specify the community folder ID (not the community object ID) in the pt:CommunityID attribute.

1

pt:CommunityMode='<communityMode>' pt:CommunityMode='2' pt:CommunityID='<communityFolderID>'

pt:DirMode

Advanced attribute. Specifies which mode to use when selecting objects from the Knowledge Directory: 1=Browse Mode; 2=Edit Mode Note: The default mode is Edit (2); users who do not have edit access to the Knowledge Directory will see an "access denied" error when they access the tree.

2

pt:DirMode='<dirMode>'


For a full list of Oracle WebCenter Interaction object type class IDs, see Oracle WebCenter Interaction Object Type Class IDs and Modes.The following code sample produces a button with an "onclick" action that opens a popup window.

<pt:standard.tree xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/' value="Button
Name" class="gContentSection" pt:windowName='myWindow' pt:windowFeatures='location=no,menubar=no,height=500,width=300'
pt:RootID='1' pt:Multi='true' pt:SelectMd='2' pt:SubmitMd='2' pt:Submit='PickerSubmit'
pt:Title='User' pt:SubTitle='Pick users' pt:Class='1'/>

The pt:treeLink tag can be used in the same way, except that it generates an anchor tag using the supplied text instead of a form button. In this tree control, the selection is limited to one user.

<pt:standard.treeLink xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/' pt:windowName='myWindow'
pt:windowFeatures='location=no,menubar=no,height=500,width=300' pt:RootID='1' pt:Multi='false'
pt:SelectMd='2' pt:SubmitMd='2' pt:Submit='PickerSubmit' pt:Title='User' pt:SubTitle='Pick
a user' pt:Class='1'>Pick a user</pt:standard.treeLink>

Clicking the link opens a popup window that allows the user to browse and choose the referenced object type. (If the popup was opened using the first code sample, the tree would display checkboxes instead of radio buttons to allow multiple choices.)As noted above, tree tags require a JavaScript function (named in the pt:Submit attribute) to handle the submission from the tree. The following sample code takes in an array with name, Object ID, and Class ID. When the pt:Multi attribute is set to false (single selections only), only the first set of declarations is necessary.

function PickerSubmit (myInput)
{
item0Name = myInput[0].Name;
item0ObjectID = myInput[0].ObjectID;
item0ClassID = myInput[0].ClassID;

item1Name = myInput[1].Name;
item1ObjectID = myInput[1].ObjectID;
item1ClassID = myInput[1].ClassID;
...
}

For optimum usability, the return array can be placed into hidden form elements and posted back to the source page so that the transformer link can specify which items should be selected if the user opens the dialog box again.

function returnFromFolderSelection(arrIn){
var tmpObject;
var iLength;

iLength = arrIn.length;


if (iLength > 0) {
tmpObject = arrIn[0];
document.Form1.HiddenSelectedFolderName.value = tmpObject.Name;
document.Form1.HiddenSelectedFolderObjectID.value = tmpObject.ObjectID;
document.Form1.HiddenSelectedFolderClassID.value = tmpObject.ClassID;
}
document.Form1.submit();
}
Securing Content Based on User Permissions Using Adaptive Tags

To insert content on a page based on conditional statements of user and group membership, use the pt:standard.choose, pt:standard.when and pt:standard.otherwise tags.

The pt:standard.choose tag denotes the start of a secured content section. The pt:standard.when tag includes a test condition (pt:test) that defines who has access to the enclosed content. The pt:standard.otherwise tag includes content that should be displayed by default.

Note:

In earlier versions of the portal, these tags are implemented as pt:choose, pt:when and pt:otherwise. This syntax is still supported.

The value for the pt:test attribute is case-sensitive. Multiple users or groups should be separated by commas, with semicolons separating user values from group values. The syntax is as follows:

<pt:standard.choose xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
<pt:standard.when pt:test="stringToACLGroup('user=userid1,userid2,...;group=groupid1,groupid2,groupid3;').isMember($currentuser) xmlns:pt='http://www.Plumtree.com/xmlschemas/ptui/'>
... content ...
</pt:standard.when>
<pt:standard.otherwise xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
... default content ...
</pt:standard.otherwise>
</pt:standard.choose>

For example:

<pt:standard.choose xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
<pt:when pt:test="stringToACLGroup('user=1;').isMember($currentuser)" xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
<title>welcome administrator</title></head>
... secret administrator content ...
</pt:standard.when>
<pt:standard.when pt:test="stringToACLGroup('user=200,201;group=200;').isMember($currentuser)"
xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
 <title>the 200 club</title></head>
... content only group 200 or users 200 and 201 can see ...
</pt:standard.when>
<pt:standard.otherwise xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
<title>everyone else</title></head>
... content any user can see ... 
</pt:standard.otherwise>
</pt:standard.choose>

You can also test if the current user is a guest user (not logged in). Since there can be multiple guest users in the portal, simply testing for default guest user ID 2 does not work.

<pt:standard.choose>
  <pt:standard.when pt:test="isGuest($currentuser)">
  ... guest user content ...
  </pt:standard.when> 
  <pt:standard.otherwise> 
  ... logged in user content ...
  </pt:standard.otherwise> 
</pt:standard.choose>

Navigation Adaptive Tag Library (pt:plugnav)

In Oracle WebCenter Interaction, customizing navigation can be implemented without coding against the portal UI. The Navigation tag library (pt:plugnav) is used to manage display of navigation elements.

The tags in the pt:plugnav tag library must be used with tagsfrom the pt:ptdata tag library. These tags are available for use only in Oracle WebCenter Interaction.

For a full list of tags and attributes, see the tagdocs.

Tag Function

pt:plugnav.ddmenurowcontainer

Manages the display and positioning of navigation tabs that activate dropdown menus. (Only accepts ddmenutab or ddmenusimpletabs or equivalent as data.)

pt:plugnav.ddmenusimpletabs

Defines a list of simple tabs using the data provided. (Must be used with ddmenurowcontainer or equivalent.)

pt:plugnav.ddmenutab

Defines a tab that activates a dropdown menu with the data provided. (Must be used with ddmenurowcontainer or equivalent.)

pt:plugnav.horizontalrowcontainermenu

Generates and displays HTML for dynamic horizontal menus. (Only accepts horizontalrowtab or equivalent as data.)

pt:plugnav.horizontalrowtab

Defines a horizontal menu tab that displays a row of links using the data provided. (Must be used with horizontalrowcontainermenu or equivalent.)


Implementing Custom Navigation Using Adaptive Tags

Navigation tags are used with Data tags to build complete navigation solutions for Oracle WebCenter Interaction.

The first step is coding the portlet. Initialize the menus by retrieving the navigation links using data tags. To create a collection, set the same ID on multiple data tags. For details on the Data tag library, see Data Adaptive Tag Library (pt:ptdata).

<span xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
<html> 

<!-- Links to my pages are stored in mypagemenu -->
<pt:ptdata.mypageactionsdata pt:id='mypagemenu' />
<pt:ptdata.mypagesdata pt:id='mypagemenu' /> 

<!-- Links to my communities are stored in commmenu -->
<pt:ptdata.communityactionsdata pt:id='commmenu' />
<pt:ptdata.mycommunitiesdata pt:id='commmenu' /> 

<!-- Links to directory are stored in directorymenu -->
<pt:ptdata.directorybrowsedata pt:id='directorymenu' />
<pt:ptdata.directoryeditdata pt:id='directorymenu'/> 

<!-- Mandatory links are stored in mandlinks-->
<pt:ptdata.mandatorylinksdata pt:id='mandlinks' />
<pt:ptdata.mandatorylinknamedata pt:key='mandlinksname'/>

<!--Links to administration and mandatory communites are stored in menutabs -->
<pt:ptdata.administrationdata pt:id='menutabs' />
<pt:ptdata.mandtabcommsdata pt:id='menutabs'/> 

Next, create the structure to display the menus. To replace standard portal navigation using a header portlet, use navigation tags to handle display as shown in the code sample below.

<!-- Dropdown menus section begin -->
<pt:plugnav.ddmenurowcontainer pt:menuvar='midrowmenu' pt:hideemptymenus='true' >
<pt:plugnav.ddmenutab pt:containervar='midrowmenu' pt:datavar='mypagemenu' pt:text='$#1840.ptmsgs_portalbrowsingmsgs' />
<pt:plugnav.ddmenutab pt:containervar='midrowmenu' pt:datavar='commmenu' pt:text='$#1841.ptmsgs_portalbrowsingmsgs' />
<pt:plugnav.ddmenutab pt:containervar='midrowmenu'pt:datavar='directorymenu'pt:text='$#1842.ptmsgs_portalbrowsingmsgs' />
<pt:plugnav.ddmenutab pt:containervar='midrowmenu' pt:datavar='mandlinks' pt:text='$mandlinksname' />
<pt:plugnav.ddmenusimpletabs pt:containervar='midrowmenu' pt:datavar='menutabs' />
</pt:plugnav.ddmenurowcontainer>
<!-- Dropdown menus section end -->

You can also display navigation links within a portlet, as shown in the sample code below.

<table cellpadding='0' cellspacing='0' width='200' border='0'>
  <tr>
    <td height='2' colspan='3'>
    </td>
  </tr>
  <tr class='menuHeaderBg'>
    <td align='left' valign='middle' height='20' colspan='3' class='navSidebarSectionHeader'>
    &nbsp; &nbsp;My Communities
    </td>
  </tr> 

<!-- links to communities are entered here -->
<pt:logic.foreach pt:data='commmenu' pt:var='temp'>
  <tr class='navMidtabBg'>
    <td height='16' colspan='2' class='navMidtabBtn'>
    <table cellpadding='0' cellspacing='0' width='100%'>
      <tr>
        <td height='20' width='100%' nowrap='nowrap' colspan='1' class='objectBtn'>
        <span class='actionbarBanText'>
          <pt:core.html pt:tag='img' src='$temp.img' alt='' border='0' align='absmiddle' height='20' width='20' />
          <pt:core.html pt:tag='a' href='$temp.url'>
            <pt:logic.value pt:value='$temp.title' />
          </pt:core.html>
        </span>
        </td>
      </tr>
    </table>
    </td>
  </tr>
</pt:logic.foreach>
</table>

You can also add portal UI elements to custom navigation using UI tags. For details on UI tags, see UI Adaptive Tag Library (pt:ptui).To deploy a custom navigation header portlet in Oracle WebCenter Interaction (to replace standard navigation), follow the steps below.

  1. Register the portlet in the portal.

  2. Create an Experience Definition that uses the custom navigation header portlet you registered in step 1.

  3. Create an Experience Rule to direct users to the new Experience Definition. For details on Experience Definitions and Experience Rules, see the Administrator Guide for Oracle WebCenter Interaction.

Conditional Adaptive Tag Library (pt:ptcond)

Conditional tags allow you to peform logic to determine the current page that the user is on, including whether or not the current page is in a Community or not. The tags in this library are available for use only in Oracle WebCenter Interaction.

Tag Function

pt:ptcond.iscurrenturl

Outputs the contents of the tag when on a specific page by comparing against the page URL.

pt:ptcond.iscurrcommunity

Outputs the contents of the tag when in a specific Community by comparing against the ID or name. Nest two or more tags to perform checks where both id and name need to match.

pt:ptcond.iscurrcommpage

Outputs the contents of the tag when on a specific Community page by comparing against the page ID or name. Nest two or more tags to perform checks where both id and name need to match.

pt:ptcond.isincommunity

Outputs the contents of the tag when in a Community.

pt:ptcond.isnotincommunity

Outputs the contents of the tag when NOT in a Community.


For example, you can use the pt:ptcond.iscurrenturl tag to determine where in the portal the user is currently. You can also retrieve additional information from the query string, such as the user ID, as shown in the sample code below.

<pt:ptcond.iscurrenturl pt:loginpage="true"/>
You are on the Login Page
</pt:ptcond.iscurrenturl>
<pt:ptcond.iscurrenturl pt:contains1="server.pt/mypage" pt:contains2="server.pt/directory"/>
You are either on a MyPage or Directory Page
</pt:ptcond.iscurrenturl>
<pt:ptcond.iscurrenturl pt:contains1="space=MyPage"/>
  <pt:ptcond.iscurrenturl pt:contains1="userid=1"/>
  You are on a MyPage and your User Id is 1
 </pt:ptcond.iscurrenturl>
</pt:ptcond.iscurrenturl>

This tag library allows you to determine the current community in a variety of ways, as shown in the examples below.

<pt:ptcond.isincommunity>
 You are in Community <pt:logic.value pt:value="$communityName"/>.
</pt:ptcond.isincommunity>
<pt:ptcond.iscurrcommunity pt:id="350"/>
This Community id is 350.
</pt:ptcond.iscurrcommunity>
<pt:ptcond.iscurrcommpage pt:name="^Community Page^">
You are on the Community Page with the name 'Community Page'
</pt:ptcond.iscurrcommpage>

UI Adaptive Tag Library (pt:ptui)

UI tags allow you to add standard portal UI components to any portlet in Oracle WebCenter Interaction, including search inputs and buttons, login components, access to account settings, and more.

The tags in the pt:ptui tag library are available for use only in Oracle WebCenter Interaction. Additional tags from the pt:standardtag library can be used to display instance-specific information,including the date and time and the page name and type. For details,see Standard Adaptive Tag Library (pt:standard).

For a full list of tags and attributes, see the tagdocs.

Tag Function

pt:ptui.welcome

Displays the user's personalized welcome message. Used as singleton only (does not display the contents of the tag).

pt:ptui.myhome

Displays a link to the user's home page (MyPage or community). Can be used as singleton or wrapper for HTML.

pt:ptui.myaccount

Displays a link to the user's My Account page. Can be used as singleton or wrapper for HTML.

pt:ptui.createaccount

Displays a link to the Create Account page. Can be used as singleton or wrapper for HTML.

pt:ptui.searchform

Displays the basic search form without any buttons or links.

pt:ptui.basicsearchbutton

Displays the basic search button. Can be used as singleton or wrapper for HTML.

pt:ptui.advancedsearchbutton

Displays the advanced search button. Can be used as singleton or wrapper for HTML.

pt:ptui.federatedsearchbutton

Displays the federated search button. Can be used as singleton or wrapper for HTML.

pt:ptui.topbestbetsearchbutton

Displays the top best bet button. Can be used as singleton or wrapper for HTML. (Must be used with pt:ptui.searchform.)

pt:ptui.help

Displays the help image and link. Can be used as singleton or wrapper for HTML.

pt:ptui.login

Displays a login/logoff link based on the current state of the user. (If the user is logged in, the URL executes logoff; if the user is not logged in, the URL executes login.)

pt:ptui.loginform

Outputs the basic login form without any buttons or links.

pt:ptui.loginusername

Displays the user name text box for the login form.

pt:ptui.loginpassword

Displays the password text box for the login form.

pt:ptui.loginbutton

Displays the login button.

pt:ptui.loginauthsource

Displays the authentication source input. Note: This tag is string- and case-sensitive. The name of the authentication source must match the entry in portalconfig.xml.

pt:ptui.loginrememberme

Displays the "Remember My Password" checkbox for the login form.

pt:ptui.loginoptionsenabled

Conditionally processes content based on the parameters specified (e.g., remembermypassword).

pt:ptui.error and pt.ptui.errortext

Displays portal error messages. Can be used as singleton or wrapper for formatted error text. The ptui.errortext tag is used to reformat or modify error message text.

<pt:ptui.error>
<p style="msg1">
<pt:ptui.errortext pt:text="Call support at 555-1212"/>
</p>
</pt:ptui.error>

pt:ptui.include

Used to include JSComponent scripts, string files and css files.

pt:ptui.rulesdebug

Displays a debug button to display experience rules debugging messages in a popup window. Can be used as singleton or wrapper for HTML.


Implementing Custom UI Elements Using Adaptive Tags

UI tags can be used to insert Oracle WebCenter Interaction UI elements in portlets to create custom UI layouts.

The sample code below implements standard portal header elements using tags. You can also add navigation elements to any portlet using Navigation Tags. For details, see Navigation Adaptive Tag Library (pt:plugnav). Additional tags from the Standard tag library can be used to display instance-specific information, including the date and time and the page name and type. For details, see Standard Adaptive Tag Library (pt:standard) .

<span xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>

<!-- Topbar -->
<table cellpadding="0" cellspacing="0" width="100%" border="0" class="banTopbarBg" id="pt-topbar">
  <tr>
    <td align="left" valign="middle" nowrap="nowrap">
      <pt:ptui.myhome pt:usespan="true"/>
      <span class="banGreetingText banText" id="pt-user-nav">
      <pt:ptui.welcome pt:usespan="true" />
      <span class="spacer" style="padding-left:8px;"></span>
      <pt:ptui.myaccount pt:usespan="true" />
      <span class="spacer" style="padding-left:8px;"></span>
      <pt:ptui.login pt:usespan="true"/> 
      </span>
    </td>
    <td align="right" valign="middle" nowrap="nowrap">
      <pt:ptui.rulesdebug/>
      <pt:ptui.help/>
      <pt:ptui.searchform pt:usespan="true">
      <pt:ptui.basicsearchbutton/>
      <pt:ptui.advancedsearchbutton/>
      <pt:ptui.federatedsearchbutton/>
      </pt:ptui.searchform>
    </td>
  </tr>
</table>
<!-- Topbar section end -->
</span>

Data Adaptive Tag Library (pt:ptdata)

The Data tag library (pt:ptdata) provides access to URLs for most navigation-related components, such as a user's my pages, my communities, subcommunities, my account page or administration.

The tags in the pt:ptdata tag library are available for use only in Oracle WebCenter Interaction. Data tags return URL attributes as data; they must be used in conjunction with a display tag (navigation tags or pt:core.html).

Each data tag requires an ID that is set with an attribute and returns a single URL, a collection of URLs, or nothing. Data tags might return no URL at all if a user does not have access to the referenced page. You can also create a collection of data tags by setting the same ID on multiple data tags.

<pt:ptdata.mypageactionsdata pt:id="mypagemenu" />
<pt:ptdata.mypagesdata pt:id="mypagemenu" />

In addition to the URL, each navigation data tag also provides additional information, such as the title of the URL and the icon associated with the URL. Certain types of URLs also contain objectIDs, classIDs, or a current page flag. It is also possible to get values for individual query string parameters from an URL. The URL and all other data is stored as a dataobject (DO) component. Each DO component can be accessed through a text replacement syntax. Data tags take in the following URL attributes: title, url, uri, img, imgwidth, and imgheight. For example, the following code gets the title and URL component from the mydata URL.

<pt:ptdata.administrationdata pt:id="mydata" />
<pt:logic.value pt:value="$mydata.title"/>
<pt:logic.value pt:value="$mydata.url"/>

After transformation, this code generates the following data: "Administration http://servername/portal/server.pt?open=space&name=ObjMgr&parentid=7&parentname=ObjMgr&control=AdminRedirect&in_hi_userid=1&cached=true
(The title text "Administration" comes from the first value tag, and the URL comes from the second value tag.)

The tables below summarize available data tags. For an example of implementing custom navigation using data tags, see Navigation Adaptive Tag Library (pt:plugnav). For a full list of tags and attributes for each tag, see the tagdocs.

Basic Portal Components: These tags provide URLs to access standard portal components, including login/logoff, Administration, Directory, search, and online help.

Tag Function

pt:ptdata.loginlogoffdata

Returns URL to Login/Logoff action based on the current state of the user. (If the user is logged in, the URL executes logoff; if the user is not logged in, the URL executes login.)

pt:ptdata.myaccountdata

Returns URL to current user's My Account page.

pt:ptdata.administrationdata

Returns URL to portal Administration. The URL is only returned if the user has permission to access Administration.

pt:ptdata.directorybrowsedata

Returns URL to the portal Directory in browse mode.

pt:ptdata.directoryeditdata

Returns URL to the portal Directory in edit mode.

pt:ptdata.advancedsearchdata

Returns URL to the Advanced Search page.

pt:ptdata.federatedsearchdata

Returns URL to the Federated Search page.

pt:ptdata.helppagedata

Returns URL to the portal online help.

pt:ptdata.genericurl

Returns URL based on parameters set in tag attributes.


MyPages: These tags provide URLs to MyPage components, including editors.

Tag Function

pt:ptdata.mypagesdata

Returns a list of URLs to the user's MyPages.

pt:ptdata.mypageactionsdata

Returns a list of URLs to the user's MyPage-related actions.

pt:ptdata.editmypageactionsdata

Returns URL to launch the Edit MyPage editor.

pt:ptdata.editmypageportletprefsdata

Returns URL to launch the Edit MyPage Portlet Preferences editor.

pt:ptdata.createnewmypagedata

Returns URL to launch the Create New MyPage editor. The URL is not returned if the user already has the maximum number of MyPages.

pt:ptdata.addmypageportletsdata

Returns URL to launch the Add Portlets to MyPages editor.

pt:ptdata.deletemypagedata

Returns URL to the Delete MyPage action. The URL is not returned if the user is on the main MyPage.


Experience Definitions: These tags provide URLs to experience-specific components as specified in the experience definition associated with the current user.

Tag Function

pt:ptdata.myhomedata

Returns URL to current user's Home page as specified in the associated experience definition.

pt:ptdata.mandatorylinksdata

Returns a list of URLs to the user's Mandatory Links as specified in the associated experience definition.

pt:ptdata.mandatorylinksnamedata

Returns the name of the Mandatory Links folder as a string.


Communities: These tags provide URLs to community components, and lists of URLs for community pages that meet specific conditions, including subcommunities, related communities, and a user's current communities.

Tag Function

pt:ptdata.mycommunitiesdata

Returns a list of URLs to the communities in the user's My Communities list.

pt:ptdata.mandtabcommsdata

Returns a list of URLs to the user's mandatory communities.

pt:ptdata.communitypagesdata

Returns a list of URLs to the pages in the specified community.

pt:ptdata.currcommunitypagesdata

Returns a list of URLs to the pages in the current community.

pt:ptdata.subcommunitiesdata

Returns a list of URLs to the subcommunities for the specified community.

pt:ptdata.currsubcommunitiesdata

Returns a list of URLs to the subcommunities for the current community.

pt:ptdata.relatedcommunitiesdata

Returns a list of URLs to the related communities for the specified community.

pt:ptdata.currrelatedcommunitiesdata

Returns a list of URLs to the related communities for the current community.

pt:ptdata.communitykddata

Returns the URL to the community Knowledge Directory

pt:ptdata.communityactionsdata

Returns a list of URLs to the user's community-related actions.

pt:ptdata.editcommunitydata

Returns URL to launch the Community Editor for the current community.

pt:ptdata.createnewcommpagedata

Returns URL to launch the Create New Community Page page of the Community Editor. The URL is returned only if the user has permission to edit the community.

pt:ptdata.addcommunityportletsdata

Returns URL to launch the Add Portlets page of the Community Editor. The URL is returned only if the user has permission to edit the community.

pt:ptdata.joincommunitiesdata

Returns URL to launch Join Communities editor.

pt:ptdata.joinparentcommunitydata

Returns URL to launch Join Communities editor for the parent Community of the current Community.

pt:ptdata.joincurrcommunitydata

Returns URL to the Join Current Community action.

pt:ptdata.joincurrparentcommunitydata

Returns URL to the Join Current Community action for the parent Community of the current Community.

pt:ptdata.unsubscribecommunitiesdata

Returns URL to the Unsubscribe Communities editor.

pt:ptdata.navsettingvalue

Returns a list of URLs to the communities listed in the NavigationSettings.xml file, specified by the commID attribute.

pt:ptdata.communityhierdata

Takes in one or more community IDs and creates a hierarchical data collection of pages for the specified communities. Hierarchical data tags are used with display tags with nested data such as a tree or multi-level dropdown menus.


Adaptive Tag Control Flow

This page describes the control flow of a typical portal request that makes use of Adaptive Tags.

  1. First, the portal page requests portlet data from the Transformer.

  2. The Transformer retrieves the requested portlets from the remote portlet servers. Native UI tags, such as JSP Tags or .NET web controls, are processed on the remote server before the HTML is returned to the Transformer.

  3. The Transformer converts the HTML into markup data including both HTML and Adaptive Tags. This markup data is passed to the Tag Transformation Engine, which processes the tags and converts them into standard HTML.

  4. Finally, the HTML is returned to the portal page where it is displayed to the end user.

The Tag Transformation Engine converts markup data from the Transformer into a tree of HTML and Adaptive Tags. The Engine moves through the tree and outputs HTML and processes the tags. When a tag is processed, it can cause all of its child nodes to be processed, or it can skip that entire section of the tree.

In this example, when the choose tag is executed, it determines whether or not the current user matches the conditions in the choose clause. If it does, the When tag will display the HTML inside the tag. If not, the otherwise tag will display its HTML.

Creating Custom Adaptive Tags

The Adaptive Tag Framework allows you to create custom tags for use in portlets and gatewayed pages. For example, the portletdefaultlayout.html file in the pagelayouts directory on the imageserver uses a tag definition.

The easiest way to define a custom tag is by using the pt:core.tagdef tag and the associated tag library. Custom tag definitions are declared in the tag definition file (tagdef.html), by default located on the portal Image Service. This file is automatically processed when the pt:logic.includetagdef tag is used to display a custom tag definition. It is also possible to declare tag definitions in portlets or adaptive layout files, but the tag definition will only be available on that page. Adaptive tags in a tag definition are not executed until displayed with the pt:logic.includetagdef.

Tag Function

pt:core.tagdef

Defines a block of arbitrary HTML and/or tags to display in multiple locations.

pt:core.tagdefshared

Defines a block of content that is only displayed once per page for each tag definition. Use this tag for Javascript, CSS or HTML that is shared between multiple tag definitions.

pt:core.tagdefarg

Defines the argument values expected by the tag definition. Argument values are passed to tag definitions by declaring XML attributes on the includetagdef tag.

pt:core.includetagdef

Displays tag definitions, the blocks of HTML and Adaptive Tags created by the pt:logic.tagdef tag. Use tag variables to pass run-time parameters to tag definitions. Names and values of XML attributes (attributes without the pt: prefix) will be converted to tag scope tag variables.


In the example below from the tagdef.html file, the script that implements the tag functionality is removed for simplicity.

<pt:core.tagdef pt:defid="menuentry">
  <pt:core.tagdefarg pt:name="label" pt:desc="Label text to display" />
  <pt:core.tagdefarg pt:name="data"  pt:desc="Name of tag variable with tag data to populate the tree with" />
  <pt:core.tagdefarg pt:name="scope" pt:defaultvalue="portlet request"         pt:desc="Tag scope where the tag data is set" /> 
    <script type="text/javascript">
      ....
    </script>
</pt:core.tagdef>

<pt:core.tagdef pt:defid="menubar">
  <pt:core.tagdefarg pt:name="menuid"     pt:desc="Identifier for this menu instance." />
  <pt:core.tagdefarg pt:name="vertical"   pt:defaultvalue="0" pt:desc="Pass in 1 to display menu labels vertically, 0 to display horizontally" />
  <pt:core.tagdefarg pt:name="labelClass" pt:defaultvalue=""  pt:desc="CSS class to style labels in menu"  />            
   <script type="text/javascript">
    ...
   </script>
</pt:core.tagdef>

In the portlet that displays the custom tag definition, the includetagdef tag uses variables to pass arguments to the tag definition.

<pt:ptdata.communityhierdata pt:id="commdata1" pt:commid="200"/>
<pt:ptdata.communityhierdata pt:id="commdata2" pt:commid="201"/>

<pt:core.includetagdef pt:defid="menubar"   menuid="topbar" />         
<pt:core.includetagdef pt:defid="menuentry" menuid="topbar" data="commdata1" label="Menu Item 1" /> 
<pt:core.includetagdef pt:defid="menuentry" menuid="topbar" data="commdata2" label="Menu Item 2" />

For more information and sample code, see the tagdocs.

Coding Custom Tags with the ATag Base Class

If you want to define a custom tag for a range of use in multiple applications, the Adaptive Tag Framework provides support for developing custom tags in both Java and .NET. The ATag class is the base class used to write custom tags. To implement a custom tag, follow the steps below.

  1. To implement a new tag, you must have a tag library. A tag library is simply a .jar or .dll file with exactly one class that implements ITagLibraryMetaData.

    Java

    public static final TagLibraryMetaData LIBRARY = new TagLibraryMetaData("Sample Tags", "sample", "This library provides sample tags.", 1.0);
    

    .NET

    public static readonly TagLibraryMetaData LIBRARY = new TagLibraryMetaData("Sample Tags",  "sample", "This library provides sample tags.", 1.0);
    
  2. Create one public static final ITagMetaData member variable that provides the name and description of the tag. Create a public static final RequiredTagAttribute or OptionalTagAttribute member variable for every attribute that the tag supports. You can also use standard HTML and XML attributes; see Accessing Attributes in Custom Adaptive Tags.

    Java

    public static final ITagMetaData TAG;
    public static final RequiredTagAttribute MESSAGEATTRIBUTE;
    public static final OptionalTagAttribute LOCATIONATTRIBUTE;
    
    static
    {
    TAG = new TagMetaData("hellolocation", "This tag displays a hello message for the given location.");
    MESSAGEATTRIBUTE = new RequiredTagAttribute( "message", "The message to display for hellolocation tag", AttributeType.STRING); 
    LOCATIONATTRIBUTE = new OptionalTagAttribute("location", "The sample location attribute for hellolocation tag", AttributeType.STRING, "World");
    }
    

    .NET

    public static readonly ITagMetaData TAG;
    public static readonly RequiredTagAttribute MESSAGEATTRIBUTE;
    public static readonly OptionalTagAttribute LOCATIONATTRIBUTE;
    
    static HelloLocationTag()
    {
    TAG = new TagMetaData("hellolocation", "This tag displays a hello message for the given location.");
    MESSAGEATTRIBUTE = new RequiredTagAttribute( "message", "The message to display for hellolocation tag", AttributeType.STRING); 
    LOCATIONATTRIBUTE = new OptionalTagAttribute("location", "The sample location attribute for hellolocation tag", AttributeType.STRING, "World");
    }
    

    Type validation is performed by the tag framework automatically. If an optional attribute is not present in the HTML, the tag framework will use the default value. In the same code below, the optional attribute has a default value of "World.".

  3. Implement the DisplayTag abstract method. Use this method to create and display HTML. To display any HTML and tags defined within the tag, call ProcessTagBody and return the resulting HTML. The sample code below adds the "Hello" string with a user-specified location to an HTMLElement and returns it to be displayed.

    Java

    public HTMLElement DisplayTag()
    {
    String strLocation = GetTagAttributeAsString(LOCATIONATTRIBUTE);
    String strMessage = GetTagAttributeAsString(MESSAGEATTRIBUTE);
    HTMLElementCollection result = new HTMLElementCollection();
    result.AddInnerHTMLString(strMessage + strLocation + "!");
    return result;
    }
    

    .NET

    public override HTMLElement DisplayTag()
    {
    String strLocation = GetTagAttributeAsString(LOCATIONATTRIBUTE);
    String strMessage = GetTagAttributeAsString(MESSAGEATTRIBUTE);
    HTMLElementCollection result = new HTMLElementCollection();
    result.ddInnerHTMLString(strMessage + strLocation + "!");
    return result;
    }
    
  4. If the tag should not display any HTML contained within the tag, use the GetTagType method to return TagType.NO_BODY.

    Java

    public TagType GetTagType()
    {
    return TagType.NO_BODY;
    }
    

    .NET

    public override TagType GetTagType()
    {
    return TagType.NO_BODY;
    }
    
  5. Implement the Create abstract method to return a new instance of the tag.

    Java

    public ATag Create()
    {
    return new HelloLocationTag();
    }
    

    .NET

    public override ATag Create()
    {
    return new HelloLocationTag();
    }
    

The ATag class allows you to include a wide range of functionality in custom tags. For a full list of interfaces and methods, see the tagdocs. For links to all tagdocs, see Appendix A, "API Libraries". For details on deploying your custom tag, see Deploying Custom Adaptive Tags.

Accessing Browser Session Information in Custom Adaptive Tags

To access browser session information from a custom adaptive tag, use the IEnvironment class.

The IEnvironment class provides access to information about the current request and user, including the following:

  • HTTP Request and Response: Retrieve the Request or Response objects, or the Request URL. For example: IXPRequest request = GetEnvironment().GetCurrentHTTPRequest();

  • User information: Retrieve the user's session, or key information including language, locale, time zone, and access style (standard, 508, or low bandwidth). For example: String strTZ = GetEnvironment().GetTimeZone();

  • VarPacks: Retrieve any VarPacks associated with the application in which the tag is executed.

Accessing Attributes in Custom Adaptive Tags

To access attributes used in a custom tag, use one of the GetTagAttribute* methods.

All basic data types are supported as attributes (defined in the AttributeType class), including boolean, char, double, int, long and string. The "pt:" attributes specify the logic for the tag, while any non-pt attributes specify the behavior of the resulting HTML tag. Non-pt attributes are only applicable in tags that output a simple HTML tag.

  • To access pt attributes, use the appropriate GetTagAttributeAs* method using the attribute name. A method is provided for each supported attribute type, e.g., GetTagAttributeAsLong. The GetTagAttribute method is provided for backwards compatibility and should not be used.

    1. First, define the attribute: MODE = new OptionalTagAttribute("mode", "Turns debug mode on and off.", AttributeType.BOOLEAN, "true");

    2. Then, access the attribute in the DisplayTag method:boolean bNewDebugMode = GetTagAttributeAsBoolean(MODE);

  • To access non-pt (XML/HTML) attributes, use the GetXMLTagAttribute method using the attribute name, or GetXMLTagAttributesAsString to retrieve all non-pt attributes. result.AddInnerHTMLElement(new HTMLGenericElement("<a href=\"" + GetHREF() + "\" " + GetXMLTagAttributesAsString() + ">"));

The ITagMetaData, RequiredTagAttribute, and OptionalTagAttribute objects pre-process tag attributes (presence, correct type, and default values). If the required attributes are not correct, an error is logged and the tag and its children are skipped. An HTML comment describing the tag and error is displayed instead.

Storing and Accessing Custom Data in Custom Adaptive Tags

To store custom data as member variables using a custom tag, use the SetStateVariable or SetStateSharedVariable methods. To retrieve it, use GetStateVariable or GetStateSharedVariable.

Standard variables (stored with SetStateVariable) can only be accessed by tags in the same library. Shared variables (stored with SetStateSharedVariable) can be accessed by tags from any library. To prevent tags from other libraries from editing a shared variable, set bOwnerEditOnly to true when the shared variable is stored (tags in other libraries will still be able to read the variable).The Scope parameter determines who can see the data and how long it stays in memory. The following options are defined in the Scope class:

Scope Description

Application Scope

Data is visible to all tags and all users, and is only removed when the application is restarted. Therefore, care should be used when storing data on the application to make sure it does not become cluttered with large amounts of data.

HTTP Request Scope

Data will be visible to all tags in the same HTTP Request as the current tag, and is removed from memory when the HTTP Request is finished.

Session Scope

Data is visible to all tags for the current user, and is cleared from memory when a user logs out and logs in again.

Persistent Session Scope

Data is visible to all tags in the same HTTP session, and is only removed from memory when the browser is closed or the browser session times out. Note: Data is not cleared on user logout, so do not cache anything on this scope that could be considered a security risk if it was leaked to another user. Most tags should use Session Scope for HTTP Session data storage (as described above).

Portlet Request Scope

Data is visible to all tags in the same portlet as the current tag, and is removed from memory when the portlet is finished displaying. Tags in other portlets on the same page will not be able to see the data.

Tag Scope

Data can only be seen by children of the current tag and is removed from memory when the tag is finished. (For example, in the following tags: <pt:atag><pt:btag/></pt:atag><pt:ctag/>, data stored in Tag Scope by "atag" would be visible to "btag" but not to "ctag.")


If data is stored directly in the tag in member variables (not recommended), override the ReleaseTag method to release the data stored on the tag.

/** 
* @see com.plumtree.portaluiinfrastructure.tags.ATag#ReleaseTag() 
*/ 
public void ReleaseTag() 
{ 
// Release all member variables. 
m_strPreviousRequestURL = null; 
}

Note:

Displaying an HTMLElement in a tag and caching it so another tag can add more HTML is not supported. HTMLElement trees can be generated and stored for later use as long as they are self-contained trees and used in a read-only way. It is safest to clone a cached HTMLElement tree before trying to display it again to make sure there are no threading problems.

Note:

It is a best practice not to use static fields for data storage in tags. Each tag instance is guaranteed to be accessed by only a single thread at a time, but there may be multiple threads accessing different instances of the same tag class at the same time, either from the same user or a different user. This means that any static fields must be accessed using synchronized methods. Since there can be multiple instances of the same tag running at the same time, state variables set in shared scopes (Session, Persistent Session and Application) could change values during the execution of a single tag.

Including JavaScript in Custom Adaptive Tags

To include JavaScript in a tag, use the AddJavaScript method inside the DisplayTag method.

For example:

HTMLScriptCollection scriptCollection = new HTMLScriptCollection(); 
HTMLScript script = new HTMLScript("text/javascript"); 
scriptCollection.AddInnerHTMLElement(script); 
script.AddInnerHTMLString("function myTest() { alert('test'); }"); 
AddJavascript(scriptCollection);

To include common JavaScript that can be shared between multiple instances of a tag (i.e. JavaScript that is displayed once per page, regardless of how many tags of a certain type there are), override the DisplaySharedJavascript method. DisplaySharedJavaScript is called automatically by the framework.

/** 
* Adds the PTIncluder object to the client.  This object is used for 
* retrieving JSComponent client classes from a page. 
*/ 
public HTMLScriptCollection DisplaySharedJavascript() 
{ 
HTMLScriptCollection result = new HTMLScriptCollection(); 
HTMLScript script = new HTMLScript("text/javascript"); 
result.AddInnerHTMLElement(script); script.SetSrc("/myjsfile.js"); 
return result; 
}

If there are errors in the tag and the JavaScript cannot be displayed properly, the tag should throw an XPException with an error message, and the tag framework will log the error and add the message and stack trace to the HTML as an HTML comment. The message contents will be HTML encoded before being added to the comment.

Note:

JavaScript is not displayed in 508 mode for either method, since section 508 compliant browsers do not support JavaScript.

Using Nested Tags in Custom Adaptive Tags

Tags can be used within other tags. To implement nested tags, use the RequiredParentTag, RequiredChildTag and RelatedChildTag member variables.

The outer tag is referred to as the "parent" tag. Any tags within a parent tag are referred to as "child" tags of that tag. If the tag is only intended for use within a particular parent tag, create a public static final RequiredParentTag member variable. If there are multiple RequiredParentTag members, at least one of the parent tags must be present for the child tag to function. If the tag must include a particular child tag to function, create a public static final RequiredChildTag member variable for each tag that is required inside the parent tag. If the child tag is not required for the parent tag to function, but is still related to that tag, create a public static final RelatedChildTag member variable instead.

public static final RequiredChildTag DATA_OBJECT; 
static 
{ 
... DATA_OBJECT = new RequiredChildTag(DataObjectTag.TAG); 
}

Note:

If required parent or child tags are missing when a tag is displayed, the tag framework will not process the incorrect tag and will add an error message to the HTML as an HTML comment.

Implementing Non-Standard Custom Adaptive Tag Types

To implement non-standard tag types in custom adaptive tags, including 508-accessible, looping or singleton tags, override the associated method.

  • To display a custom tag in non-standard access styles (508 or low bandwidth), override the SupportsAccessStyle method. The default implementation of the SupportsAccessStyle method will cause the tag to be skipped in 508 and low-bandwidth mode. Make sure that tags that support 508 mode can function without JavaScript, since JavaScript will not be displayed in 508 mode.

  • If the tag displays the tag body more than once (looping tag), override the GetTagType() method and return TagType.LOOPING.

  • If the tag never displays the tag body (singleton tag), override GetTagType() and return TagType.NO_BODY.

Deploying Custom Adaptive Tags

To deploy custom adaptive tags, follow these steps.

  1. Navigate to PORTAL_HOME\settings\portal and open CustomTags.xml in a text editor (you might need to make the file writeable).

  2. Find the <AppLibFiles> tag and add a new entry using the name of the .jar/.dll file used to define the custom tag library (e.g., mytags).

    <AppLibFiles>
    <libfile name="sampletags"/>
    </AppLibFiles>
    
  3. Add the custom implementation (.jar/.dll) to the portal hierarchy:

    • Java: Copy the custom .jar file to PORTAL_HOME\lib\java and add it to the portal.war file in PORTAL_HOME\webapp. (You must stop the portal while modifying portal.war because it will be locked while the portal is running.)

    • .NET: Copy the custom .dll file to PORTAL_HOME\webapp\portal\bin.

  4. Run a clean build of the portal to refresh all the jar files associated with the portal.

  5. Once you have deployed your code, create a portlet that contains the tag. Custom Adaptive Tags must either include the correct XML namespace or be contained within another tag that does. The simplest way is to put the HTML inside a span. Custom adaptive tags must use the pt:libraryname.tagname and pt:attributename format. The sample code below references the custom tag from Creating Custom Adaptive Tags.

    <span xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
    <pt:sample.hellolocation pt:message="Hello" pt:location="San Francisco"/>
    </span>
    
  6. Add the portlet to a portal page and view the page. Test all custom tags.

The Oracle WebCenter Interaction Scripting Framework

The Oracle WebCenter Interaction Scripting Framework is a client-side JavaScript library that provides services to portlets and hosted gatewayed pages. The Portlet Communication Component (PCC) is contained within the Scripting Framework.

The Oracle WebCenter Interaction Scripting Framework allows portlets to:

For a full list of classes and methods, see the JSPortlet API documentation.

Oracle WebCenter Interaction Scripting Framework Development Tips

These tips and best practices apply to all code that utilizes the Oracle WebCenter Interaction Scripting Framework.

  • Use unique names for all forms and functions. Use the GUID of a portlet to form unique names and values to avoid name collisions with other code on the page. You can append the portlet ID using the pt:namespace and pt:token tags, as shown in the code below.

    <pt:namespace pt:token="$$TOKEN$$" xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>
    <a onclick="doStuff$$TOKEN$$();" href="#">do stuffa onclick="doStuff$$TOKEN$$();" href="#">do stuff</a>
    <script>
    function doStuff$$TOKEN$$() {
    alert("hello");
    }
    </script>
    

    Valid values for the token are in the ASCII range 0x21 to 0x7E, excluding "<" (0x3C). The scope of the token runs from the tag defining it to the end of the file; you cannot use a token prior to defining it. A second pt:namespace tag with a different token redefines it; two tokens cannot be defined at the same time.

  • Gateway all URLs. You cannot make a request to a URL whose host/port differs from that of the calling page. All URLs requested through JavaScript must be gatewayed. For details on the gateway, see Portlets and the Gateway.

  • Check for Scripting Framework support. It is good practice to include code that determines whether or not the component is present. Ideally, your portlet should be able to handle either situation. The simplest solution is to precede your code with an If statement that alerts the user if the Scripting Framework is not supported.

    <script>
    if (PTPortlet == null) 
      {
      if (document.PCC == null) 
        {
        alert("This portlet only works in portals that support the JSPortlet API or Portlet
        Communication Component (PCC). The portlet will be displayed with severely reduced
        functionality. Contact your Administrator.");
        }
      }
    else 
      {
      [scripting code here]
      }
    </script>
    
  • Close all popup windows opened by a portlet when the portal window closes. The Scripting Framework can be used to close popup windows using the onunload event.

Using Oracle WebCenter Interaction Scripting Framework Event Notification

The Oracle WebCenter Interaction Scripting Framework allows portlet to respond to both page-level events and custom events raised by other portlet.

The registerForWindowEvent and registerOnceForWindowEvent methods in the Oracle WebCenter Interaction Scripting Framework provide portlets with access to page-level events. For a complete list, see Page-Level Events for Use with the Oracle WebCenter Interaction Scripting Framework. To register for notification of these events, pass in the name of the event and the name of the method that should be called when it occurs. When a page-level event is raised, the JavaScript event object is passed to the event handler as an argument. The Oracle WebCenter Interaction Scripting Framework also allows portlets to raise and respond to custom events using raiseEvent and registerForEvent. The Broadcast-Listener design pattern illustrates an important example of using notification services with session preferences. Users can select an item or perform some other action in a "broadcast" portlet, which causes the content in other related "listener" portlet to be redrawn. In the following example, the broadcast portlet displays a form that allows you to enter a number in a text box. When the user enters a number in the text box, the values in the listener portlets change. The first listener portlet displays the square root of the number entered in the broadcast portlet. The second listener portlet displays the cube root of the number entered in the broadcast portlet. The following steps summarize how the portlets work:

  • On load, each listener portlet calls its own instance method (registerForEvent) to register for events of type 'onBroadcastUpdate'.

  • On each onkeyup event that occurs in the "Enter number" text box, the broadcast portlet sets a session preference to the value entered in the text box, and calls its own instance method (raiseEvent) to raise an event of type 'onBroadcastUpdate'.

  • When the 'onBroadcastUpdate' event is raised or the page is reloaded, each listener portlet retrieves the session preference set by the broadcast portlet and computes a new value to display based on the value of the preference.

Broadcast Portlet

<div style="padding:10px;" align="center">
<p><b>Enter number:</b>
&nbsp;<input type="text" style="font-size:22px;font-weight:bold;text-align:center;"
id="broadcast_prefName" value="4" size="7" onkeyup="broadcast_setPrefs(this.value)"></p>
<br>
</div>

<script type="text/javascript">

function broadcast_setPrefs(val)
{
        var prefName = 'broadcastNumber';
        var prefValue = val;
        PTPortlet.setSessionPref(prefName,prefValue);

        var broadcastPortlet = PTPortlet.getPortletByGUID('{D9DFF3F4-EAE7-5478-0F4C-2DBD94444000}');

        if (!broadcastPortlet)
        {
                broadcast_debug('Could not locate PTPortlet object which corresponds to <b>Broadcast Portlet</b> on page.');
                return;
                }

        broadcast_debug('<b>Broadcast Portlet</b> raising onBroadcastUpdate event.');
        broadcastPortlet.raiseEvent('onBroadcastUpdate',false);

}

function broadcast_debug(str)
{
        if (window.PTDebugUtil) 
        { 
                PTDebugUtil.debug(str); 
        }
}
</script>



Listener Portlet #1

<div style="padding:10px;" align="center">
<p><b>Square root:</b>
<div style="height:21px;border:2px solid black;padding:2px;overflow:visible;font-size:14px;"id="listener1-swatch">
</div>
</div>

<script>

function listener1_update()
{
        var broadcastNumber = parseFloat(PTPortlet.getSessionPref('broadcastNumber'));
        if (isNaN(broadcastNumber))
        {
                listener1_error('<b>Listener-1 Portlet</b> cannot parse number from session pref broadcastNumber');
                return;
        }

        listener1_debug('<b>Listener-1 Portlet</b> computing square root of ' + broadcastNumber);
        var swatch = document.getElementById('listener1-swatch');
        swatch.innerHTML = Math.sqrt(broadcastNumber);
}

function listener1_debug(str)
{
        if (window.PTDebugUtil) 
        { 
                PTDebugUtil.debug(str); 
        }
}

function listener1_error(str)
{
        if (window.PTDebugUtil) 
        { 
                PTDebugUtil.error(str); 
        }
}

function listener1_getPortlet()
{
        var portletGUID = '{D9DFF3F4-EAE7-5478-0F4C-2DBDB4F4A000}';
        var listener1Portlet = PTPortlet.getPortletByGUID(portletGUID);
        return listener1Portlet;
}

var listener1Portlet = listener1_getPortlet();
if (listener1Portlet)
{
        listener1Portlet.registerForEvent('onBroadcastUpdate','listener1_update');
        listener1_debug('<b>Listener-1 Portlet</b> registered refreshOnEvent for event onBroadcastUpdate');
        listener1Portlet.registerForEvent('onload','listener1_update');
}

</script>

Listener Portlet #2

<div style="padding:10px;" align="center">
<p><b>Cube root:</b>
<div style="height:21px;border:2px solid black;padding:2px;overflow:visible;font-size:14px;"id="listener2-swatch">
</div>
</div>

<script>
var listener2_oneThird = (1/3);

function listener2_update()
{
        var broadcastNumber = parseFloat(PTPortlet.getSessionPref('broadcastNumber'));
        if (isNaN(broadcastNumber))
        {
                listener2_error('<b>Listener-2 Portlet</b> cannot parse number from session pref broadcastNumber');
                return;
        }

        listener2_debug('<b>Listener-2 Portlet</b> computing square root of ' + broadcastNumber);

        var swatch = document.getElementById('listener2-swatch');
        swatch.innerHTML = Math.pow(broadcastNumber,listener2_oneThird);
}

function listener2_debug(str)
{
        if (window.PTDebugUtil) 
        { 
                PTDebugUtil.debug(str); 
        }
}

function listener2_error(str)
{
        if (window.PTDebugUtil) 
        { 
                PTDebugUtil.error(str); 
        }
}

function listener2_getPortlet()
{
        var portletGUID = '{D9DFF3F4-EAE7-5478-0F4C-2DBDCA1C7000}';
        var listener2Portlet = PTPortlet.getPortletByGUID(portletGUID);
        return listener2Portlet;
}

var listener2Portlet = listener2_getPortlet();
if (listener2Portlet)
{
        listener2Portlet.registerForEvent('onBroadcastUpdate','listener2_update');
        listener2_debug('<b>Listener-2 Portlet</b> registered refreshOnEvent for event onBroadcastUpdate');
        listener2Portlet.registerForEvent('onload','listener2_update');
}
</script>
Page-Level Events for Use with the Oracle WebCenter Interaction Scripting Framework

The Oracle WebCenter Interaction Scripting Framework automatically has access to the following page-level events.

Event Triggered:

onload

immediately after the browser loads the page

onbeforeunload

prior to a page being unloaded (browser window closes or navigates to different location)

onunload

immediately before the page is unloaded (browser window closes or navigates to different location)

onactivate

the page is set as the active element (receives focus)

onbeforeactivate

immediately before the page is set as the active element (receives focus)

ondeactivate

when the active element is changed from the current page to another page in the parent document

onfocus

when the page receives focus

onblur

when the page loses focus

oncontrolselect

when the user is about to make a control selection of the page

onresize

when the size of the page is about to change

onresizestart

when the user begins to change the dimensions of the page in a control selection

onresizeend

when the user finishes changing the dimensions of the page in a control selection

onhelp

when the user presses the F1 key while the browser is the active window

onerror

when an error occurs during page loading

onafterprint

immediately after an associated document prints or previews for printing


Using In-Place Refresh

To refresh portlet content in place, without affecting other content on the page, use the Oracle WebCenter Interaction Scripting Framework to implement in-place refresh.

Many portlet display data that is time sensitive. In some cases, users should be able to navigate across links within a portlet without changing or refreshing the rest of the portal page. You can refresh portlet content on command, associate the refresh action with an event (refreshOnEvent), or program the portlet to refresh at a set interval (setRefreshInterval). The Oracle WebCenter Interaction Scripting Framework also contains methods for expanding and collapsing portlet. In the simplified example below, the refresh portlet displays a "Refresh Portlet" button. Clicking the button updates the date and time displayed in the portlet. (The refresh button in the portlet header is an optional feature available in Oracle WebCenter Interaction, configured on the Advanced Settings page of the Web Service editor.)The in-place refresh is executed by calling the refresh() method on the portlet object instance. The portlet reference can be retrieved by GUID, ID or name, available via the Oracle WebCenter Interaction Development Kit (IDK) IPortletRequest interface. You can also set a new URL to be displayed within the portlet upon refresh by using setRefreshURL or passing in a new URL when you call refresh. (The title bar cannot be altered on refresh.)

<div style="padding:10px;" align="center">
<p><button onclick="refresh_portlet()">Refresh Portlet</button></p>
<p><b>Current time is:</b><br> <span id="refreshTimeSpan"></span></p>
</div>
<pt:namespace pt:token="$PORTLET_ID$" xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>

<script type="text/javascript"> 
function refresh_portlet()
{
var refreshPortlet = PTPortlet.getPortletByID($PORTLET_ID$);
if (!refreshPortlet)
  {
  refresh_debug('Could not locate PTPortlet object which corresponds to <b>Refresh Portlet</b> on page.');
  return;
  }
refresh_debug('<b>Refresh Portlet</b> calling refresh() method.');
refreshPortlet.refresh();
}

function refresh_debug(str)
{
if (window.PTDebugUtil) 
  { 
  PTDebugUtil.debug(str); 
  }
}

var t = new Date();
document.getElementById('refreshTimeSpan').innerHTML = t;
</script>

Adaptive Portlet Development Tips

These tips apply to most adaptive portlets.

  • Gateway all URLs. You cannot make request to a URL whose host/port differs from that of the calling page. All URLs requested through JavaScript must be gatewayed. For details on the gateway, see Portlets and the Gateway.

  • Add all required JavaScript to the page in advance. Browsers might not process script blocks/includes added to the page through the innerHTML property.

    • IE: Add the defer attribute to the script tag.

    • Netscape: Use RegExp to parse the response and look for the script, then eval it.

  • JavaScript HTTP and gatewayed HTTP must use the same authentication credentials. JavaScript brokered HTTP requests send the same authentication token (cookie) as when you make a normal gatewayed HTTP request.

Portlet Style

Portlets displayed in Oracle WebCenter Interaction should reflect the style of the portal. This section explains how portal configuration affects how a portlet is displayed.

Oracle WebCenter Interaction Portlet Alignment

Where a portlet is displayed on the Oracle WebCenter Interaction portal page defines its size.

The Oracle WebCenter Interaction portal page is made up of columns. In a two-column configuration, narrow portlets are displayed on the left, wide portlets on the right. In a three-column configuration, wide portlets are displayed in the middle. In the Low Bandwidth version of the portal or the Portal for People with Disabilities, width is irrelevant; portlets are displayed in a single column.

When you configure a portlet object in the portal, you may choose from the following alignments:

  • Narrow portlets are displayed in a narrow side column on the portal page. Narrow portlets must fit in a column that is fewer than 255 pixels wide.

  • Wide portlets are displayed in the middle or widest side column on the portal page. Wide portlets fit in a column fewer than 500 pixels wide.

  • Header portlets override the portal header at the top of the page, allowing you to add custom branding to a Community page.

    Note:

    In header portlets, make sure to include the pt:pageName and pt:realmName markup tags. The "realm" name is either the name of the current Community or one of the following: "My Pages," "Documents," "Administration," or "Gateway." The page name is the name of the current page in a Community or My Page or blank otherwise. The localized name will be used if available. For details, see Using Internationalized Strings in Adaptive Tags .

  • Footer portlets override the portal footer at the bottom of the page, allowing you to add custom branding to a Community page.

  • Content Canvas portlets span across all rows and columns of a Community page, taking up all space between the header and footer.

Each My Page or community page is made up of many portlets, selected and arranged based on alignment.

CSS Customization for Oracle WebCenter Interaction Portlets

The CSS template provided with Oracle WebCenter Interaction allows you to customize portlet content and design in a variety of ways. (All portlets should reference the portal style sheet as explained in Adaptive Tags.)

CSS customization allows you to customize specific portlets using the unique portlet ID, or modify the design of a group of portlets (for example, those in the first column of a two-column page). You can also set constraints for portlets, including limiting a specific portlet to a three-column layout or preventing users from collapsing portlets.

The portal CSS template file follows standard CSS syntax rules. For details on CSS, see http://www.w3.org/Style/CSS/.

For details on using CSS to customize portlets, see the Oracle WebCenter Interaction UI Customization Guide.

Oracle WebCenter Interaction Portlet Settings

Most portlets use settings. In some cases, a portlet can access settings stored by another portlet or service.

For details on Oracle WebCenter Interaction portlet settings, see the following sections:

Portlet Settings Development Tips

These tips and best practices apply to all portlets that access settings.

  • Enter all preference and configuration pages used by a portlet in the Web Service editor. You must enter the URL to any preference pages in the Web Service editor on the Preferences page. You must enter the URL to any configuration pages in the Web Service editor on the Advanced URLs page.

  • Enter all User settings and Community Settings required by a portlet in the Preference list in the Web Service editor. If a shared setting is not entered in this list, it will not be available to the portlet.

  • Gateway all pages that store settings in the portal. To store settings on the portal, preference pages must be included in the Gateway Prefixes List, configured in the Web Service editor on the HTTP Configuration page. For instructions on entering gateway prefixes, see the portal online help.

  • Never send query string or form variables directly to the My Page. Always use a separate page to set and remove settings. Sending query string or form variables directly to the portal page is unreliable and can result in seemingly random errors. Your code will not have access to these variables in most cases, because it might be preceded by other code on the portal page.

  • Do not use session preferences for shared settings; portlets on the same portal page and the same remote server cannot use the same session. To implement shared settings, you must use the Application object, store User settings in the portal database, or use the Portlet Communication Component (PCC).

  • Return the user to the location of the portlet on the page when redirecting from a preferences page to a portal page. This can be done using the IDK IPortletResponse.ReturnToPortal method.

  • Always include a link to the correct settings page within the portlet display. It might not be clear to users where they should enter settings for a portlet. If the portlet requires configuration, include a link to the appropriate preference page or configuration page within the portlet display.

  • Always use popup windows for preference pages. Use the following guidelines for all popup windows. The portal window must remain open. Do not redirect the portal window to the destination URL.The popup window should regain focus on any successive click-through. If the user leave the window open and then clicks the same link, the same popup window should regain focus (instead of opening a new window).The popup window should close if the portal window is closed. If the user closes the portal window, any associated popup windows should close automatically.The popup window should appear in the style of the portal. You can reference the stylesheet in any gatewayed page by using the pt:Stylesheets tag as shown in the code snippet below. For details on adaptive tags,

    see . Adaptive Tags.

    <pt:styleSheets xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>
    <div class=platportletHeaderBg>The background here is <i>platportletHeaderBg</i>. <span class=platportletWideHeader>This adds the font style <i>platportletWideHeader</i> from the portal stylesheet.</span></div>
    <p><input type=button class=inputBox value="This button uses the inputBox style">
    

There are some additional considerations if the data stored by a portlet should be secure; for details, see Oracle WebCenter Interaction Portlet Security.

Oracle WebCenter Interaction Portlet Setting Types

Portlets can use seven types of settings (aka preferences) to provide personalized functionality. Each type of setting is intended for a specific range of use, and each is handled differently by the Oracle WebCenter Interaction Development Kit (IDK) and the portal.

Setting Type

User

Portlet

Preference Page Type

Notes

Administrative Setting

All

1 specific

Administrative Preferences page or Portlet Template Preferences page

Administrative settings can be modified only by users with administrative access to the portal and read/write access to the object.

User Setting

1 specific

All

Portlet Preferences page or User Configuration page

User settings must be uniquely named. A portlet has access to the User settings entered by name in the Web Service editor.

Session Preference

1 specific

All

n/a (not stored in portal database) Session preferences can be set using the Oracle WebCenter Interaction Scripting Framework. For details, see Using Session Preferences.

Session preferences are persisted for the duration of the user's session. A portlet has access to the session preferences entered by name in the Web Service editor. Note: Portlets on the same portal page and the same remote server cannot use the same session.

Portlet Setting

1 specific

1 specific

Portlet Preferences page

 

CommunityPortlet Setting

All in a specific community

1 specific

Community Preferences page

Only available when a portlet is displayed in a community (not on a My Page), and can be set only by a community owner.

Community Setting

All in a specific community

All in a specific community

Community Preferences page

Only available when a portlet is displayed in a community (not on a My Page), and can be set only by a community owner. A portlet has access to the Community settings entered by name in the Web Service editor.

User Information Setting

1 specific

All

n/a (not stored in portal database)

User Information settings required by a portlet must be configured in the Web Service editor on the User Information page.


Administrative Preferences and Portlet Template Preferences Pages

Administrative Preference pages and Portlet Template Preference pages are used to manipulate Administrative settings for specific portlets.

Administrative settings affect all users of a specific portlet and can only be defined by administrative users with read/write access to the associated object.

  • Administrative Preferences pages are accessible only from within the associated Portlet editor, and only to users with administrative rights in the portal and read/write access to the portlet object.

  • Portlet Template Preferences pages are accessible only from within the associated Portlet Template editor, and only to users with administrative rights in the portal and read/write access to the Portlet Template. Administrative settings that are set via a Portlet Template Preferences page apply to all portlet objects created from that Portlet Template.

Creating an Administrative Preferences Page

To create an Administrative Preferences page or Portlet Template Preference page, deploy the page to the remote server that hosts the portlet and enter the page URL in the Web Service editor.

The URLs to the Administrative Preferences page and/or Portlet Template Preference page are specified in the Web Service editor on the Preferences page. The base URL is defined by the associated Remote Server.

A Portlet Template Preferences page is structured exactly like a standard Administrative Preferences page; the only difference is that the settings on the page apply to all portlets created from the associated portlet template. The Oracle WebCenter Interaction Development Kit (IDK) provides interfaces to manipulate settings in the portal database. For an example of setting and accessing settings, see Creating a Portlet Preferences Page.

Community Preferences Pages

Community Preferences pages are used to manipulate Community and CommunityPortlet settings, allowing Community Owners to modify content for all users without leaving the community.

A Community Preference page is used to define settings that apply only within the current community, either to all portlets and users (Community Preference) or a single portlet for all users (CommunityPortlet Preference). Community Preference pages are accessed from the Community Editor, accessible only to Community Owners. The Community Editor also allows you to disable the portlet title bar within the community.

Creating a Community Preferences Page

To create a Community Preferences page, deploy the page to the remote server that hosts the portlet and enter the page URL in the Web Service editor.

The URL to the Community Preferences page is specified in the Web Service editor on the Preferences page. The base URL is defined by the associated Remote Server. All Community settings required by the portlet must be entered by name in the Preference list on this page. If a setting is not entered in this list, it will not be available to the portlet. CommunityPortlet settings do not need to be entered. Any pages that access settings must be gatewayed.

The Oracle WebCenter Interaction Development Kit (IDK) provides interfaces to manipulate settings in the portal database. For an example of setting and accessing settings, see Creating a Portlet Preferences Page.

Portlet Preferences Pages

Portlet Preferences pages are accessible from the portal page and can be used to manipulate both Portlet and User settings.

A Portlet Preferences page is used to define settings that affect a single user. Portlet settings apply to one specific portlet object and one particular user. User settings apply to one specific user but can be used by multiple portlets and services.

If a portlet has been configured with a Portlet Preferences page, an edit icon appears in the portlet title bar.

When a user first adds the portlet to a page, it might not be obvious where to enter necessary settings. If a portlet requires configuration, always enter a link to the preferences page in the Web Service editor.

Creating a Portlet Preferences Page

To create a Portlet Preferences page, deploy the page to the remote server that hosts the portlet and enter the page URL in the Web Service editor.

The URL to the Portlet Preferences page is specified in the Web Service editor on the Preferences page. The base URL is defined by the associated Remote Server. All User settings required by the portlet must be entered by name in the Preference list on this page. If a setting is not entered in this list, it will not be available to the portlet. Portlet settings do not need to be entered.

Note:

User settings are shared among all services, so you must use a unique setting name. For example, "Exchange55Password" is less likely to result in a name collision than "password".

The Oracle WebCenter Interaction Development Kit (IDK) provides interfaces to manipulate settings in the portal database. In the example code below, two portlets share the User setting CoStoreProductID. Note: The setting name must be entered in the Web Service editor for both portlets. All portlet files must be gatewayed. The first portlet provides a form for the user to enter the product ID, and stores this information as a User setting.

Portlet 1 - Java

<%@ page language="java" import="com.plumtree.remote.portlet.*,java.util.Date" %>

IPortletContext portletContext = PortletContextFactory.createPortletContext(request,
response); IPortletResponse portletResponse = portletContext.getResponse(); 
IPortletUser portletUser = portletContext.getUser();
IPortletRequest portletRequest = portletContext.getRequest();

// Get the incoming Product ID from the query string
String currProduct = request.getParameter("ID");

if (null == currProduct) 
  { 
  currProduct = ""; 
  }
portletResponse.setSettingValue(SettingType.User, "CoStoreProductID", 
sCurrProduct);
// Redirect to the Company Store Community
portletResponse.returnToPortal();
... 

Portlet 1 - .NET

...
Dim portletContext As IPortletContext
portletContext = PortletContextFactory.CreatePortletContext(Request, Response)

Dim portletRequest As IPortletRequest
portletRequest = PortletContext.GetRequest

Dim portletUser As IPortletUser
portletUser = PortletContext.GetUser

Dim portletResponse As IPortletResponse
portletResponse = PortletContext.GetResponse

portletResponse.SetSettingValue(SettingType.User, "CoStoreProductID",  Request.QueryString("ID"))
...

The second portlet checks for the User setting before building its display. (The portlet then retrieves the stored User setting from the portal database and displays the product.)

Portlet 2 - Java

...
currentProductID = portletRequest.getSettingValue(SettingType.User, "CoStoreProductID");
... 

Portlet 2 - .NET

...
Dim currentProductID As String
currentProductID = portletRequest.GetSettingValue(SettingType.User, "CoStoreProductID")
...

User settings can also be entered on the User Configuration page, accessible from the My Account page in the portal. For details, see the portal online help.

Using Session Preferences

To store and share settings within the client browser, use session preferences.

Portlet can use preferences to communicate with each other, but accessing preferences usually requires a round trip to the portal database. Session preferences provide a way to store and share settings in the user's session within the client browser. The Master-Detail design pattern illustrates the most basic usage of session preferences. This design pattern splits control and display between two portlet. For example, the "master" portlet could summarize data in list form, and the "detail" portlet could display details on each data item in response to user selection. In the example below, the master portlet displays a form that allows you to enter a color code in a text box. When the user enters a color code in the text box, the color in the detail portlet changes. For each onkeyup event that occurs in the "Enter color" text box in the master portlet, the following steps are executed:

  1. The master portlet sets the session preference using the current value of the text box.

  2. The master portlet calls an update method on the detail portlet.

  3. The detail portlet retrieves the session preference to get the color value.

  4. The detail portlet redraws its color swatch area to reflect the new color value.

Portlets can manipulate session preferences using the Oracle WebCenter Interaction Scripting Framework or the Oracle WebCenter Interaction Development Kit (IDK). Sample code for both options is provided below.

Note:

Shared session preferences must be specified by name on the Preferences page of the associated Web Service editor or they will not be sent to the portlet.

Oracle WebCenter Interaction Development Kit (IDK) Methods

In most cases, reading session preferences via the Oracle WebCenter Interaction Scripting Framework is inefficient and insecure. Always use the Oracle WebCenter Interaction Development Kit (IDK) to read session preferences, as shown in the example code below.

Java

<%@ page language="java" import="com.plumtree.remote.portlet.*,java.util.Date" %>

IPortletContext portletContext = PortletContextFactory.createPortletContext(request,response); 
IPortletResponse portletResponse = portletContext.getResponse(); 
IPortletUser portletUser = portletContext.getUser();
IPortletRequest portletRequest = portletContext.getRequest();

masterColor = portletRequest.getSettingValue(SettingType.Session, "masterColor");

.NET

...
Dim portletContext As IPortletContext
portletContext = PortletContextFactory.CreatePortletContext(Request, Response)

Dim portletRequest As IPortletRequest
portletRequest = PortletContext.GetRequest

Dim portletUser As IPortletUser
portletUser = PortletContext.GetUser

Dim portletResponse As IPortletResponse
portletResponse = PortletContext.GetResponse

Dim masterColor As String
masterColor = portletRequest.GetSettingValue(SettingType.Session "masterColor")
...

Oracle WebCenter Interaction Scripting Framework Methods

The Oracle WebCenter Interaction Scripting Framework provides an easy way to detach the relationship between portlets and use a common event interface for communication. This example is oversimplified; the master portlet makes a direct call to a JavaScript method of the detail portlet. Unless the master portlet takes extra measures to ensure that the detail portlet is actually present on the same page, calls from master to detail could generate errors. See Using Oracle WebCenter Interaction Scripting Framework Event Notification for more information on inter-portlet communication.

Master Portlet

<div style="padding:10px;" align="center">
<p><b>Enter color:</b> &nbsp;
<input type="text" style="font-size:22px;font-weight:bold;text-align:center;" id="master_prefName"
value="#FFFFFF" size="8" onkeyup="master_setPrefs(this.value)"></p><br>
</div>

<script type="text/javascript">
function master_setPrefs(val)
{
var prefName = 'masterColor';
var prefValue = val;
PTPortlet.setSessionPref(prefName,prefValue);

master_debug('<b>Master Portlet</b> called PTPortlet.setSessionPref(\'masterColor\',\'' + prefValue + '\').');

if (window.detail_update)
  {
  master_debug('<b>Master Portlet</b> calling detail_update().');
  detail_update();
  }
else
  {
  master_debug('Could not locate portlet <b>Detail Portlet</b> on page.');
  }
}
function master_debug(str)
{
if (window.PTDebugUtil) 
  { 
  PTDebugUtil.debug(str); 
  }
}
</script>

Detail Portlet

<div style="padding:10px;" align="center">
<p><b>Color swatch</b> &nbsp;
<div style="width:100px;height:100px;border:2px solid black;padding:2px;"id="detail-swatch"></div>
<script>
function detail_update()
{
var color = PTPortlet.getSessionPref('masterColor');
detail_debug('<b>Detail Portlet</b> received value="' + color + '" for PTPortlet.getSessionPref(\'masterColor\')');

var swatch = document.getElementById('detail-swatch');
if (swatch)
  {
  swatch.innerHTML = '<div style="background-color:' + color + ';width:100%;height:100%;"></div>';
  }
else
  {
  detail_debug('<b>Detail Portlet</b> cannot find \'detail-swatch\' DIV element.');
  }
}

function detail_debug(str)
{
if (window.PTDebugUtil) 
  { 
  PTDebugUtil.debug(str); 
  }
}
</script>

Accessing User Information

Portlets can use the Oracle WebCenter Interaction Development Kit (IDK) to access read-only User Information settings that have been entered by users or imported into the portal using a Profile Source Identity Service.

The User Information settings required by a portlet must be selected in the Web Service editor on the User Information page. The standard settings appear at the top of the page; select any settings that should be sent to the portlet. You can select additional settings that already exist in the portal by clicking Add Existing User Info. You can enter setting names manually; to add rows to the list, click Add User Info.

Once the portlet object has been configured as described above, portlet code can access the User Information settings sent from the portal using the Oracle WebCenter Interaction Development Kit (IDK). In the following example code, the portlet retrieves the Company information property (CompanyUserInfo).

Java

...
// Get user's company info setting
String companyID;
companyID = portletRequest.getSettingValue(SettingType.User, "CompanyUserInfo");

// if user's company info does not exist, retrieve from User Info properties
if (null == companyID) {
companyID = portletRequest.getSettingValue(SettingType.UserInfo, "CompanyUserInfo");
}
... 

.NET

...
' Get the user's company info setting
Dim companyID As String
companyID = portletRequest.GetSettingValue(SettingType.User, "CompanyUserInfo")

' if user's company info does not exist, retrieve from User Info properties
If companyID Is Nothing Then
companyID = portletRequest.GetSettingValue(SettingType.UserInfo, "CompanyUserInfo")
End If
...

Oracle WebCenter Interaction Portlet Security

Portlets can be used to manipulate secure content. Oracle WebCenter Interaction provides a variety of ways to control access to specific functionality.

Using the Oracle WebCenter Interaction Credential Vault

The Oracle WebCenter Interaction credential vault provides a central repository that securely stores and manages all credentials. Portlets that need login information to access a back-end application can securely retrieve the appropriate user credentials from a central location. Users enter their credentials once in their account settings and have seamless access to every application they interact with throughout the portal session.

Credentials are sent in portlet headers, using RSA public key/private key encryption. The IDK Oracle WebCenter Interaction Development Kit (IDK) ICredentialProvider interface allows portlets to access user credentials stored in the central credential vault. To use the credential vault, there must be a Lockbox in the portal associated with the authentication source. To create or configure a Lockbox, go to portal administration and click Choose Utility > Credential Vault Manager. For details, see the portal online help. To configure the credential vault for use with your portlet, three steps are required:

  1. In the Remote Server editor associated with the portlet, enter the Public Encryption Key.

  2. In the Web Service editor on the Authentication Settings page, choose the appropriate Lockbox and set the Basic Authentication Settings to User's Lockbox Credentials.

  3. Provide the private key for RSA encryption in one of two ways:

    • Enter the private key in the RSAPrivateKey parameter in the IDK web.xml/Web.config file on the remote server.

    • Set the private key programmatically using the ICredentialProvider.setPrivateKey method as shown in the example below.

    If you do not enter a key, the credential vault will use Base64 encryption.

The ICredentialProvider interface lets you retrieve the user name and password from portlet headers with a few lines of code.

Note:

If the private key for RSA encryption is set in the web.xml/Web.config file, the setPrivateKey method is not required. The values in the configuration file override any value set through the setPrivateKey method.

Java

// get an ICredentialProvider instance from IPortletContext
IPortletContext portletContext = PortletContextFactory.createPortletContext(req, resp);
ICredentialProvider cProvider = CredentialManager.getProviderInstance(req);

// set the private key used to decrypt the password 
cProvider.setPrivateKey(rsaPrivateKeyString);

// get the username and password
String username = cProvider.getUsername();
String password = cProvider.getPassword();

.NET

// get an ICredentialProvider instance from IPortletContext
IPortletContext portletContext = PortletContextFactory.CreatePortletContext(req, resp);
ICredentialProvider cProvider = portletContext.GetCredentialProvider();

// set the private key used to decrypt the password
cProvider.SetPrivateKey(rsaPrivateKeyString);

// get the username and password
String username = cProvider.GetUsername();
String password = cProvider.GetPassword();   

You can also use ICredentialProvider to access settings encrypted in RC2, AES and Base64 that are stored in the portal database. For details, see the next section.

Using Oracle WebCenter Interaction Development Kit (IDK) Encryption

The Oracle WebCenter Interaction Development Kit (IDK) provides standard methods for encrypting and decrypting credentials stored in the portal database.

You can use the Oracle WebCenter Interaction Development Kit (IDK) to access credentials from the credential vault. If you are not using the credential vault, you must set the encryption type and associated key, and the setting type and setting names. You can enter these parameters in the Oracle WebCenter Interaction Development Kit (IDK) web.xml/Web.config file, or set them programmatically. Both options are detailed below.

  • To configure encryption in the web.xml/Web.config file, enter values for the following parameters:

    Parameter Accepted Values

    CredentialSettingType

    Portal setting type:

    • GADGET: Portlet Preference

    • COMMUNITYGADGET: CommunityPortlet Preference

    • COMMUNITY: Community Preference

    • ADMIN: Administrative Preference

    • SESSION: Session Preference

    • USER: User Preference

    • USERINFO: User Information Setting

    UsernameParameterName

    The setting name for the user name setting (for example, MyAppUserName).

    PasswordParameterName

    The setting name for the password setting (e.g., MyAppPassword).

    CredentialEncryptionType

    Encryption type:

    • BASE64

    • RC2

    • AES

    • NONE

    (RSA encryption is only available with the credential vault.)

    RC2PrivateKey

    String of private key for RC2 encryption.

    AESPrivateKey

    String of private key for AES encryption.


    Note:

    The encryption settings in the configuration file will override any values set programmatically. If you do not include encryption settings in the configuration file, you must set them programmatically as shown below.

  • To encrypt and store credentials in the portal database, use ICredentialSetter.

    Java

    // get an ICredentialSetter instance from IPortletContext
    IPortletContext portletContext = PortletContextFactory.createPortletContext(req, resp);
    ICredentialSetter cSetter = portletContext.getCredentialSetter();
    
    // set the header type and parameter names
    cSetter.setCredentialSettingType(SettingType.User);
    cSetter.setUsernameParameterName("MyAppUserName");
    cSetter.setPasswordParameterName("MyAppPassword");
    
    // set the encryption type and key
    cSetter.setCredentialEncryptionType(EncryptionType.RC2);
    cSetter.setPrivateKey("skiroblbpauwyryrhfvnmsl");
    
    // set the user name and password
    cSetter.setUsername(username);
    cSetter.setPassword(password);  
    

    .NET

    // get an ICredentialSetter instance from IPortletContext
    IPortletContext portletContext = PortletContextFactory.CreatePortletContext(req, resp);
    ICredentialSetter cSetter = portletContext.GetCredentialSetter();
    
    // set the header type and parameter names
    cSetter.SetCredentialSettingType(SettingType.User);
    cSetter.SetUsernameParameterName("MyAppUserName");
    cSetter.SetPasswordParameterName("MyAppPassword");
    
    // set the encryption type and key
    cSetter.SetCredentialEncryptionType(EncryptionType.RC2);
    cSetter.SetPrivateKey("skiroblbpauwyryrhfvnmsl");
    
    // set the user name and password
    cSetter.SetUsername(username);
    cSetter.SetPassword(password);  
    
  • To decrypt credentials stored in the portal database, use ICredentialProvider.

    Java

    // get an ICredentialProvider instance from IPortletContext
    IPortletContext portletContext = PortletContextFactory.createPortletContext(req, resp);
    ICredentialProvider cProvider = portletContext.getCredentialProvider();
    
    // set the header type and parameter names
    cProvider.setCredentialSettingType(SettingType.User);
    cProvider.setUsernameParameterName("MyAppUsername");
    cProvider.setPasswordParameterName("MyAppPassword");
    
    // set the encryption type and key
    cProvider.setCredentialEncryptionType(EncryptionType.RC2);
    cProvider.setPrivateKey("skiroblbpauwyryrhfvnmsl");
    
    // get the username and password
    String username = cProvider.getUsername();
    String password = cProvider.getPassword(); 
    

    .NET

    // get an ICredentialProvider instance from IPortletContext
    IPortletContext portletContext = PortletContextFactory.CreatePortletContext(req, resp);
    ICredentialProvider cProvider = portletContext.GetCredentialProvider();
    
    // set the header type and parameter names
    cProvider.SetCredentialSettingType(SettingType.User);
    cProvider.SetUsernameParameterName("DCTMUsername");
    cProvider.SetPasswordParameterName("DCTMPassword");
    
    // set the encryption type and key
    cProvider.SetCredentialEncryptionType(EncryptionType.RC2);
    cProvider.SetPrivateKey("skiroblbpauwyryrhfvnmsl");
    
    // get the username and password
    String username = cProvider.GetUsername();
    String password = cProvider.GetPassword(); 
    

Portlet Internationalization

These tips and best practices apply to all portlets that will be translated into multiple languages.

For details on implementing internationalization, see Using Internationalized Strings in Adaptive Tags.

Modifying the Portlet Title Bar

The portlet title bar is the solid colored bar that displays the portlet name at the top of each portlet on a portal page. The portlet code has full control over the text and functionality displayed in the title bar.

The default title for a portlet is entered in the Portlet Editor. In internationalized portlets, the portlet title bar should be localized. To override the default title, use the Oracle WebCenter Interaction Development Kit (IDK) method PortletResponse.setTitle as shown in the sample VB code below.

<%
Dim portletContext As IPortletContext
portletContext = PortletContextFactory.CreatePortletContext(Request, Response)

Dim portletResponse As IPortletResponse
portletResponse = PortletContext.GetResponse()

Dim portletRequest As IPortletRequest
portletRequest = PortletContext.GetRequest()

portletResponse.SetTitle("New Title")
...

This code can be combined with logic to determine the locale of the user and display the title in the appropriate language. For details on internationalizing portlet content, see Using Internationalized Strings in Adaptive Tags.

Portlet Caching

Caching is the functionality that allows Oracle WebCenter Interaction and Oracle WebCenter Ensemble to request portlet content, save the content, and return the saved content to users when appropriate. The importance of caching cannot be overstated.

Efficient caching makes every web application faster and less expensive. The only time content should not be cached is if the data must be continuously updated. If every portlet had to be freshly generated for each request, performance could become unacceptably slow. Oracle WebCenter Interaction and Oracle WebCenter Ensemble rely on caching to improve performance. Portlet content is cached and returned when later requests match the cache's existing settings.

Caching is indexed on the settings sent by the portlet. When the Oracle WebCenter Interaction or Oracle WebCenter Ensemble gateway server processes a request for a page, it looks individually at each portlet on the page and checks it against the cache. The process can be summarized as follows:

  1. The gateway server assembles a cache key used to uniquely identify each portlet in the cache.

  2. The gateway server checks the cache for a matching cache key entry:

    • If the gateway server finds a match that is not expired, it returns the content in the cache and does not make a request to the remote server.

    • If there is no matching cache key for the portlet or if the cache key has expired, the gateway server makes a request to the remote server. If the matching cache entry uses ETag or Last-Modified caching, it also sends the appropriate caching header to the remote server in the request.

  3. The response comes back from the remote server; the gateway server checks for caching headers:

    • If the headers include an Expires header, the gateway server stores the new portlet content (along with a new expiration date) in its cache.

    • If the headers use ETag or Last-Modified caching, the existing cache entry might be revalidated (in the case of '304-Not Modified') or new portlet content might be stored in the cache.

Oracle WebCenter Interaction and Oracle WebCenter Ensemble cache gatewayed content to complement, not replace, browser caching. Public content is accessible to multiple users without any user-specific information (based on HTTP headers). The gateway server calculates the cache headers sent to the browser to ensure that the content is properly cached on the client side.

Oracle WebCenter Interaction and Oracle WebCenter Ensemble cache all text (i.e., nonbinary) content returned by GET requests. Even if gateway caching is disabled (via PTSpy), portlet caching still takes place. Gatewayed content can be cached by a proxy server or by the user's browser. Beware browser caching of gatewayed content; it is a good idea to clear your browser cache often during development. An incorrectly set Expires header can cause browsers to cache gatewayed content.

The portlet cache contains sections of finished markup and sections of markup that require further transformation. Post-cache processing means content can be more timely and personalized. Adaptive tags enable certain portlet (for example, Community banners) to be cached publicly for extended periods of time and yet contain user- and page-specific information, as well as the current date and time.

For a full explanation of HTTP caching, see RFC 2616 (http://www.w3.org/Protocols/rfc2616/rfc2616.html).

Portlet Caching Strategies

Portlet caching is controlled both by the programmer and by the administrator who registers the portlet in Oracle WebCenter Interaction or Oracle WebCenter Ensemble. Each and every portlet needs a tailored caching strategy to fit its specific functionality.

A portlet's caching strategy should take all possibilities into account and use the most efficient combination for its specific functionality. A portlet that takes too long to generate can degrade the performance of every page that displays it. These questions can help you determine the appropriate caching strategy:

  • Will the content accessed by the portlet change? How often?

  • How time-critical is the content?

  • What processes are involved in producing portlet content? How expensive are they in terms of server time and impact?

  • Is the portlet the only client with access to the back-end application?

  • Is the content different for specific users?

  • Can users share cached content?

Determine how often portlet content must be updated, dependent on data update frequency and business needs. Find the longest time interval between data refreshes that will not negatively affect the validity of the content or the business goals of the portlet.

Since caching is indexed on the settings used by a portlet, new content is always requested when settings change (assuming that no cached content exists for that combination of settings).

There are two common situations in which you might mistakenly decide that a portlet cannot be cached:

  • In-place refresh: You might think that caching would "break" a portlet that uses in-place refresh because the portlet would be redirected to the original (cached) content. This can be avoided if a unique setting is updated on every action that causes a redraw, effectively "flushing" the cache. (In-place refresh renews the portlet display by causing the browser to refresh the portal page at a set interval.)

  • Invisible preferences: If the content of the portlet is dependent on something other than preferences (for example, the portlet keys off the User ID to display a name or uses portal security to filter a list), caching can still be implemented with “invisible preferences” (in this case, User ID). As with in-place refresh, invisible preferences are set solely for the purpose of creating a different cache entry. They are set programmatically, without the user's knowledge.

Portlet Cache Key

The cache key for a portlet entry in Oracle WebCenter Interaction or Oracle WebCenter Ensemble consists of these values.

Parameter Description

Portlet ID

The unique ID for the portlet, defined by Oracle WebCenter Interaction or Oracle WebCenter Ensemble.

Content Mode

The content mode of the portlet.

Portal Settings

All seven types of settings stored in the portal database: Portlet settings, User settings, Community settings, CommunityPortlet settings, Administrative settings, Session preferences, and User Information.

User Interface

The type of device used to access the portlet.

CanSet values

All three values for the CanSet header: CanSetPersonal, CanSetCommunity, CanSetAdmin

LocaleID

The ID for the portal-defined locale associated with the current user.

UserID

The unique ID for the current user. Included only if private caching is used.

URI

The URL to the portlet page on the remote server.

Community ID

Included only if the portlet is displayed on a community page.

Last-modified date

The last modified date of the portlet.


The data below can be added to the cache key by setting options in the Web Service editor on the Advanced Settings page.

Parameter Description

Community ACL

The ACL for the community in which the portlet is displayed.

Page ID

The ID for the portal page on which the portlet is displayed.

TimeZone

The time zone for the portal in which the portlet is displayed.

Experience Definition ID

The ID for the Experience Definition in which the portlet is displayed.

Portlet Alignment

The alignment of the portlet in the current page.

Activity Rights

Only the Activity Rights configured in the Web Service editor are included in the cache key.


The data below is deliberately not included in the cache key:

Parameter Description

StyleSheetURI

Portal stylesheets are applied at runtime, depending on the user preference. Portlet content does not depend on the particular stylesheet that the user has selected.

HostpageURI

All parts of the Hostpage URI value are covered separately. The cache key includes Community ID, so it already distinguishes between My Pages and Community pages. The User ID is added if private caching is used.


Implementing Portlet Caching

Caching on the Portal Server can be set in two ways: programmatically through HTTP headers and/or using the administrative settings in the Web Service editor. You should always implement caching programmatically, although the administrator can still choose to override caching through administrative settings.

While caching is an integral and necessary part of portlet design, it is helpful to disable it while developing and debugging. Otherwise, it can be very difficult to view the results of any modifications you have made. To disable the caching implemented by the Portal Server, go to the HTTP Configuration page of the Portlet Web Service editor (shown under Portlet Settings above) and set the minimum and maximum caching times to 0. Clear the checkbox marked “Suppress errors where possible (use cached content instead).”

Note:

After the code has been developed and debugged, make sure to turn caching on and test the performance of your portlet. For details on troubleshooting portlets, see Portlet Debugging. If you using the Oracle WebCenter Interaction Logging Utilities to debug caching, turn on all types of tracing for the OpenKernel.OpenHttp.Cache component.

Setting HTTP Caching Headers - Cache-Control

The Cache-Control header can be used to expire content immediately or disable caching altogether. The value of this header determines whether cached portlet content can be shared among different users.

The Cache-Control header can contain the following values:

Header Value Description

public

Allows any cached content to be shared across users with identical sets of preferences using the same portal server. This value should be used whenever possible.

private

Tells the portal server not to share cached content. The User ID is added to the cache key so that a separate copy is retained in the cache for each individual user. This value should only be used to protect sensitive information, for example, an e-mail inbox portlet. (User settings can also make public content effectively private.)

max-age=[seconds]

Specifies the maximum amount of time that an object is considered fresh. Similar to the Expires header, this directive allows more flexibility. [seconds] is the number of seconds from the time of the request that the object should remain fresh.

must-revalidate

Tells the cache that it must obey any freshness information it receives about an object. HTTP allows caches to take liberties with the freshness of objects; specifying this header tells the cache to strictly follow your rules.

no-cache

Disables caching completely and overrides Web Service editor settings. Neither the client nor the Portal Server responds to subsequent requests with a cached version.


In JSP, use the setHeader method to configure the Cache-Control header:

<%
response.setHeader("Cache-Control","public");
%>

The JSP example below expires the content immediately using the maximum age header.

<%
response.setHeader("Cache-Control","max-age=0");
%>

In .NET, the Cache-Control header is accessed through the System.Web.HttpCachePolicy class. To set the header to public, private or no-cache, use the Response.Cache.SetCacheability method.

Response.Cache.SetCacheability(HttpCacheability.Public);

To set a maximum age for content in .NET, use the Response.Cache.SetMaxAge method. The example below expires the content immediately.

TimeSpan ts = new TimeSpan(0,0,0);
Response.Cache.SetMaxAge(ts);

To set the header to must-revalidate in .NET, use the Response.Cache.SetRevalidation method.

Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);

Setting HTTP Caching Headers - Expires

The Expires header specifies when content will expire, or how long content is “fresh.” After this time, the portal server will always check back with the remote server to see if the content has changed.

Most web servers allow setting an absolute time to expire, a time based on the last time that the client saw the object (last access time), or a time based on the last time the document changed on your server (last modification time).In JSP, setting caching to forever using the Expires header is as simple as using the code that follows:

<%
response.setDateHeader("Expires",Long.MAX_VALUE);
%>

The .NET System.Web.HttpCachePolicy class provides a range of methods to handle caching, but it can also be used to set HTTP headers explicitly (see MSDN for API documentation: ). The Response.Cache.SetExpires method allows you to set the Expires header in a number of ways. The following code snippet sets it to forever:

Response.Cache.SetExpires(DateTime.Now.AddYears(100000000));

In .NET, the Web Form page (.aspx) can also use standard ASP methods to set HTTP headers.

Note:

Never use Expires = 0 to prevent caching. The Expires header is sent by the remote server and passed through to the browser by the Portal Server. Unless the time on all three machines is synchronized, an Expires=0 header can mistakenly return cached content. To solve this problem, set the Expires header to a fixed date that is definitely in the past.

Setting HTTP Caching Headers - Last-Modified and ETag

The Last-Modified response header specifies the last time a change was made in the returned content, in the form of a time stamp. ETag values are unique identifiers generated by the server and changed every time the object is modified. Either can be used to determine if cached content is up to date.

When an object stored in the cache includes a Last-Modified or ETag header, the portal server can use this value to ask the remote server if the object has changed since the last time it was seen.

  • The portal server sends the value from the Last-Modified header to the remote server in the If-Modified-Since Request header.

  • The remote server sends the ETag header to the portal server with portlet content. When another request is made for the same content, the Portal Server sends the value in the ETag header back to the remote server in the If-None-Match header.

The portlet code on the remote server uses the header value to determine if the content being requested has changed since the last request, and responds with either fresh content or a 304 Not Modified Response. If the portal server receives the latter, it displays the cached content.JSP portlet can access the value in the If-Modified-Since request header using the getLastModified(HttpServletRequest req) method provided by the Java class HttpServlet.In .NET, the Response.Cache.SetLastModified method allows you to set the Last-Modified header to the date of your choice. Alternately, the SetLastModifiedFromFileDependencies method sets the header based on the time stamps of the handler's file dependencies.

Response.Cache.SetLastModified(DateTime.Now);

To use ETag in .NET, use the Response.Cache.SetETag method to pass in the string to be used as the ETag. The SetETagFromFileDependencies method creates an ETag by combining the file names and last modified timestamps for all files on which the handler is dependent.

Configuring Oracle WebCenter Interaction Portlet Caching Settings

In Oracle WebCenter Interaction, the HTTP Configuration page of the Web Service editor allows portal administrators to set minimum and maximum validation times for cached portlet content.

Note:

Using HTTP headers to control caching is always preferable. Administrators can override some programmatic caching, but they cannot be relied upon to set caching correctly. If your portlet requires specific editor settings for its caching strategy, you must include this information in your Installation Guide.

The default cache settings are a minimum of 0 seconds and a maximum of 20 days. These settings affect caching as follows.

  • The portal server never makes a request to the remote server before the Minimum Cache Time if there is content in the cache. (In version 6.0, the portlet cache is limited to 15 minutes, so a request will always be made after 15 minutes.) Multiple requests made for the same portlet with identical cachekeys within this minimum time always receive cached content. As noted earlier, setting the Cache-Control header to “no-cache” overrides editor caching settings; content will not be cached.

  • The portal server always makes a request to the remote server after the Maximum Cache Time. Cached content might or might not be returned, based on other information (for example, the Last-Modified header).

  • The portal server might or might not make a request to the remote server if content has been cached in between the Minimum and Maximum Cache Time. The portal server observes programmatic caching (for example, the Expires header) in the window between the minimum and maximum times.

Setting the Cache-Control header to “no-cache” overrides editor settings; content will never be cached.For example, the minimum caching time for a particular portlet is set to ten minutes, and the maximum caching time is set to one hour. Client A requests the portlet content. Five minutes later, Client B, with an identical set of preferences, requests the same content. Five minutes is under the minimum caching time set in the Portlet editor, so cached content is returned, no matter what type of programmatic caching has been implemented by the portlet. (Remember, the Portal Server only abides by headers if cached content was generated between the minimum and maximum caching times set in the editor. An Expires header set to two minutes does not refresh the cache in this example.) If no copies of the content existed for Client B's particular collection of settings or no content was cached, the remote server would be called to generate content that matched that group of settings. To continue the example, Client A requests the portlet content again, and there is a matching copy of the content in the cache that is 15 minutes old. This is over the minimum caching time and under the maximum. In this case, whether or not new content is generated depends on the HTTP headers sent by the portlet. If the portlet has not specified any caching programmatically, the Portal Server asks the remote server for fresh content. If the portlet set the Expires header to 30 minutes, new content is not generated. If ETag or Last-Modified caching was implemented, new content is only returned if content has changed. Finally, Client A requests the same content two hours later, and the matching copy was generated more than an hour before. Since this is over the maximum caching time set in the Portlet editor, the Portal Server requests new content from the remote server, regardless of the caching specified programmatically by the portlet. Of course, if the portlet has implemented ETag or Last-Modified caching, new content is only returned if content has changed.