Friday, February 25, 2011

Changing portal page to use a layout template

If you create a portal page from portal administration user interface:


the chances are you will not be able to use the "PageBuilder2" feature to add new portlet into the page (using "Actions" - "Customize").  To enable the page to use the feature you need to do the following:
1. Export the page definition into xml file
2. Update the xml file by adding the following parameter for the specific <content node>


            <parameter name="com.ibm.portal.layout.template.expiration" type="string" update="set"><![CDATA[1297730961223]]></parameter>
            <parameter name="com.ibm.portal.layout.template.file.name.html" type="string" update="set"><![CDATA[layout.html]]></parameter>
            <parameter name="com.ibm.portal.layout.template.lastmodified" type="string" update="set"><![CDATA[1297644561353]]></parameter>
            <parameter name="com.ibm.portal.layout.template.markup" type="string" update="set"><![CDATA[html]]></parameter>
            <parameter name="com.ibm.portal.layout.template.ref" type="string" update="set"><![CDATA[dav:fs-type1/layout-templates/3ColumnCenter]]></parameter>

into the <content-node> stanza for the specified portal page.

3. We also need to update the type of the content node to "staticpage"

<content-node action="update" active="true" allportletsallowed="true" content-parentref="Z6_020K9B1A0823E0IE07U5O500O0" create-type="explicit" domain="rel" objectid="Z6_020K9B1A0GIU80IE2099SD20H6" ordinal="600" type="staticpage">

4. Re-import the xml file

Hope this helps..

Friday, February 18, 2011

Using SAP extension in WebSphere Portlet Factory and WebSphere Application Server Community Edition

I have WebSphere Portlet Factory 7.0 running on Ubuntu Linux 10.10. I also used WAS CE  version 2.1.1.4 as the test environment.

