cancel
Showing results for 
Search instead for 
Did you mean: 

Liferay JSR-168 (Portlets) and Web Scripts

jett
Champ in-the-making
Champ in-the-making
I tried creating a portlet in Netbeans that references a Web Script in Alfresco. The webscript has not problems as I can "call" it directly from http://host/alfresco/services . When I deploy the portlet WAR file however, I am getting the following error message from the Tomcat log:

15:45:17,921 INFO  [AutoDeployDir:76] Processing alfsample.war
15:45:17,921 INFO  [PortletAutoDeployListener:78] Copying portlets for C:\Docume
nts and Settings\Jett\liferay\deploy\alfsample.war
15:45:17,921 INFO  [BaseDeployer:529] Deploying alfsample.war
  Expanding: C:\Documents and Settings\Jett\liferay\deploy\alfsample.war into E:
\POCs\azeus\liferay-portal-tomcat-5.5-5.1.2\temp\20081228154517921
  Copying 1 file to E:\POCs\azeus\liferay-portal-tomcat-5.5-5.1.2\temp\200812281
54517921\WEB-INF\classes
  Copying 1 file to E:\POCs\azeus\liferay-portal-tomcat-5.5-5.1.2\temp\200812281
54517921\WEB-INF\classes
  Copying 1 file to E:\POCs\azeus\liferay-portal-tomcat-5.5-5.1.2\temp\200812281
54517921\META-INF
15:45:22,953 INFO  [BaseDeployer:1244] Modifying Servlet 2.5 E:\POCs\azeus\lifer
ay-portal-tomcat-5.5-5.1.2\temp\20081228154517921\WEB-INF\web.xml
  Warning: META-INF\MANIFEST.MF modified in the future.
  Warning: WEB-INF\lib\alfresco-webscript-framework.jar modified in the future.
  Warning: WEB-INF\lib\spring-2.0.6.jar modified in the future.
  Warning: WEB-INF\lib\spring.jar modified in the future.
  Warning: WEB-INF\liferay-plugin-package.properties modified in the future.
  Warning: index.jsp modified in the future.
  Copying 20 files to E:\POCs\azeus\liferay-portal-tomcat-5.5-5.1.2\webapps\alfs
ample
  Copying 1 file to E:\POCs\azeus\liferay-portal-tomcat-5.5-5.1.2\webapps\alfsam
ple
  Deleting directory E:\POCs\azeus\liferay-portal-tomcat-5.5-5.1.2\temp\20081228
154517921
15:45:23,156 INFO  [PortletAutoDeployListener:88] Portlets for C:\Documents and
Settings\Jett\liferay\deploy\alfsample.war copied successfully
Dec 28, 2008 3:45:23 PM org.apache.catalina.startup.HostConfig checkResources
INFO: Undeploying context [/alfsample]
15:45:23,781 INFO  [PortletHotDeployListener:314] Unregistering portlets for alf
sample
15:45:23,781 INFO  [PortletHotDeployListener:342] 1 portlets for alfsample unreg
istered successfully
15:45:25,359 INFO  [PortletHotDeployListener:202] Registering portlets for alfsa
mple
15:45:25,375 INFO  [PortletHotDeployListener:209] 1 portlets for alfsample are r
eady for registration
15:45:25,375 ERROR [PortletHotDeployListener:534] java.lang.NullPointerException

java.lang.NullPointerException
        at org.alfresco.web.scripts.portlet.WebScriptPortlet.init(WebScriptPortl
et.java:86)
        at com.liferay.portlet.InvokerPortletImpl.init(InvokerPortletImpl.java:2
50)
        at com.liferay.portlet.PortletInstanceFactory._init(PortletInstanceFacto
ry.java:253)
        at com.liferay.portlet.PortletInstanceFactory._create(PortletInstanceFac
tory.java:123)
        at com.liferay.portlet.PortletInstanceFactory.create(PortletInstanceFact
ory.java:56)
        at com.liferay.portal.deploy.hot.PortletHotDeployListener.initPortlet(Po
rtletHotDeployListener.java:531)
        at com.liferay.portal.deploy.hot.PortletHotDeployListener.doInvokeDeploy
