To customize portal functionality using a PEI, you must create a class that implements the PEI. For a list of PEIs, see Step 1: Choosing a PEI. For detailed information on available methods for each PEI, see the API documentation. This page provides three examples of implementing PEIs: Hello World Login PEI, Login Usage Agreement, and Banner Search Customization.
Below are some important objects used by multiple PEIs:
The IPTSession object is always available to PEIs. If the object is not passed to the PEI in the argument, it can be retrieved from the ActivitySpace object ((IPTSession)myActivitySpace.GetUserSession()). The IPTSession object is the portal session for the current user. This object lets you perform any action that the current user has the rights to execute on the Portal Server. For example, if the current user has the necessary rights, you can create new portal objects, query existing objects, browse the Directory or query MyPages and Communities.
The ActivitySpace object is passed to many PEI functions. This object provides access to the user session and any user specific information, as well as other ActivitySpace-specific information including page name, Control name and server name. The ActivitySpace object is the container for all the Model, View, and Control classes that comprise a particular piece of functionality. Any objects required by a piece of functionality can usually be retrieved from the parent ActivitySpace object.
The ApplicationData object is is passed to PEIs that are not sent the ActivitySpace object. The object provides access to application-specific data from the ActivitySpace, including the Web Application and the Web Session. The ApplicationData object also lets you perform some actions on the Request object. For example, you can get and set Cookies, get the requested URL or set values on the HTTP header.
For more detailed information on objects and methods, see the API documentation.
To create a custom PEI, follow the steps below.
Create your own custom project and custom PEI class (e.g., a CustomLoginPEI project and a CustomLoginPEI class in com.yourcompany.pei.login). For instructions on creating a custom project, see ALI Portal Development Environment: Creating a Custom Project (Java | .NET).
Edit the new class in your custom project.
Compile the new class into a new JAR/DLL file with an intuitive name (e.g., CustomLoginPEI). Note: You must re-compile PEIs against each new release of the .NET portal even if you have not made any modifications.
This page provides three examples of implementing PEIs: Hello World Login PEI, Login Usage Agreement, and Banner Search Customization.
The sample customization below adds a message ("HELLO WORLD ") to be displayed in PTSpy after a user logs in.
The name of the file is important. All classes that implement PEIs should use a file name the references the name of the interface that they implement. The ILoginActions interface defines a few simple methods: OnBeforeLogin, OnAfterLogin, OnFailedLogin, and OnBeforeLogout. Use your IDE to navigate to the interface definition or view the API documentation for PEI classes (e.g., ILoginActions).
Note: These instructions apply to AquaLogic Interaction (formerly called the Plumtree Portal) version 6.0.
This example uses the sample code from the Developer Center: SampleProjects-60.zip. For details, see Installing UI Customization Sample Projects (Java | .NET). Install the files and add the sampleloginpei project to your IDE. (You must also set up your IDE for portal development as explained in Setting Up the Development Portal.)
Open the HelloWorldLoginActions file (.java or .cs). This file implements the ILoginActions interface at com.plumtree.uiinfrastructure.pei.
The OnAfterLogin() method allows for some functionality to occur once the user has successfully logged in and then possibly do a redirect to someplace other than the MyPage. As noted above, this code tells PTSpy to to print out a HELLO WORLD string after a user logs in. This code uses the Error tracing type; you must confirm that PTSpy Error tracing is enabled when you deploy the code to view the message.
Java:
|
|
C#:
|
public virtual Redirect OnAfterLogin(Object _oUserSession, ApplicationData _appData) { //
Print out "HELLO WORLD" to PTSpy return null; } |
The remaining methods are unused in this example, so they simply return null. They could be used to perform similar actions before logging in or out, or when a login fails. For a more advanced login customization, see the next example.
.NET only: After the code is complete, you must associate the portal60 project with the custom project.
In Visual Studio, navigate to the SOURCE_HOME\portal.NET\prod and open portal60.sln.
Expand the project, right-click on References, and select Add Reference.
On the Projects tab, highlight the sampleloginpei project.
Click Select and OK. Click OK to close the References window.
Build the portal60 solution to ensure that all projects build successfully.
Close Visual Studio.
Once you have written the code for your new PEI, you must deploy it for use by the portal, described in the next step.
This customization redirects guest users to a usage agreement page when they log in. Based on whether they accept or reject the agreement, they are redirected to the appropriate My Page or back to the Login page. The customization includes the following classes:
The LoginAgreementActions class implements the ILoginActions PEI and executes custom code when users log in.
The GuestLoginAgreementControl class implements both the ILoginControl and IHTTPControl interfaces and logs users in as a custom guest user.
The MarkAsGuestControl class sets a variable on the HTTP Session to show that this custom guest user should still be treated as a guest user, basically invalidating their session.
The LoginAgreementRepostControl class handles the users choice to accept the agreement or to reject it.
The sections below summarize the functionality of each class. To view all the code for this customization, see the sampleagreementlogin project in SampleProjects-60.zip (available on the ALUI Developer Center on dev2dev).
The LoginAgreementActions class implements ILoginActions and executes custom code when users log in to the portal.
The OnAfterLogin() method gets the PTSession and checks if the login is for an actual user, then checks if the user has already accepted the agreement. If the user has accepted the agreement, the login proceeds to the portal normally; if the user has not accepted the agreement, the login page redirects to GuestLoginAgreementControl.
|
|
The GuestLoginAgreementControl class is responsible for logging users in and out. When users are first redirected to GuestLoginAgreementControl they are logged out and logged back in as a guest. After they have seen the agreements page, it redirects them back to GuestLoginAgreementControl, which logs users in through their account or redirects them back to the login page.
The GuestLoginAgreementControl class implements both the ILoginControl and IHTTPControl interfaces. The SetHttpItems() method accesses the HTTP request and PageData objects, used later in the AttemptLogin method. It is very important to clear these member variables (set them equal to null) after they have been used to make sure they are not leaked.
|
|
The CheckActionSecurityAndExecute() method is used to return a Redirect object. This Redirect is followed after the login from the Control is processed. The Redirect object returned depends on the user's current status.
When users are directed to this control the first time, they are redirected to MarkAsGuestControl, which marks them as a guest and invalidates the session. This is to prevent users from viewing parts of the portal to which they do not have access. The users PTSession is cached for later use.
After users have viewed the agreements page and are redirected back to this control (the user session retrieved from the persistent sub-session is not null), the CheckActionSecurityAndExecute method checks whether they accepted the agreement or not. If they accepted the agreement, a redirect to their My Pages is returned. If they did not accept the agreement, they are redirected back to MarkAsGuestControl, which invalidates the session and redirects to the Login page.
|
|
The DoGetSession() method tells the Interpreter whether or not to log in a new user during this request. This method creates a default guest user PTSession to be used in GetSession() if the user has not accepted the usage agreement. If a user has already accepted the usage agreement, this method does nothing.
|
|
The GetSession() method returns a PTSession for the current user. The LoginHelper AttemptLogin method attempts to log users out of their account and log in to the default guest user account (using the PTSession created by DoGetSession() above) and calls all the appropriate login PEIs. This code nulls out the IHTTPControl member variables to make sure they are not leaked and returns the PTSession created earlier. It also removes the user's PTSession cached in the persistent sub-session if it is no longer needed.
Only after users have accepted the agreement are they allowed to log in through their account. In this case, the PTSession is the user session they originally logged in through, that was stored when they were first directed to this control in CheckActionSecurityAndExecute. If the agreement was not accepted, the PTSession returned is a new session for the guest user.
|
|
The MarkAsGuestControl class is another essential component in this customization. In order to prevent users from potentially viewing parts of the portal to which they should not have access, it is necessary to invalidate their session when logged in. This control essentially marks users as a guest, making sure they are unable to access any portion of the portal. This control is used when users are first logged out and logged back in as a guest, and also if users reject the agreement and are logged in as a guest and redirected to the login page.
The CheckActionSecurityAndExecute() method in this control sets a variable on the HTTP Session to show that users should still be treated as a guest user. The method sets an attribute (variable) on the user sub-session (HTTP Session). Setting the USERSESSIONVALID attribute to False tells the TopBar to treat users as a guest or non-authenticated user. The method then checks whether the user rejected the agreement or has not yet been prompted with the agreement by checking for a cached PTSession in the persistent sub-session. If the user has not yet been prompted with the agreement (i.e., there is a PTSession in the sub-session), the login cookie is removed to prevent a session timeout and they are redirected to LoginAgreementRepostControl. If the user has rejected the agreement, they are redirected to the Login page.
|
|
The LoginAgreementRepostControl class implements the second half of this customization. GuestLoginAgreementControl handles the necessary details of logging a user in and out of the portal, while LoginAgreementRepostControl handles the corresponding user actions on the agreements page.
The CheckActionSecurityAndExecute() method in this control first checks if the user has already accepted the agreement. If users accept the agreement by clicking OK, a value is stored in the users preferences so they do not see the agreements page on future logins. Whether they accept the agreement or not, all users are redirected back to GuestLoginAgreementControl, which redirects to the proper Activity Space (the login page or the user's My Pages). The cached PTSession in the persistent sub-session is removed by GuestLoginAgreementControl either in GetSession() or CheckActionSecurityAndExecute() depending on whether the user has accepted the agreement or not.
|
|
The examples in this section customize portal banner search functionality through the IBeforeBannerSearchActions PEI.
This code adds the string plumtree to every banner search query.
|
|
This example adds an author property to the set of fields to be searched.
|
|
This example adds a constraint that the author property must contain plumtree (in addition to the users query, which can match on Name, Description, or Content).
|
|
This example provides a 4.5WS-like banner search experience. It restricts banner search to match only documents and folders by turning off banner search of users, portlets, communities, Collaboration Server, and Content Server. This code also turns off spell correction.
|
|
Once you have written the code for your new PEI, you must deploy it for use by the portal, described in the next step.