I have to do the following to allow SAP extension

  • Get the SAPJCo from SAP administrator
  • Install the SAPJCO according to the documentation provided by SAP for linux environment
  • Add class path variable into /etc/environment:
           CLASSPATH="/opt/sapjco/sapjco.jar"
  • Add path to the /opt/sapjco folder. (This is also done in /etc/environment file).  The following is the content of my /etc/environment file
                  PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/sapjco"
                      LD_LIBRARY_PATH="/opt/sapjco"
                        CLASSPATH="/opt/sapjco/sapjco.jar"
      • Add "LD_LIBRARY_PATH=/opt/sapjco" at the end of /etc/bash.bashrc file
      • Restart your system
      • Follow the instruction in http://publib.boulder.ibm.com/infocenter/wpfhelp/v6r1m0/index.jsp?topic=/com.bowstreet.designer.doc/get_start/sap_getting_started.htm
      After the above steps, I am able to do a "Test Connection" from the builder, however, when trying to test the application, I got "noclassdeffounderror" for the jco class. In order to fix that, I have to update geronimo.sh file and add /opt/sapjco, into $EXT_DIRS variable.

      Restart your server after that. Then you should be able to test the model

      Thursday, October 7, 2010

      Redirecting 404 error if users type in invalid URL which starts with /wps/portal

      As a default behavior in portal 6.1.x, if a user type in a url, which starts in /wps/portal/*, in a browser's window, the portal server will automatically redirect user to the first available anonymous page in portal. The example of the URL includes: http://<serveraddress>/wps/portal/invalidpage. Sometimes this behavior is not acceptable by some portal users, the requirements is to let the user knows that the page does not exist or no longer exist.

      In order to change this behavior we need to intercept the http status code 404, and modify the default redirection to redirect to a specified page. The best way to do that is to write a servlet filter and a wrapper for the servlet response.

      • The servlet filter:
        package com.servletFilter;

        import javax.servlet.Filter;
        import javax.servlet.FilterConfig;
        import javax.servlet.ServletException;
        import javax.servlet.http.HttpServletResponse;


        /**
         *
         * This is the servlet filter that wrap the servlet response object
         * and use it in the FilterChain
         * The wrapper will store the status code and do the re-direct if necessary
         */
        public class Redirect404 implements Filter {
          

            public void destroy() {
                // TODO Auto-generated method stub

            }

            public void doFilter(javax.servlet.ServletRequest request, 
                      javax.servlet.ServletResponse response,
                      javax.servlet.FilterChain chain)
                  throws java.io.IOException, javax.servlet.ServletException{

                HttpStatusServletResponse statusResponse =
                    new HttpStatusServletResponse((HttpServletResponse) response);
                chain.doFilter(request, statusResponse);
                int status = statusResponse.getStatus();
                System.out.println("******** Status: " + status);
            }   

            public void init(FilterConfig arg0) throws ServletException {
               
            }
        }
         

        •  The servlet response wrapper
        package com.servletFilter;

        import java.io.IOException;

        import javax.servlet.http.HttpServletResponse;
        import javax.servlet.http.HttpServletResponseWrapper;

        /**
         *
         * This is a wrapper class which is used to store the HTTP Status Code and modify the redirect.
         * 
         */
        public class HttpStatusServletResponse extends HttpServletResponseWrapper {

            private int httpStatus;

            public HttpStatusServletResponse(HttpServletResponse response) {
                super(response);
            }

            @Override
            public void sendError(int sc) throws IOException {
                httpStatus = sc;
                    super.sendError(sc);
            }

            @Override
            public void sendError(int sc, String msg) throws IOException {
                httpStatus = sc;
                    super.sendError(sc, msg);
            }

            @Override
            public void sendRedirect(String location) throws IOException {
                System.out.println("******* Calling sendRedirect, location is: " + location);
                if (httpStatus == SC_NOT_FOUND)
                    location = "/wps/portal/404Error";
                super.sendRedirect(location);
            }

            @Override
            public void setStatus(int sc) {
                httpStatus = sc;
                super.setStatus(sc);
            }

            @Override
            public void flushBuffer() throws java.io.IOException {
                    super.flushBuffer();
            }
           
            public int getStatus() {
                return httpStatus;
            }

        }

          We need to place these class files in a place the classpath of WebSphere Portal server. I placed it in: <portal_root>/shared/ext.

          We also need to modify the web.xml of wps.war, to add the filter definition and filter mapping. The following is the definition:
              <filter>
                  <filter-name>Error 404 Redirect</filter-name>
                  <filter-class>com.servletFilter.Redirect404</filter-class>
              </filter>
              <filter-mapping>
                  <filter-name>Error 404 Redirect</filter-name>
                  <url-pattern>/portal/*</url-pattern>
              </filter-mapping>



          To update web.xml, you will need to export wps.ear (using wsadmin.sh|bat), expand wps.ear (using EARExpander.sh|bat), update web.xml (located at wps.war/WEB-INF), collapse back the wps.ear (using EARExpander.sh|bat), and install the new wps.ear back to portal server (using wsadmin.sh).  The detailed instruction can be found in the following reference: How to redirect to a custom error page when HTTP 404 Not Found encountered on Non-URL Resources ("Resolving the problem" section).


          References:

          Tuesday, September 7, 2010

          Working with theme after upgrading WebSphere Portal from 6.1.x to 6.1.5

          We have a custom theme based on PortalWeb2 in IBM WebSphere Portal 6.1.0.2. The theme was working fine. As part as the customization, we have to update ibmCSA.js

          Recently we upgraded WebSphere Portal to version 6.1.5.1, which uses Dojo 1.3.2. Because we want to use the latest Dojo packages, we need to:
          1. Apply the same modification of ibmCSA.js.uncompressed.js located in wp_profile_root/installedApps/node_name/Dojo_Resources.ear/dojo.war. Once the file has been modified, it is recommended that we compressed it.
          2. Follow the instruction in http://publib.boulder.ibm.com/infocenter/wpdoc/v6r1/topic/com.ibm.wp.ent.doc_v615/dev/dojo_overview.html?resultof=%22%70%6f%72%74%61%6c%5f%64%6f%6a%6f%22%20, section "Using Dojo V 1.3.2 in your custom portal theme"
           

          Sunday, September 5, 2010

          Profiling a Portlet in a remote WebSphere Portal Server

          I have been trying profile/monitor my custom portlet behavior in a remote WebSphere Portal Server and just recently successfully able to perform this task. The following is my configuration:

          Local Development Workstation:
          • Rational Application Developer 7.5.5 (you need to include portal toolkit with WebSphere Portal 6.1 stub)
          Remote Portal Server:
          • WebSphere Portal 6.1.5.1
          • Rational Agent Controller 8.1.3
          • OS:  Windows 2003 SP 2
          I follow the following document from IBM Web Site:
          http://www-01.ibm.com/support/docview.wss?uid=swg27016728&aid=1

          The following are the environment variables that I have to set on the remote machine:
          • JAVA_PROFILER_HOME=c:\IBM\SDPNew\AgentController\plugins\org.eclipse.tptp.javaprofiler
          • LIB=%LIB%;c:\IBM\SDPNew\AgentController\plugins\;c:\IBM\SDPNew\AgentController\bin; c:\IBM\SDPNew\AgentController\lib
          • Path=%PATH%;c:\IBM\SDPNew\AgentController\plugins\;c:\IBM\SDPNew\AgentController\bin; c:\IBM\SDPNew\AgentController\lib;c:\IBM\SDPNew\AgentController\plugins\org.eclipse.tptp.javaprofiler
          • PROBEKIT_HOME=c:\IBM\SDPNew\AgentController\plugins\org.eclipse.hyades.probekit
          • TPTP_AC_HOME=c:\IBM\SDPNew\AgentController
          Note: I installed Rational Agent Controller at c:\IBM\SDPNew folder

          I also have to match the port number that is located in c:\IBM\SDPNew\AgentController\config\serviceconfig.xml:
              <TransportLayer loadlib="socketTL" type="TPTP_SOCKET">
                      <Configuration>
                          <Port>60006</Port>
                          <SecurityEnabled>false</SecurityEnabled>
                      </Configuration>
                      <CommandExtractor>tptpCmdExtr</CommandExtractor>
                  </TransportLayer>

          with the port specified in RAD:

          The last thing I have to do is to run setconfig tools, to make sure that the jvm version used by agent controller is the same as the jvm run on WebSphere.

          After configuring the system as specified above, I am able to profile my custom portlet