(PortletHotDeployListener.java:230)
        at com.liferay.portal.deploy.hot.PortletHotDeployListener.invokeDeploy(P
ortletHotDeployListener.java:114)
        at com.liferay.portal.kernel.deploy.hot.HotDeployUtil._fireDeployEvent(H
otDeployUtil.java:84)
        at com.liferay.portal.kernel.deploy.hot.HotDeployUtil.fireDeployEvent(Ho
tDeployUtil.java:41)
        at com.liferay.portal.kernel.servlet.PortletContextListener.portalInit(P
ortletContextListener.java:92)
        at com.liferay.portal.kernel.util.PortalInitableUtil.init(PortalInitable
Util.java:48)
        at com.liferay.portal.kernel.servlet.PortletContextListener.contextIniti
alized(PortletContextListener.java:88)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContex
t.java:3764)
        at org.apache.catalina.core.StandardContext.start(StandardContext.java:4
216)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase
.java:760)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:74
0)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:544)

        at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.jav
a:926)
        at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.j
ava:889)
        at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492
)
        at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1217)
        at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java
:293)
        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(Lifecycl
eSupport.java:120)
        at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBas
e.java:1306)
        at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.p
rocessChildren(ContainerBase.java:1570)
        at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.p
rocessChildren(ContainerBase.java:1579)
        at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.r
un(ContainerBase.java:1559)
        at java.lang.Thread.run(Thread.java:619)
15:45:25,390 INFO  [PortletHotDeployListener:285] 1 portlets for alfsample regis
tered successfully

My development environment is as follows :

1 Alfresco 3 running on Tomcat 5.5 port 8080
1 Liferay 5.x running on Tomcat 5.5 port 8090

My Liferay WAR configuration files follows

portlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
             version="1.0">

    <portlet>
        <description>A Portlet</description>
        <portlet-name>Alfresco Portlet</portlet-name>
        <portlet-class>org.alfresco.web.scripts.portlet.WebScriptPortlet</portlet-class>

        <init-param>
            <param-name>authenticator</param-name>
            <param-value>webscripts.authenticator.jsr168.webclient</param-value>
        </init-param>
        <init-param>
            <name>http://localhost:8080</name>
            <value>/alfresco/service/sample/avm/stores</value>
        </init-param>

        <supports>
            <mime-type>text/html</mime-type>
            <portlet-mode>VIEW</portlet-mode>
        </supports>

        <portlet-info>
            <title>Portlet Title</title>
            <short-title>Portlet Short Title</short-title>
        </portlet-info>
    </portlet>


</portlet-app>

liferay-portlet.xml
<?xml version="1.0"?>
<!DOCTYPE liferay-portlet-app PUBLIC "-//Liferay//DTD Portlet Application 4.4.0//EN" "http://www.liferay.com/dtd/liferay-portlet-app_4_4_0.dtd">

<liferay-portlet-app>
    <portlet>
        <portlet-name>Alfresco Portlet</portlet-name>
        <instanceable>true</instanceable>
    </portlet>
    <role-mapper>
        <role-name>administrator</role-name>
        <role-link>Administrator</role-link>
    </role-mapper>
    <role-mapper>
        <role-name>guest</role-name>
        <role-link>Guest</role-link>
    </role-mapper>
    <role-mapper>
        <role-name>power-user</role-name>
        <role-link>Power User</role-link>
    </role-mapper>
    <role-mapper>
        <role-name>user</role-name>
        <role-link>User</role-link>
    </role-mapper>
</liferay-portlet-app>

liferay-plugin-package.properties
name=Alfresco Portlet
module-group-id=ipc
module-incremental-version=1
tags=validation
short-description=This portlet shows how to create JSP Validation portlet in Liferya.
change-log=Adapted to the latest version of Liferay.
page-url=http://www.liferay.com/web/guest/downloads
author=Liferay, Inc.
licenses=MIT

Anybody out there who has successfully "called" Alfresco web scripts from within a Liferay portlet? (I am not using the Alfresco Portlet because I need custom functionality)
10 REPLIES 10

andrepra
Champ in-the-making
Champ in-the-making
I want to do the same thing. Can you tell me, please, where I can find the jar containing the WebScriptPortlet?

thanks
Andrea

zstinah
Champ in-the-making
Champ in-the-making
alfresco-webscript-framework.jar
in \root\projects\webscript-framework\build\dist
in the alfresco source http://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/HEAD

jett
Champ in-the-making
Champ in-the-making
While searching for the a solution to this issue, I found an old (2007) presentation regarding integrating Liferay and Alfresco. Sent an email to the author of the presentation (Luis Sala from Alfresco) and got a response. I am sharing his response so the rest of us can benefit.

The presentation is outdated, not to mention that it doesn't include any code. Finally, I strongly discourage deploying Alfresco in its entirety into the portal. It was a mistake for our engineers to make that possible in the first place.

