Portal UI Customization: Basic

Creating a Custom Condition Type

If one of the standard condition types does not meet your needs, you can create your own condition type. The portal dynamically discovers and loads all condition types, including custom condition types.

There are two kinds of condition types:

The sample code below illustrates how to create a condition type based on the user's browser (Firefox or Internet Explorer). You could use this new condition type to allow only users with Firefox to see the Knowledge Directory.

The classes referenced below are in the com.plumtree.portaluiinfrastructure.condition and com.plumtree.server.condition packages. For a full list of interfaces and methods, see the API documentation.

Step 1: Create Class (A*ConditionType)

Extend either the ARegularConditionType or AGuestConditionType class (com.plumtree.portaluiinfrastructure.condition), depending on whether you are creating a regular condition type or a guest condition type.

Step 2: Create Condition Type ID

Use the GetTypeID (com.plumtree.server.condition) method to retrieve a unique ID for the condition type. All condition types must be uniquely identified, since the ID is used as a key for storing and retrieving information.

Java:

public int getTypeID()

{

   return ConditionTypeConstants.CONDITIONTYPE_ID_BASE + 1;

}

C#:

public virtual public override int GetTypeID()

    {

      return ConditionTypeConstants.CONDITIONTYPE_ID_BASE + 1;

    }   

Step 3: Implement Compare Method

The Compare (com.plumtree.server.condition) method evaluates experience rules by comparing the values of condition types with the values for the current user. When the portal encounters a condition, it retrieves the appropriate condition type and calls this method to compare the value of the condition with the current value in the user's environment. The result of the comparison determines whether the condition has been met.

You can add debug messages to be displayed on the My Page when troubleshooting (see Debugging below). Any exceptions caught from this method will be considered as a return value of "false" and will be discarded.  

For this example, the Compare method compares the browser of the user to the value specified in the condition.

Java:

public boolean Compare(XPHashtable htUserEnvironment, IValue conditionValue, XPStringBuilder sbDebugText) <p class=Numbered style="font-family: Courier; font-size: 10.0pt; font-weight: normal;">

