Thursday, June 23, 2011

Portal Rich Text editor

If your portlet is extended from FacesPortlet then you can easily place a rich text editor in the jsp page through jsf/rte tag library.

Sample code :
<h:form styleClass="form" id="form1>
    <h:panelGrid styleClass="panelGrid" id="grid1">
        <hx:commandExButton type="submit" value="Submit" styleClass="commandExButton" id="button1"></hx:commandExButton>
        <r:inputRichText width="702" height="352" id="richTextEditor1" value="#{pc_TextEditorView.richText}"></r:inputRichText>
    </h:panelGrid>
</h:form>

If you just want to display the RTE submitted text in an JSF output tag then all the extra RTE characters are also displayed. Like - &lt;span style="font-weight: bold;"&gt;Name : Mike&lt;/span&gt;&lt;br style="font-weight: bold;"&gt;

So u need to set the "escape" attribute of the h:outputText command controls whether HTML characters are "escaped" (turned into text) or sent to the browser as HTML characters. To pass the HTML through instead of escaping it, set "escape='false'" on the outputText tag. After setting the value for “escape=false”, you will get value in HTML format like. Ex- <span style="font-weight: bold;">Name : Mike</span><br style="font-weight: bold;">
The output text includes the HTML tags instead of using them to format the text.

This is because of Portal server has a "cross site scripting" protection setting that is ON by default. This protection escapes all HTML being passed in request parameters. Since RTE uses HTML, it also gets escaped and the result is what you see.

Portal server Administrator can turn it off, via parameter
security.css.protection in ConfigService.properties
Or we can manually unescapeHtml, while request is summited -
org.apache.commons.lang.StringEscapeUtils.unescapeHtml(richTextEscapedHtml);


Note -
1)Make sure you have classloader set to PARENT_LAST for your portlet.
Side note:

2)Use the escape attribute with extreme care. If someone somehow got javascript into the text:
code
<script type="text/javascript">alert("i can do anything now");</script>
This would be executed by the browser when rendered. You need to make sure the text being rendered with escape="false" is safe text.

Session and Portlet Event for Anonymous users


Do the following configuration in Websphere Application Server to initialize a session for an anonymous user.

1. from the WebSphere Application Server administration console, select Resources > Resource Environment Providers.
2. Click WP NavigatorService. Under Additional Properties select Custom Properties.
3. Click New to create new custom properties.
4. In the Name field, type public.session .
5. In the Value field, type true.
6. Click OK to confirm the changes.
7. Save the configuration.
8. Restart portal server


We can also fire an event for an anonymous user using portlet wiring. To get that property we are supposed to do following changes inside  WAS ->

Resources -> Resource Environment Providers:

WP PortletServiceRegistryService -> Custom Properties:
we need to have the property "com.ibm.wps.propertybroker.standard.service.PropertyBrokerServiceWrapper.com.ibm.portal.propertybroker.standard.anonymous.page.support" set to "true".

Tuesday, June 21, 2011

Image / Thumbnail for PDF

Pdf-renderer - http://java.net/projects/pdf-renderer
Download the source code using SVN and use ant to build.
After running ant build, copy PDFRenderer.jar from dist folder and set into your project classpath.
You can use this api to generate Image/Thumnail for various PDF pages.

Java 5 supports following image types : "bmp jpeg wbmp gif jpg png" and mime types "image/png image/jpeg image/x-png image/vnd.wap.wbmp image/bmp image/gif".

API will fail to generate image If pdf has unsupported java image type like cmyk embedded.
 
PDF Renderer is a LGPL licensed pure-java library that makes this very simple:

public class Pdf2Image {