The best approach is where you develop a standalone portlet that invokes a Web Script on a remote Alfresco server.

I recently edited this article, which I think will help provide some hints and tips:
http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/Alfresco+integration

Finally, I've attached two quick and dirty sample portlets that some friends drew up to demonstrate the use of the new CMIS API which are implemented within Alfresco as Web Scripts… One of them uses a straight XML parse the ATOM responses while the other uses the Abdera library.

There seems to be no way of attaching files in this forum so I am copying and pasting both sample portlet code.

the first one:

package training;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.PortletSecurityException;
import javax.portlet.PortletSession;
import javax.portlet.PortletURL;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class AlfrescoTrainingPortlet extends GenericPortlet {

   @Override
   protected void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {
      response.setContentType("text/html");
      
      HttpClient client = new HttpClient();
      client.getParams().setAuthenticationPreemptive(true);
      Credentials defaultcreds = new UsernamePasswordCredentials("admin", "admin");
      client.getState().setCredentials(AuthScope.ANY, defaultcreds);
      String url;
      
      String objectIdParam = (String) request.getPortletSession().getAttribute("objectId", PortletSession.PORTLET_SCOPE);
      if (objectIdParam == null) {
         url = "http://192.168.13.42:8080/alfresco/s/api/path/workspace/SpacesStore/Company%20Home/children";
      } else {
         url = "http://192.168.13.42:8080/alfresco/s/api/node/workspace/SpacesStore/" + objectIdParam + "/children";
      }
      
      GetMethod method = new GetMethod(url);
      client.executeMethod(method);
      
      PortletURL actionURL = response.createActionURL();
      
      PrintWriter writer = response.getWriter();
      try {
         Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(method.getResponseBodyAsStream());
         NodeList list = dom.getElementsByTagName("cmis:propertyId");
         int len = list.getLength();
         
         for (int i = 0; i < len; i++) {
            Element element = (Element) list.item(i);
            String propertyName = element.getAttribute("cmis:name");
            String objectId = null;
            if (propertyName.equals("ObjectId")) {
               objectId = element.getElementsByTagName("cmis:value").item(0).getTextContent();
               objectId = objectId.replaceAll("workspace://SpacesStore/", "");
               writer.println("<p>" + objectId);
            }
            if (objectId == null) {
               continue;
            }
            NodeList stringList = ((Element) element.getParentNode()).getElementsByTagName("cmis:propertyString");
            int stringSize = stringList.getLength();
            for (int j = 0; j < stringSize; j++) {
               Element strElem = ((Element) stringList.item(j));
               String strName = strElem.getAttribute("cmis:name");
               if (strName.equals("Name")) {
                  actionURL.setParameter("objectId", objectId);
                  writer.println("<a href='" + actionURL.toString() + "'>" + strElem.getTextContent() + "</a>");
                  break;
               }
            }
         }
      } catch (Exception exc) {
         exc.printStackTrace();
      }
      
      //response.getWriter().println(method.getResponseBodyAsString());
   }

   @Override
   public void processAction(ActionRequest request, ActionResponse response)
         throws PortletException, PortletSecurityException, IOException {
      String objectId = request.getParameter("objectId");
      if (objectId != null) {
         request.getPortletSession().setAttribute("objectId", objectId, PortletSession.PORTLET_SCOPE);
      }
   }
}


second code (using Abdera)

package alf;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.URL;

import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.UnavailableException;

import org.apache.abdera.Abdera;
import org.apache.abdera.model.Document;
import org.apache.abdera.model.Entry;
import org.apache.abdera.model.Feed;
import org.apache.abdera.parser.Parser;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;

public class AlfPort extends GenericPortlet {

   @Override
   protected void doView(RenderRequest request, RenderResponse response)
         throws PortletException, IOException, UnavailableException {
      response.setContentType("text/html");
      HttpClient client = new HttpClient();
      client.getParams().setAuthenticationPreemptive(true);
      Credentials defaultCreds = new UsernamePasswordCredentials("admin","admin");
      client.getState().setCredentials(AuthScope.ANY, defaultCreds);
      
      GetMethod method = new GetMethod("http://192.168.13.42:8080/alfresco/s/api/path/workspace/SpacesStore/Company%20Home/children");
      client.executeMethod(method);
      //response.getWriter().println(method.getResponseBodyAsString());
      PrintWriter writer = response.getWriter();
      
      Abdera abdera = new Abdera();
      Parser parser = abdera.getParser();
       
      //URL url = new URL("http://192.168.13.42:8080/alfresco/s/api/path/workspace/SpacesStore/Company%20Home/children");
      Document<Feed> doc = parser.parse(method.getResponseBodyAsStream());
      Feed feed = doc.getRoot();
      writer.println(feed.getTitle());
      System.out.println(feed.getTitle());
      for (Entry entry : feed.getEntries()) {
         writer.println("\t" + entry.getTitle());
          System.out.println("\t" + entry.getTitle());
      }
   }
}

