Author: julien_viet
Date: 2012-02-13 07:10:57 -0500 (Mon, 13 Feb 2012)
New Revision: 8420
Added:
portal/trunk/examples/portlets/resourceserving/
portal/trunk/examples/portlets/resourceserving/pom.xml
portal/trunk/examples/portlets/resourceserving/src/
portal/trunk/examples/portlets/resourceserving/src/main/
portal/trunk/examples/portlets/resourceserving/src/main/java/
portal/trunk/examples/portlets/resourceserving/src/main/java/org/
portal/trunk/examples/portlets/resourceserving/src/main/java/org/gatein/
portal/trunk/examples/portlets/resourceserving/src/main/java/org/gatein/portal/
portal/trunk/examples/portlets/resourceserving/src/main/java/org/gatein/portal/samples/
portal/trunk/examples/portlets/resourceserving/src/main/java/org/gatein/portal/samples/resourceserving/
portal/trunk/examples/portlets/resourceserving/src/main/java/org/gatein/portal/samples/resourceserving/ResourceServingDemoPortlet.java
portal/trunk/examples/portlets/resourceserving/src/main/webapp/
portal/trunk/examples/portlets/resourceserving/src/main/webapp/WEB-INF/
portal/trunk/examples/portlets/resourceserving/src/main/webapp/WEB-INF/portlet.xml
portal/trunk/examples/portlets/resourceserving/src/main/webapp/WEB-INF/web.xml
Modified:
portal/trunk/examples/portlets/pom.xml
portal/trunk/webui/portal/src/main/java/org/exoplatform/portal/webui/application/UIPortletActionListener.java
Log:
GTNPORTAL-2351 : Portlet resource serving does not handle status code other than 200 OK
Modified: portal/trunk/examples/portlets/pom.xml
===================================================================
--- portal/trunk/examples/portlets/pom.xml 2012-02-10 14:43:12 UTC (rev 8419)
+++ portal/trunk/examples/portlets/pom.xml 2012-02-13 12:10:57 UTC (rev 8420)
@@ -20,6 +20,7 @@
<module>jsphellouser</module>
<module>simplesthelloworld</module>
<module>struts-jpetstore</module>
+ <module>resourceserving</module>
</modules>
</project>
Property changes on: portal/trunk/examples/portlets/resourceserving
___________________________________________________________________
Added: svn:ignore
+ .idea
*.iml
target
Added: portal/trunk/examples/portlets/resourceserving/pom.xml
===================================================================
--- portal/trunk/examples/portlets/resourceserving/pom.xml (rev
0)
+++ portal/trunk/examples/portlets/resourceserving/pom.xml 2012-02-13 12:10:57 UTC (rev
8420)
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2011 eXo Platform SAS.
+ ~
+ ~ This is free software; you can redistribute it and/or modify it
+ ~ under the terms of the GNU Lesser General Public License as
+ ~ published by the Free Software Foundation; either version 2.1 of
+ ~ the License, or (at your option) any later version.
+ ~
+ ~ This software is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ ~ Lesser General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public
+ ~ License along with this software; if not, write to the Free
+ ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ ~ 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ -->
+
+<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <!--
+ the parent isn't required, you can drop it if you add a groupId
+ and version
+ -->
+ <parent>
+ <groupId>org.gatein.portal.examples.portlets</groupId>
+ <artifactId>parent</artifactId>
+ <version>3.2.0-CR02-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>resource-serving</artifactId>
+ <packaging>war</packaging>
+ <name>GateIn Portal Examples - Resource Serving Portlet</name>
+ <description />
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.portlet</groupId>
+ <artifactId>portlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
Added:
portal/trunk/examples/portlets/resourceserving/src/main/java/org/gatein/portal/samples/resourceserving/ResourceServingDemoPortlet.java
===================================================================
---
portal/trunk/examples/portlets/resourceserving/src/main/java/org/gatein/portal/samples/resourceserving/ResourceServingDemoPortlet.java
(rev 0)
+++
portal/trunk/examples/portlets/resourceserving/src/main/java/org/gatein/portal/samples/resourceserving/ResourceServingDemoPortlet.java 2012-02-13
12:10:57 UTC (rev 8420)
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+package org.gatein.portal.samples.resourceserving;
+
+import javax.portlet.GenericPortlet;
+import javax.portlet.PortletException;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.portlet.ResourceURL;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ */
+public class ResourceServingDemoPortlet extends GenericPortlet
+{
+
+ /** . */
+ private static final String HTML = "html", EXCEPTION =
"exception", NOT_FOUND = "404", NO_OP = "noop";
+
+ /** . */
+ private static String[] msg = {"HTML", "Exception", "Not
Found", "No op"};
+
+ /** . */
+ private static String[] behaviors = {HTML, EXCEPTION, NOT_FOUND, NO_OP};
+
+ @Override
+ protected void doView(RenderRequest request, RenderResponse response) throws
PortletException, IOException
+ {
+ ResourceURL url = response.createResourceURL();
+ response.setContentType("text/html");
+ PrintWriter writer = response.getWriter();
+ writer.print("<p>This portlet shows how a resource serving portlet can
modify the response</p>");
+ writer.print("<ul>");
+ for (int i = 0;i < msg.length;i++)
+ {
+ url.setParameter("behavior", behaviors[i]);
+ writer.print("<li><a href='" + url +
"'>" + msg[i] + "</a></li>");
+ }
+ writer.print("</ul>");
+ }
+
+ @Override
+ public void serveResource(ResourceRequest request, ResourceResponse response) throws
PortletException, IOException
+ {
+ String behavior = request.getParameter("behavior");
+ if (HTML.equals(behavior))
+ {
+ response.setContentType("text/html");
+ PrintWriter writer = response.getWriter();
+ writer.print("<html><body>Hello
World</body><html>");
+ }
+ else if (EXCEPTION.equals(behavior))
+ {
+ throw new PortletException("Don't freak out");
+ }
+ else if (NOT_FOUND.equals(behavior))
+ {
+ response.setProperty(ResourceResponse.HTTP_STATUS_CODE, "404");
+ PrintWriter writer = response.getWriter();
+ writer.print("<html><body>Not
Found</body><html>");
+ }
+ else
+ {
+ // Do nothing
+ }
+ }
+}
Added: portal/trunk/examples/portlets/resourceserving/src/main/webapp/WEB-INF/portlet.xml
===================================================================
--- portal/trunk/examples/portlets/resourceserving/src/main/webapp/WEB-INF/portlet.xml
(rev 0)
+++
portal/trunk/examples/portlets/resourceserving/src/main/webapp/WEB-INF/portlet.xml 2012-02-13
12:10:57 UTC (rev 8420)
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2011 eXo Platform SAS.
+ ~
+ ~ This is free software; you can redistribute it and/or modify it
+ ~ under the terms of the GNU Lesser General Public License as
+ ~ published by the Free Software Foundation; either version 2.1 of
+ ~ the License, or (at your option) any later version.
+ ~
+ ~ This software is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ ~ Lesser General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public
+ ~ License along with this software; if not, write to the Free
+ ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ ~ 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ -->
+
+<portlet-app
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
+version="2.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2...
+
http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
+ <portlet>
+ <description xml:lang="EN">A portlet that demonstrate resource
serving basics</description>
+ <portlet-name>ResourceServingDemoPortlet</portlet-name>
+ <display-name xml:lang="EN">Resource Serving
Demo</display-name>
+
<portlet-class>org.gatein.portal.samples.resourceserving.ResourceServingDemoPortlet</portlet-class>
+ <supports>
+ <mime-type>text/html</mime-type>
+ </supports>
+ <portlet-info>
+ <title>Resource Serving Demo Portlet</title>
+ <keywords>Sample</keywords>
+ </portlet-info>
+ </portlet>
+</portlet-app>
\ No newline at end of file
Added: portal/trunk/examples/portlets/resourceserving/src/main/webapp/WEB-INF/web.xml
===================================================================
--- portal/trunk/examples/portlets/resourceserving/src/main/webapp/WEB-INF/web.xml
(rev 0)
+++
portal/trunk/examples/portlets/resourceserving/src/main/webapp/WEB-INF/web.xml 2012-02-13
12:10:57 UTC (rev 8420)
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+ ~ Copyright (C) 2011 eXo Platform SAS.
+ ~
+ ~ This is free software; you can redistribute it and/or modify it
+ ~ under the terms of the GNU Lesser General Public License as
+ ~ published by the Free Software Foundation; either version 2.1 of
+ ~ the License, or (at your option) any later version.
+ ~
+ ~ This software is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ ~ Lesser General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public
+ ~ License along with this software; if not, write to the Free
+ ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ ~ 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ -->
+
+<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+ version="2.5">
+</web-app>
Modified:
portal/trunk/webui/portal/src/main/java/org/exoplatform/portal/webui/application/UIPortletActionListener.java
===================================================================
---
portal/trunk/webui/portal/src/main/java/org/exoplatform/portal/webui/application/UIPortletActionListener.java 2012-02-10
14:43:12 UTC (rev 8419)
+++
portal/trunk/webui/portal/src/main/java/org/exoplatform/portal/webui/application/UIPortletActionListener.java 2012-02-13
12:10:57 UTC (rev 8420)
@@ -33,11 +33,13 @@
import java.util.Map;
import javax.portlet.PortletMode;
+import javax.portlet.ResourceResponse;
import javax.portlet.WindowState;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.namespace.QName;
+import org.exoplatform.commons.utils.Safe;
import org.exoplatform.portal.Constants;
import org.exoplatform.portal.application.PortalRequestContext;
import org.exoplatform.portal.webui.page.UIPage;
@@ -68,6 +70,7 @@
import org.gatein.pc.api.invocation.response.ErrorResponse;
import org.gatein.pc.api.invocation.response.HTTPRedirectionResponse;
import org.gatein.pc.api.invocation.response.PortletInvocationResponse;
+import org.gatein.pc.api.invocation.response.ResponseProperties;
import org.gatein.pc.api.invocation.response.SecurityErrorResponse;
import org.gatein.pc.api.invocation.response.SecurityResponse;
import org.gatein.pc.api.invocation.response.UpdateNavigationalStateResponse;
@@ -365,11 +368,13 @@
log.trace("Serve Resource for portlet: " +
uiPortlet.getPortletContext());
String resourceId = null;
+ //
+ PortalRequestContext context = (PortalRequestContext)event.getRequestContext();
+ HttpServletResponse response = context.getResponse();
+
+ //
try
{
- PortalRequestContext context =
(PortalRequestContext)event.getRequestContext();
- HttpServletResponse response = context.getResponse();
-
//Set the NavigationalState
String navState =
context.getRequestParameter(ExoPortletInvocationContext.NAVIGATIONAL_STATE_PARAM_NAME);
if (navState != null)
@@ -386,90 +391,120 @@
//
PortletInvocationResponse portletResponse =
uiPortlet.invoke(resourceInvocation);
- // todo: handle the error response better than this.
+ //
+ int statusCode;
+ MultiValuedPropertyMap<String> transportHeaders;
+ String contentType;
+ Object content;
if (!(portletResponse instanceof ContentResponse))
{
if (portletResponse instanceof ErrorResponse)
{
ErrorResponse errorResponse = (ErrorResponse)portletResponse;
- if (errorResponse.getCause() != null)
+ Throwable cause = errorResponse.getCause();
+ if (cause != null)
{
- throw (Exception)errorResponse.getCause();
+ log.trace("Got error response from portlet", cause);
}
else if (errorResponse.getMessage() != null)
{
- throw new Exception("Received an error response with message :
" + errorResponse.getMessage());
+ log.trace("Got error response from portlet:" +
errorResponse.getMessage());
}
else
{
- throw new Exception("Received an error response.");
+ log.trace("Got error response from portlet");
}
-
}
else
{
- throw new Exception("Unexpected response type [" +
portletResponse
- + "]. Expected a ContentResponse or an ErrorResponse.");
+ log.trace("Unexpected response type [" + portletResponse +
"]. Expected a ContentResponse or an ErrorResponse.");
}
+ statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
+ contentType = null;
+ transportHeaders = null;
+ content = null;
}
-
- ContentResponse piResponse = (ContentResponse)portletResponse;
-
- //
- //Manage headers
- if (piResponse.getProperties() != null &&
piResponse.getProperties().getTransportHeaders() != null)
+ else
{
- MultiValuedPropertyMap<String> transportHeaders =
piResponse.getProperties().getTransportHeaders();
- Map<String, String> headers = new HashMap<String, String>();
+ //
+ ContentResponse piResponse = (ContentResponse)portletResponse;
+ ResponseProperties properties = piResponse.getProperties();
+ transportHeaders = properties != null ? properties.getTransportHeaders() :
null;
- for (String key : transportHeaders.keySet())
+ // Look at status code if there is one and honour it
+ String status = transportHeaders != null ?
transportHeaders.getValue(ResourceResponse.HTTP_STATUS_CODE) : null;
+ if (status != null)
{
- for (String value : transportHeaders.getValues(key))
+ try
{
- headers.put(key, value);
+ statusCode = Integer.parseInt(status);
}
+ catch (NumberFormatException e)
+ {
+ statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
+ }
}
- context.setHeaders(headers);
+ else
+ {
+ statusCode = HttpServletResponse.SC_OK;
+ }
+
+ //
+ contentType = piResponse.getContentType();
+
+ //
+ log.trace("Try to get a resource of type: " + contentType +
" for the portlet: " + uiPortlet.getPortletContext());
+ if (piResponse.getChars() != null)
+ {
+ content = piResponse.getChars();
+ }
+ else if (piResponse.getBytes() != null)
+ {
+ content = piResponse.getBytes();
+ }
+ else
+ {
+ content = null;
+ }
}
- String contentType = piResponse.getContentType();
+ //
+ response.setStatus(statusCode);
- if (contentType == null)
+ // Set content type if any
+ if (contentType != null)
{
- return;
+ response.setContentType(contentType);
}
- log.trace("Try to get a resource of type: " + contentType + "
for the portlet: "
- + uiPortlet.getPortletContext());
- response.setContentType(contentType);
- if (piResponse.getChars() != null)
+ // Send headers if any
+ if (transportHeaders != null)
{
- OutputStream stream = response.getOutputStream();
-
stream.write(piResponse.getChars().getBytes(response.getCharacterEncoding()));
+ sendHeaders(transportHeaders, context);
}
- else
+
+ // Send body if any
+ if (content instanceof String)
{
- if (piResponse.getBytes() != null)
+ context.getWriter().write((String)content);
+ }
+ else if (content instanceof byte[])
+ {
+ byte[] bytes = (byte[]) content;
+ response.setContentLength(bytes.length);
+ OutputStream stream = response.getOutputStream();
+ try
{
- OutputStream stream = response.getOutputStream();
- stream.write(piResponse.getBytes());
+ stream.write(bytes);
}
- else
+ finally
{
- if (piResponse.getChars() != null)
- {
- log.error("Received a content type of " + contentType +
" but it contains no bytes of data. Chars were unexpectantly returned instead :
" + piResponse.getChars());
- }
- else
- {
- log.error("Received a content type of " + contentType +
" but it contains no bytes of data.");
- }
+ Safe.close(stream);
}
-
-
}
- context.getResponse().flushBuffer();
+ //
+ response.flushBuffer();
}
catch (Exception e)
{
@@ -483,6 +518,29 @@
event.getRequestContext().setResponseComplete(true);
}
}
+
+ /**
+ * Send any header to the client
+ *
+ * @param headers the headers
+ * @param context the context
+ * @throws IOException any io exception
+ */
+ private void sendHeaders(MultiValuedPropertyMap<String> headers,
PortalRequestContext context) throws IOException
+ {
+ Map<String, String> map = new HashMap<String, String>();
+ for (String key : headers.keySet())
+ {
+ for (String value : headers.getValues(key))
+ {
+ map.put(key, value);
+ }
+ }
+
+ // We need to remove it if it there
+ map.remove(ResourceResponse.HTTP_STATUS_CODE);
+ context.setHeaders(map);
+ }
}
/**