    /**
     * @param args
     */
    public static void main(String[] args) {
        File file = new File("c:/sample.pdf");
        RandomAccessFile raf;
        try {
            raf = new RandomAccessFile(file, "r");

            FileChannel channel = raf.getChannel();
            ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
            PDFFile pdffile = new PDFFile(buf);
            // draw the first page to an image
            int num=pdffile.getNumPages();
            for(int i=0;i<num;i++)
            {
                PDFPage page = pdffile.getPage(i);
               
                //get the width and height for the doc at the default zoom               
                int width=(int)page.getBBox().getWidth();
                int height=(int)page.getBBox().getHeight();               
               
                Rectangle rect = new Rectangle(0,0,width,height);
                int rotation=page.getRotation();
                Rectangle rect1=rect;
                if(rotation==90 || rotation==270)
                    rect1=new Rectangle(0,0,rect.height,rect.width);
               
                //generate the image
                BufferedImage img = (BufferedImage)page.getImage(
                            rect.width, rect.height, //width & height
                            rect1, // clip rect
                            null, // null for the ImageObserver
                            true, // fill background with white
                            true  // block until drawing is done
                    );

                ImageIO.write(img, "png", new File("c:/"+i+".png"));
            }
        }
        catch (FileNotFoundException e1) {
            System.err.println(e1.getLocalizedMessage());
        } catch (IOException e) {
            System.err.println(e.getLocalizedMessage());
        }
    }
}

Wednesday, June 15, 2011

Visual formatting model - DIV HTML Floats Issue

A float is a box that is shifted to the left or right on the current line. The most interesting characteristic of a float (or "floated" or "floating" box) is that content may flow along its side (or be prohibited from doing so by the 'clear' property). Content flows down the right side of a left-floated box and down the left side of a right-floated box.

Here is showing what happens when a float overlaps borders of elements in the normal flow.

Image showing a floating image
that overlaps the borders of two paragraphs: the borders are
interrupted by the image.  

A floating image obscures borders of block boxes it overlaps.
The following example illustrates the use of the 'clear' property to prevent content from flowing next to a float.
Example(s):
Assuming a rule such as this:

p { clear: left }
formatting might look like this:
Image showing a floating
image and the effect of 'clear: left' on the two paragraphs.   
Both paragraphs have set 'clear: left', which causes the second paragraph to be "pushed down" to a position below the float — "clearance" is added above its top margin to accomplish this.

Content Source - http://www.w3.org/TR/CSS2/visuren.html

Tuesday, June 14, 2011

Get Current Page Details in theme

1) To get current page title
 <portal-fmt:title varname="${wpsSelectionModel.selectedNode}"/>

2) Get selected page
javax.naming.Context ctx = new javax.naming.InitialContext();
com.ibm.portal.model.NavigationSelectionModelHome navigationSelectionModelHome = (com.ibm.portal.model.NavigationSelectionModelHome) ctx.lookup("portal:service/model/NavigationSelectionModel");
final com.ibm.portal.model.NavigationSelectionModelProvider nsmProvider = navigationSelectionModelHome.getNavigationSelectionModelProvider();
            final com.ibm.portal.navigation.NavigationSelectionModel nsm = nsmProvider.getNavigationSelectionModel(request, response);
            com.ibm.portal.model.ContentModelProvider cmProvider = contentModelHome.getContentModelProvider();
            com.ibm.portal.content.ContentModel contentModel = cmProvider.getContentModel( request, response );
           
            final NavigationNode currentNavNode = (NavigationNode) nsm.getSelectedNode();
            final ContentNode currentContentNode = currentNavNode.getContentNode();

3) ChildrenCount of Specific Page
<% String themeLinksUniqueNameRoot = "com.employeeportal.footer"; %>

<portal-navigation:navigation scopeUniqueName="<%=themeLinksUniqueNameRoot%>"  startLevel="1" stopLevel="1">
    <%
        int pageCount=((com.ibm.wps.model.wrappers.NavigationModelWrapper)wpsNavModel).getChildrenCount(((com.ibm.wps.model.wrappers.NavigationModelWrapper)wpsNavModel).findByUniqueName(themeLinksUniqueNameRoot));
     %>
       </portal-navigation:navigation>

Verify Websphere Portal User's Password

There are two ways to verify user's password -

1) Use "UserRegistry"
public static boolean checkUserAuthenticatedLDAP(String userId, String password) {
        try {
              Context ctx = new InitialContext();
              com.ibm.websphere.security.UserRegistry reg = (com.ibm.websphere.security.UserRegistry) ctx.lookup("UserRegistry");
              String res = reg.checkPassword(userId, password);
return res != null;
        } catch (Exception ex) {
              return false;
        }
  }