zstinah
Champ in-the-making
Champ in-the-making
Hi Jett

in your first post  you are using the Web Script Framework in your portlet.  Right? 
Deploying a presentation web script as a portlet.

Do you (or anyone) have code samples using presentation web scripts communicating with a data webscript in Alfresco?
How they interact?

The code samples you shared use the CMIS API. 

When should I use the CMIS API and when should I use the WSF?  I am confused. Pros/cons?

I need to be able to search a remote alfresco repository for files of certain contenttype and then open/download that file if the user logged in has permission to do that.
From what I've read that should be an ideal job for the web script framework.

Regards

jett
Champ in-the-making
Champ in-the-making
In my original post, I was attempting use Alfresco Webscripts JSR-168 runtime (http://wiki.alfresco.com/wiki/3.0_Web_Scripts_Framework#JSR-168_Runtime). Based on the documentation this seemed to be the easiest to implement as one would theoretically just create a Webscript which had both the controller/business logic and view/presentation. All one had to do for the Portal part is to "declare" the portlet in the xml config files (portlet.xml, liferay-portlet.xml, liferay-plugin-package.properties)  I was however unable to get this approach to work and hence my posting of this topic.

I only needed to understand the concept in preparation for a POC we are about to create. In theory, here is what I was planning to do:

Webscript
1. create an Alfresco webscript and set the response format to either "html" or "portlet" (refer to http://wiki.alfresco.com/wiki/3.0_Web_Scripts_Framework#HTTP_Response_Formats) in the description configuration file  (.desc.xml) for the Webscript.

Portlet
From the portlet, one just needs to "call" the Webscript from the Portlet (example is in the code from Luis).

This requires portlet to authenticate with Alfresco first. There are 2 options:
    a. use HTTP basic authentication - the sample code does this exactly using httpclient.Credentials
    b. pass an alf_ticket request parameter to the URL of your webscript call (http://wiki.alfresco.com/wiki/Web_Scripts#Authenticating). If you chose this method, you would need to login first by calling Alfresco's Login REST API service (http://wiki.alfresco.com/wiki/2.1_REST_API#Login)

** In my case for SSO functionality, we will be using the user's Liferay username and password. To authenticate, I will be using a couple of methods in Liferay's PortalUtil class (com.liferay.portal.util.PortalUtil) to get the current user's login credentials.
*** I think authentication (or getting alf_ticket) needs to be done only once and it should work for subsequent calls so this may be done once user logs into Liferay.

Assuming that authentication is ok, the webscript should return an output depending on the response format set for the Webscript (html or portlet in our case). Whatever output is retrieved will be written to the portlet using writer. Assuming method is a httpclient.methods.GetMethod object, it should be as simple as:

response.getWriter().println(method.getResponseBodyAsString());


Again this is purely theoretical until I actually get to write the code. Other suggestions/thoughts are definitely welcome.

zstinah
Champ in-the-making
Champ in-the-making
Thank you for your answer.   It helps alot.

Seems we are planning similar things but everything still just in theory Smiley Happy  In theory our plans should all be a piece of pie according to the wikis!

Would be nice to know if there are people out there that have this thing actually working Smiley Happy

Regards

alovell
Champ in-the-making
Champ in-the-making
Hi folks,

Has anyone been able to make any advances on this? I've been trying to do exactly this without much success.

All the Best

Andy Lovell

rivetlogic
Champ on-the-rise
Champ on-the-rise
Hi,

You could try AWPr (http://forge.rivetlogic.com/Forge/Rivets/Alfresco-Web-script-Portlet). I'm not sure if this will satisfy your requirements but it's a possible option.

Hope this helps,

–Alaaeldin

anusk
Champ in-the-making
Champ in-the-making
Hi!
I know is an old post, but i'm trying to achieve the same and appears the same error.
java.lang.NullPointerException
at org.springframework.extensions.webscripts.portlet.WebScriptPortlet.init(WebScriptPortlet.java:80)
I am using Liferay 6 and Alfresco 3.3.
Did anyone find the solution? because I'm really stuck at this point.

Thanks in advance.
Ana
Getting started

Tags


Find what you came for

We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.