{

   // Cast the value into a string type.

   String strUserAgent = (String) conditionValue.GetValue();
   BrowserType currentBrowser = (BrowserType) htUserEnvironment.GetElement(new
   Integer(GetTypeID()));

   if (strUserAgent.equals(currentBrowser.GetBrowserName()))

    {     

     if (null != sbDebugText)

      {

        sbDebugText.Append("Condition on User Agent returns true because the
User Agent: ")
        .Append(strUserAgent).Append("matches the one found in the user's
environment: ")
        .Append(currentBrowser.GetBrowserName()).Append("<br>");

          }

      return true;

   } else {

      if(null != sbDebugText)

             {

              sbDebugText.Append("Condition on User Agent returning false because the
User Agent: ")
              .Append(strUserAgent).Append(" does not match the one found in the
user's environment: ")
              .Append(currentBrowser.GetBrowserName()).Append("<br>");

              }

                 return false;

              }

   }     

C#:

public override bool Compare(XPHashtable htUserEnvironment, IValue conditionValue,

 XPStringBuilder sbDebugText)

    {

     if (conditionValue.GetType() != ValueTypeEnum.STRING ||
!htUserEnvironment.ContainsKey(GetTypeID()))

      {

        if (null != sbDebugText)

        {

          sbDebugText.Append("Condition on User Agent returning false because either the
condition value is of the wrong type,").Append(" or the User Agent was not
found in the user's environment<br>");

        }

        return false;

      }

      // Cast the value to type: String

      String strUserAgent = (String) conditionValue.GetValue();

      BrowserType currentBrowser = (BrowserType)
htUserEnvironment.GetElement(GetTypeID());

      if (strUserAgent.Equals(currentBrowser.GetBrowserName()))

      {

        if (null != sbDebugText)

        {

          sbDebugText.Append("Condition on User Agent returning true because the User
Agent: ")
.Append(strUserAgent).Append(" matches the one found in the user's
environment: ")
.Append(currentBrowser.GetBrowserName())
.Append("<br>");

          }

        return true;

      } else

      {

        if (null != sbDebugText)

        {

          sbDebugText.Append("Condition on User Agent returning false because the User
Agent: ")
.Append(strUserAgent).Append(" does not match the one found in the
user's environment: ")
.Append(currentBrowser.GetBrowserName())
.Append("<br>");

          }

        return false;

      }

    }

     

Step 4: Retrieve Values

The GetCurrentValue (com.plumtree.portaluiinfrastructure.condition.A*ConditionType) method retrieves the current value used in the Compare method and puts it in a hash table that keeps track of the user's environment.

The GetConditionValue method retrieves the data and converts it to the expected value type. You can use this method to validate your code, since any value that is not acceptable for the condition will cause an exception to be thrown.

In this example, the method retrieves the user's browser as a string, such as "Firefox" or "MSIE".

Java:

public void GetCurrentValue(XPLimitedRequest xpRequest, IPTSession guestReadOnlySession, XPHashtable htUserEnvironment)
{
htUserEnvironment.PutElement(new Integer(GetTypeID()), new BrowserType(xpRequest.GetHeader("User-Agent")));
}

public Object GetConditionValue(int nRow, IPTGrowableSortedArrayWrapperRO saData)

{

      Object result = saData.GetItem(nRow,
GrowableListModel.EXPLIST_SORTEDARRAY_PROPID_INPUTTEXT);

          String browser = (String) result;

    if (!browser.equals("MSIE") || !browser.equals("Netscape") ||
    !browser.equals("Firefox") || !browser.equals("Mozilla") ||  
!browser.equals("Safari"))   

           {

            throw new ValidationFailedException();

           }

     return result;

   }

C#:

public override void GetCurrentValue(XPLimitedRequest xpRequest, IPTSession guestReadOnlySession, XPHashtable htUserEnvironment)
{
htUserEnvironment.PutElement(GetTypeID(), new BrowserType(xpRequest.GetHeader("User-Agent")));
}

public override Object GetConditionValue(int nRow,
IPTGrowableSortedArrayWrapperRO saData)

    {

      Object result = saData.GetItem(nRow,
GrowableListModel.EXPLIST_SORTEDARRAY_PROPID_INPUTTEXT);

      String browser = (String) result;

      if (!browser.Equals("MSIE") || !browser.Equals("Netscape") ||
!browser.Equals("Firefox") || !browser.Equals("Mozilla") ||
!browser.Equals("Safari"))

      {

        throw new ValidationFailedException();

      }

      return result;

    }

 

The AddItemToMyConditionsList (com.plumtree.portaluiinfrastructure.condition.A*ConditionType) method adds values of conditions into a list. These stored values are later used by the Compare method.

By default, condition types use a GrowableList (com.plumtree.uiinfrastructure.expandablelist.GrowableList), but any list structure that extends ExpandableList (com.plumtree.portaluiinfrastructure.expandablelist) can be used. For details on including custom classes in the build script, see Setting Up the Development Portal.

This example uses the default GrowableList.

Java:

//This condition uses a GrowableList. It is called right before
//the Rules Editor is opened.

public void AddItemToMyConditionsList(Object objItem, ExpListModel myListModel, IPTSession ptSession)

 {

 GrowableListModel myGrowableListModel = (GrowableListModel) myListModel;

 myGrowableListModel.AddRowsToList(new String[] {XPConvert.ToString(objItem)});

 }

C#:

public override void AddItemToMyConditionsList(Object objItem, ExpListModel myListModel,

     IPTSession ptSession)

    {

      GrowableListModel myGrowableListModel = (GrowableListModel) myListModel;

      myGrowableListModel.AddRowsToList(new String[]{XPConvert.ToString(objItem)});

      }   

Step 5: Register the Condition Type Class

Add your new condition type to ConditionTypes.xml (PT_HOME\settings\portal\dynamicloads\Plugins). The portal uses this file to dynamically discover all condition types.

The first four items listed are the standard condition types installed with the portal. Add your custom condition type to the end of the list.

<interface name="com.plumtree.portaluiinfrastructure.condition.AConditionType" />

<interfaceassembly name="portaluiinfrastructure" />

<class name="com.plumtree.portalpages.condition.conditiontypes.ConditionTypeURLDomain"/>

<class name="com.plumtree.portalpages.condition.conditiontypes.ConditionTypeClientIPAddress"/>

<class name="com.plumtree.portalpages.condition.conditiontypes.ConditionTypeCommunityID"/>

<class name="com.plumtree.portalpages.condition.conditiontypes.ConditionTypeGroupID"/>

<class name="com.plumtree.portalpages.condition.conditiontypes.ConditionTypeBrowser"/>

Step 6: Deploy Custom Code

You must deploy your custom class for use by the portal. The process is different for Java and .NET.

Java:

  1. Place a copy of the new jar file in PT_HOME\ptportal\6.0\lib\java.

  2. Add the jar to your portal.war file in PT_HOME\portal\6.0\webapp. Always create a backup of your portal.war file before making any changes.

    1. Unzip the portal.war file.

    2. You will see the following directories: \conf, \META-INF and \WEB-INF. Place a copy of your jar file in \WEB-INF\lib.

    3. Rebuild the portal.war file by zipping up the \conf, \META-INF and \WEB-INF directories.

.NET:

Place the new dll file in the following locations:

Step 7: Restart the Portal

After you restart the portal, you should see the new condition type in the Experience Rules Manager.

Debugging

You can configure the portal to display debugging messages to troubleshoot problems with your condition types and experience rules. Go to portal portal administration and click Select Utility | Portal Settings to open the User Settings Manager.  Under Debug Mode, select Enable Experience Definition Rules Debug Mode to display experience rules debug messages on My Pages. Enabling this mode adds the option to display debug messages to users' My Account | Display Options | Advanced Settings page.

The Guest Associations page in the Experience Rules Manager lists experience rules and the resulting guest user if the rule evaluates to true. The rules listed on this page may be a subset of all rules because the list only includes guest rules that can be evaluated before a user logs in, for example, a URL or IP address rule.

The Folder Associations page shows which administrative folders are associated with which experience definitions. If an Experience Definition has an associated administrative folder, users created in that folder see the associated Experience Definition only if no Experience Definition rule applies to those users. If no Experience Rule applies to a user, and that user is not in an administrative folder associated with an Experience Definition, the user sees the default Experience Definition.