2) Use "LoginContext"
/**
     * This method validates the user based on the user id and password
     * attributes, If the user id or password is not valid then throws Exception.
     *
     * @param userId
     * @param password
     * @return boolean
     * @throws Exception
     */
    public boolean checkUserAuthenticated(String userId, String password) throws Exception {
        javax.security.auth.login.LoginContext loginContext = null;
        Subject subject = null;
        try {
            loginContext = new javax.security.auth.login.LoginContext("WSLogin", new com.ibm.websphere.security.auth.callback.WSCallbackHandlerImpl(userId, password));
        } catch (javax.security.auth.login.LoginException e) {
            throw new Exception("Cannot create LoginContext", e);
        }
        try {
            loginContext.login();
            subject = loginContext.getSubject();
        } catch (com.ibm.websphere.security.auth.WSLoginFailedException e) {
            throw new Exception("Password is incorrect", e);
        } catch (Exception e) {
            throw new Exception("Unknown username", e);
        }
        if (subject == null)
            throw new Exception("Password is incorrect");

        return true;
    }

Monday, June 13, 2011

Puma Service/User Details in (Theme, Servlet, Portlet)

a) Get details of User in Theme for loggedIn User
1) Use following tag lib to get basic user attribute value
<%@ taglib uri="http://www.ibm.com/xmlns/prod/websphere/portal/v6.0/portal-fmt" prefix="portal-fmt" %>
<portal-fmt:user attribute="givenName" /> <portal-fmt:user attribute="sn" />
2) To get other info like in which group user belongs to
<%
com.ibm.portal.puma.User portalUser=  (com.ibm.portal.puma.User) request.getAttribute(com.ibm.portal.RequestConstants.REQUEST_USER_OBJECT);
 if(portalUser!=null) {
    java.util.List groups = portalUser.getGroups();
        for (int i=0; i< groups.size() ; i++){
            com.ibm.portal.puma.Group grp = (com.ibm.portal.puma.Group)groups.get(i);
        }
}
%>

b) Get details of User in Servlet for loggedIn User
import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.naming.CompositeName;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ibm.portal.um.PumaHome;
import com.ibm.portal.um.PumaLocator;
import com.ibm.portal.um.PumaProfile;
import com.ibm.portal.um.User;
import com.ibm.portal.um.exceptions.PumaAttributeException;
import com.ibm.portal.um.exceptions.PumaMissingAccessRightsException;
import com.ibm.portal.um.exceptions.PumaModelException;
import com.ibm.portal.um.exceptions.PumaSystemException;

public class UserInfo extends HttpServlet {
    private static final long serialVersionUID = 1L;

    private PumaHome pumaHome;

    @Override
    public void init() throws ServletException {
        super.init();

        try {
            Context context = new InitialContext();
            Name pumaJndiName = new CompositeName(PumaHome.JNDI_NAME);
            pumaHome = (PumaHome) context.lookup(pumaJndiName);
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        String UIDParam = request.getParameter("uid");

        PumaLocator pLocator = pumaHome.getLocator();
        PumaProfile pProfile = pumaHome.getProfile();

        try {
            List<User> users =pLocator.findUsersByAttribute("uid", UIDParam);

            // get a list of attributes defined for this User
            List attribNames = pProfile.getDefinedUserAttributeNames();
            // Get a map of attribute values for this user
            Map userDetails = pProfile.getAttributes(users.get(0), attribNames);

            String userEmail = (String) userDetails.get("mail");
            System.out.println("UserInfo.doGet()" + UIDParam + ":"+ userEmail + ":" + users.size());
        } catch (PumaSystemException e) {
            e.printStackTrace();
        } catch (PumaAttributeException e) {
            e.printStackTrace();
        } catch (PumaMissingAccessRightsException e) {
            e.printStackTrace();
        } catch (PumaModelException e) {
            e.printStackTrace();
        }
    }

}

c) Get details of User in Portlet for loggedIn User

import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.portlet.ActionRequest;
import javax.portlet.PortletRequest;

