Guys !!! Checkout my new application. Just upload your error/log file and trace all the exceptions along with detailed output in various formats (like xml, text, json).

Want To Search Something Else? Just Google It !

Sunday, October 2, 2011

Opening Portlet with Maximized Window in Render Mode

There is no provision in portlet API for opening a portlet with maximized window in render mode (doView() method). When a portlet gets loaded into browser for the first time, it always opens up in normal window.

I happened to come across a scenario where I had to open-up portlet in a maximized window which I achieved in following way:

javax.portlet.PortletURL object allows to set Window State. We can utilize this facility in following way to open a portlet with maximized window in render (doView() method) mode.

1. In doView method, Generate a render URL from renderResponse.
2. Add all the request parameters from renderRequest to these new URL.
3. Set window state to Maximized on this new URL.
4. Set this new URL value as renderRequest attribute and pass the control to view.jsp (your jsp file which generates output in render mode).
5. In view.jsp, retreive the URL we created in step-1 and redirect the page to this new URL using javascript by setting location.href value.

That's it. Next time, when the portlet will be rendered, it will open up in Maximized mode.

Following is the piece of code for both doView() method of Portlet class and view.jsp.

In Portlet Class,

public void doView(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException
    {
      
        if(renderRequest.getWindowState() != WindowState.MAXIMIZED)
        {
            //Create a render URL
            PortletURL url = renderResponse.createRenderURL();
          
            //Pass all the parameters from existing request to this new URL
            Enumeration params = renderRequest.getParameterNames();
          
            while(params.hasMoreElements())
            {
                String pname = params.nextElement().toString();
                url.setParameter(pname, renderRequest.getParameter(pname));
            }
          
            //Set window state to Maximized on newly created URL
            url.setWindowState(WindowState.MAXIMIZED);
          
            //Set this URL as attribute in renderRequerst
            renderRequest.setAttribute("maximizedUrl", url.toString());
          
          
            renderRequest.setAttribute("isMaximized", "false");
          
        }
        include(viewJSP, renderRequest, renderResponse);
    }
   

protected void include(String path, RenderRequest renderRequest,RenderResponse renderResponse) throws IOException, PortletException
{
            PortletRequestDispatcher portletRequestDispatcher =
                                               getPortletContext().getRequestDispatcher(path);
            if (portletRequestDispatcher == null)
            {
                Logger.error(path + " is not a valid include");
            }
            else
            {
                portletRequestDispatcher.include(renderRequest, renderResponse);
            }
}


In view.jsp,

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>

<jsp:useBean class="java.lang.String" id="maximizedUrl"
    scope="request" />
<jsp:useBean class="java.lang.String" id="isMaximized"
    scope="request" />

<portlet:defineObjects />


<script type="text/javascript">
    var maximizedFlag = '<%=isMaximized%>';
   
    //Redirect to New Render URL only if current window is not in maximized state
    if(maximizedFlag=='false')
    {
        location.href='<%=maximizedUrl%>';  
    }
</script>

 

Wednesday, September 28, 2011

Liferay Alfresco Integration

With the time, Liferay and Alfresco have matured in terms of capabilities, both the products have their own focal point in terms of offerings. Where liferay's main focus is collaboration features, Alfresco is better in document management and record management.  With this said, there are many scenarios where need rises to integrate both the systems in order to provide better software solutions and architectures.  

There are multiple ways we can integrate alfresco with liferay. I will explain two of them which I have used along with benefits/drawbacks which I know. 

Method-1. Integrating Alfresco with Liferay using CMIS 1.0

Content Management Interoperability Services (CMIS) - is a standard protocol which consists a set of web services for sharing information among different content management systems to provide interoperability and integration for people and applications using multiple content repositories.

Liferay 6 and Alfresco 3.3 both provides CMIS support. Here I will explain how to integrate Alfresco 3.3 (or higher) with Liferay 6 (Tomcat Bundle). 

1. Download Alfresco(Community or Enterprise edition) share.war and alfresco.war (version 3.3 or higher). You can download it from following URLs.

Community Edition: http://wiki.alfresco.com/wiki/Download_Community_Edition
Enterprise Edition: http://www.alfresco.com/try/    (30-Days trial version)

2. Download and install Liferay 6 (EE or CE). ou can download it from http://www.liferay.com/downloads/liferay-portal/available-releases

3. Copy alfresco.war and share.war from $ALFRESCO_HOME/tomcat/webapps to  $LIFERAY_HOME/tomcat/webapps.

4. Create a database alfresco in MySQL. (Assuming you are using MySQL database)
drop database if exists alfresco;
create database alfresco character set utf8;
grant all on alfresco.* to 'alfresco'@'localhost' identified by 'alfresco' with grant option;
grant all on alfresco.* to 'alfresco'@'localhost.localdomain' identified by 'alfresco' with grant option;


5. Create a database lportal in MySQL. (Assuming you are using MySQL database)
drop database if exists lportal;
create database lportal character set utf8;
grant all on lportal.* to 'lportal'@'localhost' identified by 'lportal' with grant option;
grant all on lportal.* to 'lportal'@'localhost.localdomain' identified by 'lportal' with grant option;


6. Create a file named portal-ext.properties at $LIFERAY_HOME/tomcat/webapps/ROOT/WEB-INF/classes and add following lines in portal-ext.properties.
dl.hook.impl=com.liferay.documentlibrary.util.CMISHook
cmis.credentials.username=admin
cmis.credentials.password=admin
cmis.repository.url=http://localhost:8080/alfresco/service/api/cmis (NOTE: This URL will be the URL where you alfresco is running. Change the value accordingly)
cmis.repository.version=1.0
cmis.system.root.dir=Liferay Home

7. Add Database entry in portal-ext.properties (Assuming you are using MySQL database)

             ## MySQL
             jdbc.default.driverClassName=com.mysql.jdbc.Driver
             jdbc.default.url=jdbc:mysql://localhost:3306/lportal?useUnicode=true&characterEncoding=UTF- 
            8&useFastDateParsing=false (Change according to your DB settings)
            jdbc.default.username=lportal (Change according to your DB settings)
            jdbc.default.password=lportal (Change according to your DB settings)


8. That's it. Start Liferay and you are through. Whatever documents you create from Liferay Document Library will directly get stored into Alfresco. 


Advantages:

This integration method enables us to run both liferay and alfresco independently from each other and still have a nice level of integration for document management.  

Disadvantages:

a. When any document is created/uploaded in liferay document library it stores document meta-data in liferay data store and actual document in Alfresco. 

So if you store any document directly from Alfresco, it doesn't get reflected in Liferay document library. 

b. Alfresco maps the document hierarchy with it's own numeric notations: For example, if a document named MyInfo.pdf is stored under Document Library -> My Docs -> Personal Info -> MyInfo.pdf in liferay, alfresco maps it similar to following: 

Liferay Home -> 10232(this is liferay instance id) -> 10280 (this is liferay folder id) - > 1 (numerically named folder created for each document uploaded from Liferay) ->1 (Actual document named as 1)

This mapping notation makes it very difficult to track the documents directly from Alfresco.  Also since the meta-data information is stored in liferay, when we try to open document directly from alfresco, it fails. 

c. When we delete any document from liferay, it only deletes the meta-data information. The actual document remains stored in alfresco. 


Method-2. Integrating Alfresco Web Client as portlet in Liferay

This method deploys alfersco.war (web client) as portlet in liferay.  Following are the stes to achieve this:


1. Download Alfresco(Community or Enterprise edition)  alfresco.war (version 3.3 or higher). You can download it from following URLs.

Community Edition: http://wiki.alfresco.com/wiki/Download_Community_Edition
Enterprise Edition: http://www.alfresco.com/try/    (30-Days trial version)

2. Download and install Liferay 6 (EE or CE). ou can download it from http://www.liferay.com/downloads/liferay-portal/available-releases

3. Extract(Unzip) alfresco.war to any directory of your choice.

4. Update dir.root in $ALFRESCO_HOME/ WEB-INF/classes/alfresco/repository.propertes.
      
     dir.root=../../alf_data

5. Create a database alfresco in MySQL. (Assuming you are using MySQL database)

drop database if exists alfresco;
create database alfresco character set utf8;
grant all on alfresco.* to 'alfresco'@'localhost' identified by 'alfresco' with grant option;
grant all on alfresco.* to 'alfresco'@'localhost.localdomain' identified by 'alfresco' with grant option;

6. Remove the file from WEB-INF/lib/portlet-api-lib.jar 

7.  Add /WEB-INF/faces-config.xml to the faces config files list at $ALFRESCO_HOME/WEB-INF/web.xml like
     <context-param>
      <param-name>javax.faces.CONFIG_FILES</param-name>
      <param-value>/WEB-INF/faces-config.xml,/WEB-INF/faces-config-app.xml,/WEB-INF/faces-config-beans.xml,/WEB-INF/faces-config-navigation.xml,/WEB-INF/faces-config-common.xml,/WEB-INF/faces-config-repo.xml,/WEB-INF/faces-config-wcm.xml,/WEB-INF/faces-config-custom.xml</param-value>
</context-param>

8. Download and add files: faces-config.xml, liferay-display.xml, liferay-portlet.xml, portlet.xml to WEB-INF. You can
      download these files from http://liferay.cignex.com/palm_tree/0387/sso/liferay/alfresco-portlet/

9. Package all files as a WAR: alfresco.war and copy it to $LIFERAY_HOME/deploy folder.

10. Start Liferay and you are through. All the alfresco portlets will be available under Alfresco category from the Add dropdown menu. 

Advantages:



This method lets you run alfresco web client directly as portlet under liferay and removes complexity of maintaining two separate systems.   


Disadvantages:

We have to manually edit the source files of alfresco.war. 


Feel free to provide any comments/suggestions/enhancements.