import com.ibm.portal.portlet.service.PortletServiceHome;
import com.ibm.portal.um.PumaController;
import com.ibm.portal.um.PumaEnvironment;
import com.ibm.portal.um.PumaLocator;
import com.ibm.portal.um.PumaProfile;
import com.ibm.portal.um.User;
import com.ibm.portal.um.portletservice.PumaHome;
import com.ibm.websphere.security.UserRegistry;

public class UserProfileService {
    // This class uses PUMA SPI to access the LDAP and retrieve user profile information
    private static PumaHome pumaHome;

    // List of all Attribute Names that are defined in LDAP for USER group
    public static final String LAST_NAME = "sn";
    public static final String FIRST_NAME = "givenName";
    public static final String EMAIL = "mail";
    public static final String PASSWORD_USER_PROPERTY = "password";
    public static final String USERID_USER_PROPERTY = "uid";
    public static final String COMMONNAME_USER_PROPERTY = "cn";
   
    // Method to connect and create a PumaHome object
    public UserProfileService() {
        try {
            Context ctx = new InitialContext();
            PortletServiceHome psh = (PortletServiceHome) ctx
                    .lookup("portletservice/com.ibm.portal.um.portletservice.PumaHome");

            if (psh != null) {
                pumaHome = (PumaHome) psh.getPortletService(PumaHome.class);
            }

        } catch (Exception ne) {
            // ne.printStackTrace();
            pumaHome = null;
        }

    }

    public Map getUserProfile(PortletRequest req) {
        Map userDetails = null;
        // Util method that uses PUMA SPI to load user attributes from LDAP into
        // // a domain object (LmsUser)
        if (pumaHome == null) {
            return null;
        } else {
            try {
                // first get a PumaProfile object
                PumaProfile pumaProfile = pumaHome.getProfile(req);
                // get a list of attributes defined for this User
                List attribNames = pumaProfile.getDefinedUserAttributeNames();

                // Get a map of attribute values for this user
                userDetails = pumaProfile.getAttributes(pumaProfile
                        .getCurrentUser(), attribNames);
                System.out.println("userDetails::::::"+userDetails);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        return userDetails;
    }

    public static PumaHome getPumaHome() {
        if (pumaHome == null) {
            try {
                PortletServiceHome psh;
                Context ctx = new InitialContext();
                psh = (PortletServiceHome) ctx.lookup(PumaHome.JNDI_NAME);
                if (psh != null) {
                    pumaHome = (PumaHome) psh.getPortletService(PumaHome.class);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return pumaHome;
    }

    protected static PumaLocator getPumaLocator(PortletRequest portletRequest) {
        PumaLocator pumaLocator = getPumaHome().getLocator(portletRequest);
        return pumaLocator;
    }
    protected static PumaProfile getPumaProfile(PortletRequest portletRequest) {
        PumaProfile pumaProfile = getPumaHome().getProfile(portletRequest);
        return pumaProfile;
    }

    protected static PumaEnvironment getPumaEnvironment() {
        PumaEnvironment pumaEnvironment = getPumaHome().getEnvironment();
        return pumaEnvironment;
    }
    protected static PumaController getPumaController(PortletRequest portletRequest) {
        PumaController pumaController = getPumaHome().getController((ActionRequest) portletRequest);
        return pumaController;
    }
    public static void changePasswordLDAP(ActionRequest actionRequest, String password) {
        final PumaProfile pf = getPumaProfile(actionRequest);
        final PumaController pc = getPumaController(actionRequest);
        final PumaEnvironment pe = getPumaEnvironment();
        final Map userSetAttr = new HashMap();
        final List passwd=new ArrayList();
        passwd.add(password);
        // set AD password attribute in the Map
        userSetAttr.put(PASSWORD_USER_PROPERTY, passwd);
        try {
            pe.runUnrestricted(new PrivilegedExceptionAction() {
                public Object run() {
                    try {
                            User user = pf.getCurrentUser();
                            pc.setAttributes(user, userSetAttr);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return null;
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

Dojo Profiling - Improve performance of Web applications that use Dojo by almost 30 to 40%

A tutorial has been published by IBM developersworks channel to increase the performance of Webapplications that uses DOJO by almost 30 % to 40 %.
I have gone through steps described in it and found significant improvement in a test web application.
The tutorial describes how to shrink the DOJO libraries and load the required widgets only. It minimizes server roundtrip to load all dojo widgets so automatically responses time gets reduced.

WebLink - http://www.ibm.com/developerworks/websphere/techjournal/1003_col_haverlock/1003_col_haverlock.html?S_TACT=105AGX54&S_CMP=D0311&ca=dnw-1110&ca=dth-w

Universal Test client application to troubleshoot JNDI lookup

I found this very useful when debugging EJB application, so thought of Sharing through myblog.

The Rational Application Developer has a IBM Universal Test client enterprise application which is web based application that you can use to test your EJB's or JPA beans or look at the JNDI tree in your server,.. Essentially it is set of tools to troubleshoot problems.

You can follow these steps to enable IBM Universal Test client.

  1. Double click on your server name to open the server definition. On that page check "Enable universal test client " check box
  2. Once you save the server definition you will notice that the UTC application is getting deployed on your server, wait for couple of minutes to get it started
  3. Right click on the Server name and click on Universal test client > Run to access universal test client
  4. The RAD will open http://localhost:10039/UTC/ URL in the browser if you want you can directly access this page from outside the RAD
  5. RAD will prompt you to login use the was admin user and password and you should see next screen with JNDI Explorer, JPA explorer,.. use the section that you want to explore, in my case i went to JNDI explorer to see all the name bindings like this. You can also test exposed methods of Object.

    Content Source - http://wpcertification.blogspot.com/2011/04/universal-test-client-application.html

PumaEnvironment's runUnrestricted

All the users in portal having some access rights associated with it. So this restricts users to update and look for the other users & groups attributes value.
So the solution in this scenario is – run your code as admin.
This can be done through PumaEnvironment's runUnrestricted method.
See the sample code below –

PumaEnvironment pe = pumaHome.getEnvironment();
try {
    pe.runUnrestricted(new PrivilegedExceptionAction() {
        public Object run() {
            //write your logic here to find groups

            return null;
        }
    });
} catch (PrivilegedActionException e) {
    throw e;
}

Reflecting LDAP attribute changes in WebSphere Portal immediately

To fix this problem have to disabling VMM and Puma caching.

There are two scenarios from where LDAP values get changed and those value wouldn't reflect in Portal immediately :
a) Explictly made changes in ADS via some tool or using ADS console
b) Some time ads policies are enforced and sometimes changes in some attribute values change the other attribute value internally.
Like - If we change password for user then password_last_set timestamp value will get updated automatically.

To disable VMM and PUMA caching here are the steps:

a.       Add a new entry in WP Puma Store Service to disable PUMA cache
                                                               i.      Login to IBM console goto “Resource environment entries -> WP PumaStoreService -> Custom properties”
                                                             ii.      Set the property store.puma_default.userManagement.cacheMode to false to turn off the PUMA cache. Ex-
store.puma_default.userManagement.cacheMode        false
b.      Use the $AdminTask to update the cache properties accordingly. To turn off the cache for the LDAP in VMM
                                                               i.      Open a command prompt
                                                             ii.      Switch to wp_profile/bin and type wsadmin
                                                            iii.      Run the following command to disable attribute caching
1.       $AdminTask updateIdMgrLDAPAttrCache {-id TestADS -enabled false}
2.       $AdminConfig save
                                                           iv.      Run the following command to disable searchresult caching
1.       $AdminTask setIdMgrLDAPSearchResultCache {-id TestADS -enabled false}
2.       $AdminConfig save

I had followed this link also tuning of WebSphere Portal Caching is described on this page -
http://www-01.ibm.com/support/docview.wss?uid=swg21379992

Set Public Render Parameters in Theme

You can use the following tag to reset render parameters from theme -
<portal-navigation:navigationUrl type="launch" keepNavigationalState="false"/>
It is described under the following link - http://publib.boulder.ibm.com/infocenter/wpdoc/v6r1/index.jsp?topic=/com.ibm.wp.ent.doc_v6101/dev/dgn_ptlnavig.html

<portal-navigation:urlGeneration/> tag can be used together with <portal-navigation:urlParam/> to pass action/render parameters to a portlet.

It is described under the following URL - http://publib.boulder.ibm.com/infocenter/wpdoc/v6r1/index.jsp?topic=/com.ibm.wp.ent.doc_v6101/dev/dgn_link.html

Personalizing Page & Portlet using external data (user resource)

Objective : The objective of this documentation is to introduce you to an important feature in Portal 6.1 called Attribute Based Administration using external resource collection

Overview : Attribute Based Administration provides a facility to customize the site layout for individual users or groups of users via “Visibility Rules”. Visibility Rules instruct Portal to: Show or hide pages and portlets  based on dynamic characteristics that are determined at runtime according to business rules.

Note: All the screenshots are captured from RSAv7.5.4

1)     For running this Lab exercise prerequisites are :
a.     Portal Server v6.1.0.3 or higher
b.    Derby10.1(Network Server) – Derby Client JDBC Driver
c.     RSA or RAD v7.0 or higher
2)     Start derby database
a.     Start derby service using the following command  -
${WebSphere_AppServer_HOME)\derby\bin\networkServer\startNetworkServer.bat
3)     Create a database and table in derby using RSA/RAD
a.     Setting JDBC Driver for Derby10.1  client
                                          i.    Open the RSA – ignore if already open
                                         ii.    Goto Window-> Preferences (
                                        iii.    Expand “Data Management”->”Connectivity” tab then click on “Driver Definitions”
                                        iv.    From the list of Database driver name , select “Derby 10.1 – Derby Client JDBC Driver Default” and click on edit button, “Edit Driver Definition” a new window will open
                                         v.    Switch to “Jar List” tab
                                        vi.    Specify correct JDBC driver jar file for Derby10.1 client Ex - ${WebSphere_AppServer_HOME)\derby\lib\derbyclient.jar By clicking on “Add Jar/Zip” button.
b.    Create the database & table required
                                          i.    Open the RSA – ignore if already open
                                         ii.    Switch to “Database Development” perspective
                                        iii.    Define “Database Connections” – Right click on “Database Connections” and chose “New…” option from context menu. Specify database connection parameters similar to below captured screenshot. Password is user

                                        iv.    Click on “Test Connection” button to check Derby DB availability. Once db pinged successfully click on Finish button
                                         v.    Right click on “pzn_user_resource” database connection and choose “New Sql Script” option
                                        vi.    In SQL Script window paste following SQL Scripts to generate sample table and its data
Note: Users_id column must contain the same value for user’s uid attribute that is defined in WPS server user repository Like – LDAP

CREATE TABLE app.USERS (
            USER_ID VARCHAR(100) NOT NULL primary key,
            DEPT_ID INTEGER
);
insert into app.users values('uid=wpadmin,o=defaultWIMFileBasedRealm',1);      
insert into app.users values('uid=shashi,o=defaultWIMFileBasedRealm',2);

                                       vii.    Right click on “SQL Script window” and select “Run SQL” option; it will execute all the sql statement written in SQL editor window. Resultant user’s table will create and be populated with sample data.

4)     Create a empty portlet project
a.     Open the RSA – ignore if already open
b.    Switch to web perspective
c.     Create a new empty portlet project and specify filed value similar to below captured screenshot and click on finish button.



5)     Create “Content or User Resource”
a.     Open the RSA – ignore if already open
b.    Select & Right Click on “PZN_demo” portlet project and select “New->Other” option
c.     Expand “Portal”->”Personalization” and select “Content or User Resource” and click on next button.
d.    Chose “SQL” as a protocol and “Web users” as resource collection as captured in below screenshot. Click on next button.





e.     Select “pzn_user_resource” as existing database connection and click on next button



f.     The personalization resource wizard opens. On the Tables tab, highlight USERS by single clicking on it. Click the arrow button pointing to the right to select the table. Click Primary Table to mark it as the primary table.





g.    Select the Columns tab. On the Columns tab, move all columns to the right by clicking the double arrow button. Notice the primary key is the column User_ID.



h.     Click the Mappings tab. On the Mappings tab, select Dept_id and click Populate.





i.      Click the Select buttons and expand APP > USERS to select DEPT_ID for the Description and Value fields. Click OK.



j.      Click the Deployment tab.
k.     On the Deployment tab, change the datasource to jdbc/pzndemo. This datasource is required to define in WAS.



l.      Click Next


m.   Set the package name as pzndemo. Select Include schema names in the generated Resource Runtime Manager.




n.     Click Finish.
You can now see the new JAVA classes in your project:





6)     Create a datasource using appserver console
a.     Start the portal sever – if not already started
b.    Open a browser and type https://localhost:10041/ibm/console and enter logic credentials
c.     Define “J2c Authentication Data”
                                          i.    Expand "Security" section and click on "Secure administration, applications and infrastructure"
From right side box "Java Authentication and Authorization Service" expand it and click on "J2C authentication data"



                                         ii.    Click on New Button
                                        iii.    Specify pzndemo_derby as alias, user as user and password as user





                                        iv.    Click on apply button, then click on save link
Once you click on save link you will get screen similar to below, newly create “J2c authentication data is listed”



d.    Define Derby JDBC provider
                                          i.    Expand "Resources">JDBC and click on JDBC Provider
In the JDBC Provider block, select Server as websphere_portal and click on new button





                                         ii.    Specify JDBC provider information then click on next button then finish button



                                        iii.    Click on Save link





e.     Create a databsource with JNDI name “jdbc/pzndemo”
                                          i.    Expand "Resources"> "JDBC" click on "Data sources" link
In the Data Sources block, select Server as WebSphere_Portal and click on New Button



                                         ii.    Specify datasource name, JNDI name & Component-managed based authentication alias



                                        iii.    Click on Next.



                                        iv.    Select JDBC Provider just created




                                         v.    Click on next
                                        vi.    Specify database name “pzn_user_resource” and click on next button then Finish button



                                       vii.    Click on save link. Select the newly created Datasource and click on “Test Connection” button. If all setting is correct then you will get following message.


7)     Deploy & Import Personalization Workspace resource collections
a.     Deploy pzn_demo personalization code
                                          i.    Place pzndemo class files into a directory accessible by that portlet. To do this, export the pzndemo folder in RSA under PZN_demo/Java Resources: src as a JAR file. Make the target location PortalServer_root/pzn/prereq.pzn/collections/pzndemo.jar. Accept the defaults and click Finish



b.    Restart Portal Server
c.     Import Personalization resource collections
                                          i.    Login to portal server using admin credentials
                                         ii.    Click the Applications>Content>Personalization>Business Rules
                                        iii.    In the Personalization Navigator portlet, click New > Folder



                                        iv.    Enter the name Pzn demo and click save





                                         v.    Change to the Pzn demo folder.



                                        vi.    Click Import
                                       vii.    Browse to find the Users.hrf file in your {RSA workspace}/PZN_demo/WebContent/WEB-INF/pzn-resourceCollections/pzndemo project directory.
                                      viii.    See the resource collection in the Workspace.





8)     Create Simple Visibility Rules (We need to display or hide a portlet based on personalized rule)
a.     Login to the portal server using admin credentials
b.    Click the Applications>Content>Personalization>Business Rules
c.     In the Personalization Navigator portlet, Change to the Pzn demo folder
Then click New > Rule



d.    Type "PZN_demo Visibility Rule" in the New Rule field.





e.     Select “Visibility Rule” from the Rule Type drop-down list.
f.     click on “attribute” on the rule editor and select Users -> Dept_id



g.    Specify 1 for the value and click submit.



h.     Click Save. The completed rule will list like the following example.



9)     Apply Personalization Rule to Page or Portlet
a.     Open a Web Browser window and browse to http://localhost:10040/wps/portal Login using admin credentials
b.    Create a new page under Home ex.“About WebSphere” using portal administration and add some out-of-box portlet like – “About WebSphere Portal”. Move your mouse to the About WebSphere & click on the down arrow icon to open the context menu.  Click on “Edit Page Layout”





c.     Click on Show Portlet Rule Mappings



d.    Click on Select Rule





e.     From Personalization Picker select “PZN demo Visibility Rule” rule and click on ok


f.     Click Done on the Page Layout Page.  Depending on the users dept_id the portlet that was configured with this rule would be visible or not.




*****Lab Files are here
http://www.box.net/shared/b00thbvypqqrazt19hyb
http://www.box.net/shared/r9nyfmccba87nc4ot0sl