Author: chris.laprun(a)jboss.com
Date: 2010-03-30 20:58:27 -0400 (Tue, 30 Mar 2010)
New Revision: 2403
Added:
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/ResourceHandler.java
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/handler/CookieUtil.java
Modified:
components/wsrp/trunk/common/src/main/java/org/gatein/wsrp/WSRPResourceURL.java
components/wsrp/trunk/common/src/main/java/org/gatein/wsrp/WSRPTypeFactory.java
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/InvocationHandler.java
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/MarkupProcessor.java
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/RenderHandler.java
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/RequestPrecursor.java
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/SessionHandler.java
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/WSRPConsumerImpl.java
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/handler/RequestHeaderClientHandler.java
components/wsrp/trunk/consumer/src/test/java/org/gatein/wsrp/consumer/RenderHandlerTestCase.java
Log:
- GTNWSRP-7:
+ WSRPConsumerImpl is now able to handle ResourceInvocations via ResourceHandler when
resource URLs used to be rewritten to absolute URLs. This should
improve resource support and allow for consumer proxying. Still needs to be tested
more.
+ Rewrote MarkupProcessor.getReplacementFor method to generate resource URLs (note that
they are not quite correct as we need to bridge WSRP 1 and JSR-286.
+ Improved WSRP templates to generate "real" resource URLs instead of fake
ones.
- GTNWSRP-12: Temporarily remove timeout parameter when it's present in the markup in
encoded URLs.
- Extracted cookie handling code from RequestHeaderClientHandler so that it can be reused
in ResourceHandler.
- Added more guards around debugging statements.
Modified: components/wsrp/trunk/common/src/main/java/org/gatein/wsrp/WSRPResourceURL.java
===================================================================
---
components/wsrp/trunk/common/src/main/java/org/gatein/wsrp/WSRPResourceURL.java 2010-03-30
21:32:46 UTC (rev 2402)
+++
components/wsrp/trunk/common/src/main/java/org/gatein/wsrp/WSRPResourceURL.java 2010-03-31
00:58:27 UTC (rev 2403)
@@ -203,6 +203,7 @@
*
* @param request
* @param portletContext
+ * @deprecated should be removed when WSRP 2 is implemented
*/
public void buildURLWith(HttpServletRequest request, PortletContext portletContext)
{
Modified: components/wsrp/trunk/common/src/main/java/org/gatein/wsrp/WSRPTypeFactory.java
===================================================================
---
components/wsrp/trunk/common/src/main/java/org/gatein/wsrp/WSRPTypeFactory.java 2010-03-30
21:32:46 UTC (rev 2402)
+++
components/wsrp/trunk/common/src/main/java/org/gatein/wsrp/WSRPTypeFactory.java 2010-03-31
00:58:27 UTC (rev 2403)
@@ -26,15 +26,17 @@
import org.gatein.common.text.TextTools;
import org.gatein.common.util.ParameterValidation;
import org.gatein.pc.api.ActionURL;
+import org.gatein.pc.api.ContainerURL;
import org.gatein.pc.api.Mode;
import org.gatein.pc.api.OpaqueStateString;
import org.gatein.pc.api.PortletStateType;
-import org.gatein.pc.api.PortletURL;
import org.gatein.pc.api.RenderURL;
+import org.gatein.pc.api.ResourceURL;
import org.gatein.pc.api.StateString;
import org.gatein.pc.api.StatefulPortletContext;
import org.gatein.pc.api.URLFormat;
import org.gatein.pc.api.WindowState;
+import org.gatein.pc.api.cache.CacheLevel;
import org.gatein.pc.api.spi.PortletInvocationContext;
import org.oasis.wsrp.v1.BlockingInteractionResponse;
import org.oasis.wsrp.v1.CacheControl;
@@ -83,6 +85,8 @@
import java.util.List;
import java.util.Map;
+import static org.gatein.wsrp.WSRPRewritingConstants.*;
+
/**
* Creates minimally valid instances of WSRP types, populated with default values where
possible, as per
* wsrp_v1_types.xsd. See <a
href="http://jira.jboss.com/jira/browse/JBPORTAL-808">JBPORT...
for more
@@ -646,22 +650,22 @@
{
public StateString getInteractionState()
{
- return new OpaqueStateString(WSRPRewritingConstants.REWRITE_PARAMETER_OPEN +
WSRPRewritingConstants.INTERACTION_STATE +
WSRPRewritingConstants.REWRITE_PARAMETER_CLOSE);
+ return new OpaqueStateString(REWRITE_PARAMETER_OPEN + INTERACTION_STATE +
REWRITE_PARAMETER_CLOSE);
}
public StateString getNavigationalState()
{
- return new OpaqueStateString(WSRPRewritingConstants.REWRITE_PARAMETER_OPEN +
WSRPRewritingConstants.NAVIGATIONAL_STATE +
WSRPRewritingConstants.REWRITE_PARAMETER_CLOSE);
+ return getTemplateNS();
}
public Mode getMode()
{
- return Mode.create(WSRPRewritingConstants.REWRITE_PARAMETER_OPEN +
WSRPRewritingConstants.MODE + WSRPRewritingConstants.REWRITE_PARAMETER_CLOSE, true);
+ return getTemplateMode();
}
public WindowState getWindowState()
{
- return WindowState.create(WSRPRewritingConstants.REWRITE_PARAMETER_OPEN +
WSRPRewritingConstants.WINDOW_STATE + WSRPRewritingConstants.REWRITE_PARAMETER_CLOSE,
true);
+ return getTemplateWindowState();
}
};
@@ -669,7 +673,7 @@
{
public StateString getNavigationalState()
{
- return new OpaqueStateString(WSRPRewritingConstants.REWRITE_PARAMETER_OPEN +
WSRPRewritingConstants.NAVIGATIONAL_STATE +
WSRPRewritingConstants.REWRITE_PARAMETER_CLOSE);
+ return getTemplateNS();
}
public Map<String, String[]> getPublicNavigationalStateChanges()
@@ -680,15 +684,66 @@
public Mode getMode()
{
- return Mode.create(WSRPRewritingConstants.REWRITE_PARAMETER_OPEN +
WSRPRewritingConstants.MODE + WSRPRewritingConstants.REWRITE_PARAMETER_CLOSE, true);
+ return getTemplateMode();
}
public WindowState getWindowState()
{
- return WindowState.create(WSRPRewritingConstants.REWRITE_PARAMETER_OPEN +
WSRPRewritingConstants.WINDOW_STATE + WSRPRewritingConstants.REWRITE_PARAMETER_CLOSE,
true);
+ return getTemplateWindowState();
}
};
+ private static ResourceURL RESOURCE_URL = new WSRPResourceURL()
+ {
+ public String getResourceId()
+ {
+ return REWRITE_PARAMETER_OPEN + WSRPRewritingConstants.RESOURCE_URL +
REWRITE_PARAMETER_CLOSE;
+ }
+
+ public StateString getResourceState()
+ {
+ // todo: fix-me
+ return null;
+ }
+
+ public CacheLevel getCacheability()
+ {
+ // todo: fix-me
+ return null;
+ }
+
+ public Mode getMode()
+ {
+ return getTemplateMode();
+ }
+
+ public WindowState getWindowState()
+ {
+ return getTemplateWindowState();
+ }
+
+ public StateString getNavigationalState()
+ {
+ return getTemplateNS();
+ }
+ };
+
+ private static StateString getTemplateNS()
+ {
+ return new OpaqueStateString(REWRITE_PARAMETER_OPEN + NAVIGATIONAL_STATE +
REWRITE_PARAMETER_CLOSE);
+ }
+
+ private static WindowState getTemplateWindowState()
+ {
+ return WindowState.create(REWRITE_PARAMETER_OPEN + WINDOW_STATE +
REWRITE_PARAMETER_CLOSE, true);
+ }
+
+ private static Mode getTemplateMode()
+ {
+ return Mode.create(REWRITE_PARAMETER_OPEN + MODE + REWRITE_PARAMETER_CLOSE, true);
+ }
+
+
/**
* defaultTemplate(xsd:string)?, blockingActionTemplate(xsd:string)?,
renderTemplate(xsd:string)?,
* resourceTemplate(xsd:string)?, secureDefaultTemplate(xsd:string)?,
secureBlockingActionTemplate(xsd:string)?,
@@ -707,13 +762,13 @@
templates.setSecureRenderTemplate(createTemplate(context, RENDER_URL,
Boolean.TRUE));
//fix-me: deal with resources properly, create fake ones for now
- templates.setResourceTemplate(WSRPRewritingConstants.FAKE_RESOURCE_URL);
- templates.setSecureResourceTemplate(WSRPRewritingConstants.FAKE_RESOURCE_URL);
+ templates.setResourceTemplate(createTemplate(context, RESOURCE_URL, false));
+ templates.setSecureResourceTemplate(createTemplate(context, RESOURCE_URL, true));
return templates;
}
- private static String createTemplate(PortletInvocationContext context, PortletURL url,
Boolean secure)
+ private static String createTemplate(PortletInvocationContext context, ContainerURL
url, Boolean secure)
{
String template = context.renderURL(url, new URLFormat(secure, null, null, true));
template = TextTools.replace(template, WSRPRewritingConstants.ENC_OPEN,
WSRPRewritingConstants.REWRITE_PARAMETER_OPEN);
Modified:
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/InvocationHandler.java
===================================================================
---
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/InvocationHandler.java 2010-03-30
21:32:46 UTC (rev 2402)
+++
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/InvocationHandler.java 2010-03-31
00:58:27 UTC (rev 2403)
@@ -93,21 +93,27 @@
// as long as we don't get a non-null response and we're allowed to try
again, try to perform the request
while (response == null && retryCount++ <= MAXIMUM_RETRY_NUMBER)
{
- log.debug("performRequest: " + retryCount + " attempt(s) out of
" + MAXIMUM_RETRY_NUMBER + " possible");
+ if (log.isDebugEnabled())
+ {
+ log.debug("performRequest: " + retryCount + " attempt(s) out
of " + MAXIMUM_RETRY_NUMBER + " possible");
+ }
SessionHandler sessionHandler = consumer.getSessionHandler();
// prepare everything for the request
updateRegistrationContext(request);
RuntimeContext runtimeContext = getRuntimeContextFrom(request);
- WindowContext windowContext = invocation.getWindowContext();
- runtimeContext.setNamespacePrefix(getNamespaceFrom(windowContext));
+ if (runtimeContext != null)
+ {
+ WindowContext windowContext = invocation.getWindowContext();
+ runtimeContext.setNamespacePrefix(getNamespaceFrom(windowContext));
- InstanceContext instanceContext = invocation.getInstanceContext();
- runtimeContext.setPortletInstanceKey(instanceContext == null ? null :
instanceContext.getId());
+ InstanceContext instanceContext = invocation.getInstanceContext();
+ runtimeContext.setPortletInstanceKey(instanceContext == null ? null :
instanceContext.getId());
- updateUserContext(request, consumer.getUserContextFrom(invocation,
runtimeContext));
- consumer.setTemplatesIfNeeded(invocation, runtimeContext);
+ updateUserContext(request, consumer.getUserContextFrom(invocation,
runtimeContext));
+ consumer.setTemplatesIfNeeded(invocation, runtimeContext);
+ }
try
{
@@ -142,7 +148,10 @@
"properly transmitted. Look at server.log for clues as to what
happened..."));
}
- log.debug("performRequest finished. Response is " + (response != null ?
response.getClass().getName() : null));
+ if (log.isDebugEnabled())
+ {
+ log.debug("performRequest finished. Response is " + (response != null
? response.getClass().getName() : null));
+ }
return response;
}
Modified:
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/MarkupProcessor.java
===================================================================
---
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/MarkupProcessor.java 2010-03-30
21:32:46 UTC (rev 2402)
+++
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/MarkupProcessor.java 2010-03-31
00:58:27 UTC (rev 2403)
@@ -61,26 +61,8 @@
public String getReplacementFor(String match, String prefix, String suffix)
{
- if (match.startsWith(WSRPRewritingConstants.RESOURCE_URL_DELIMITER))
+ if (prefix.equals(match))
{
- // we have a resource URL coming from a template so extract URL
- int index = match.lastIndexOf(WSRPRewritingConstants.RESOURCE_URL_DELIMITER);
-
-/*
- // todo: right now, no need to extract value of require rewrite..
- String requireRewriteStr = match.substring(index + URL_DELIMITER_LENGTH);
- boolean requireRewrite = Boolean.valueOf(requireRewriteStr);
- if (requireRewrite)
- {
- // FIX-ME: do something
- log.debug("Required re-writing but this is not yet
implemented...");
- }*/
-
- match = match.substring(URL_DELIMITER_LENGTH, index);
- return URLTools.decodeXWWWFormURL(match);
- }
- else if (prefix.equals(match))
- {
return namespace;
}
else if (match.startsWith(WSRPRewritingConstants.BEGIN_WSRP_REWRITE_END))
@@ -92,45 +74,11 @@
if (portletURL instanceof WSRPResourceURL)
{
WSRPResourceURL resource = (WSRPResourceURL)portletURL;
- String replacement = getResourceURL(match, resource);
- // if the URL starts with /, prepend the remote host address and the portlet
application name so that we
- // can attempt to create a remotely available URL
- if (replacement.startsWith(URLTools.SLASH))
- {
- replacement = WSRPResourceURL.createAbsoluteURLFrom(replacement,
serverAddress, portletApplicationName);
- }
-
- return replacement;
-
-/*
- todo: use this code to reactivate primitive use of resources
- // get the parsed URL and add marker to it so that the consumer can know
it needs to be intercepted
- URL url = resource.getResourceURL();
- String query = url.getQuery();
- if (ParameterValidation.isNullOrEmpty(query))
- {
- query = WSRPRewritingConstants.GTNRESOURCE;
- }
- else
- {
- query = "+" + WSRPRewritingConstants.GTNRESOURCE;
- }
-
- try
- {
- URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(),
url.getPort(),
- url.getPath(), query, url.getRef());
-
- // set the resulting URI as the new resource ID, must be encoded as it
will be used in URLs
- String s = URLTools.encodeXWWWFormURL(uri.toString());
- resource.setResourceId(s);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("Cannot parse specified
Resource as a URI: " + url);
- }*/
-
+ // bridge the WSRP 1 resources with JSR-286-style
+ // set the URL as the new resource ID, must be encoded as it will be used in
URLs
+ String s =
URLTools.encodeXWWWFormURL(resource.getResourceURL().toExternalForm());
+ resource.setResourceId(s);
}
return context.renderURL(portletURL, format);
Modified:
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/RenderHandler.java
===================================================================
---
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/RenderHandler.java 2010-03-30
21:32:46 UTC (rev 2402)
+++
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/RenderHandler.java 2010-03-31
00:58:27 UTC (rev 2403)
@@ -189,6 +189,9 @@
{
// fix-me: how to deal with fragment header? => interceptor?
+ // todo: remove, this is a work-around for GTNWSRP-12
+ markup = markup.replaceFirst("%3ftimeout%3d.*%2f", "%2f");
+
markup = MarkupProcessor.replaceBoundedString(
markup,
WSRPRewritingConstants.WSRP_REWRITE,
Modified:
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/RequestPrecursor.java
===================================================================
---
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/RequestPrecursor.java 2010-03-30
21:32:46 UTC (rev 2402)
+++
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/RequestPrecursor.java 2010-03-31
00:58:27 UTC (rev 2403)
@@ -1,6 +1,6 @@
/*
* JBoss, a division of Red Hat
- * Copyright 2009, Red Hat Middleware, LLC, and individual
+ * Copyright 2010, Red Hat Middleware, LLC, and individual
* contributors as indicated by the @authors tag. See the
* copyright.txt in the distribution for a full listing of
* individual contributors.
@@ -68,7 +68,10 @@
// retrieve handle
portletContext =
WSRPUtils.convertToWSRPPortletContext(WSRPConsumerImpl.getPortletContext(invocation));
ParameterValidation.throwIllegalArgExceptionIfNullOrEmpty(getPortletHandle(),
PORTLET_HANDLE, null);
- log.debug("About to invoke on portlet: " + getPortletHandle());
+ if (log.isDebugEnabled())
+ {
+ log.debug("About to invoke on portlet: " + getPortletHandle());
+ }
// create runtime context
SecurityContext securityContext = invocation.getSecurityContext();
@@ -126,7 +129,10 @@
}
}
- log.debug(WSRPUtils.toString(markupParams));
+ if (log.isDebugEnabled())
+ {
+ log.debug(WSRPUtils.toString(markupParams));
+ }
}
public String getPortletHandle()
Added:
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/ResourceHandler.java
===================================================================
---
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/ResourceHandler.java
(rev 0)
+++
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/ResourceHandler.java 2010-03-31
00:58:27 UTC (rev 2403)
@@ -0,0 +1,173 @@
+/*
+ * JBoss, a division of Red Hat
+ * Copyright 2010, Red Hat Middleware, LLC, and individual
+ * contributors as indicated by the @authors tag. See the
+ * copyright.txt in the distribution for a full listing of
+ * individual contributors.
+ *
+ * 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.wsrp.consumer;
+
+import org.apache.commons.httpclient.Cookie;
+import org.gatein.common.io.IOTools;
+import org.gatein.common.net.media.MediaType;
+import org.gatein.common.net.media.TypeDef;
+import org.gatein.common.util.MultiValuedPropertyMap;
+import org.gatein.pc.api.PortletInvokerException;
+import org.gatein.pc.api.invocation.PortletInvocation;
+import org.gatein.pc.api.invocation.ResourceInvocation;
+import org.gatein.pc.api.invocation.response.ContentResponse;
+import org.gatein.pc.api.invocation.response.PortletInvocationResponse;
+import org.gatein.pc.api.invocation.response.ResponseProperties;
+import org.gatein.wsrp.handler.CookieUtil;
+import org.oasis.wsrp.v1.RuntimeContext;
+import org.oasis.wsrp.v1.UserContext;
+
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:chris.laprun@jboss.com">Chris
Laprun</a>
+ * @version $Revision$
+ */
+public class ResourceHandler extends InvocationHandler
+{
+ protected ResourceHandler(WSRPConsumerImpl consumer)
+ {
+ super(consumer);
+ }
+
+ @Override
+ protected void updateUserContext(Object request, UserContext userContext)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ @Override
+ protected void updateRegistrationContext(Object request) throws
PortletInvokerException
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ @Override
+ protected RuntimeContext getRuntimeContextFrom(Object request)
+ {
+ return null; //To change body of implemented methods use File | Settings | File
Templates.
+ }
+
+ @Override
+ protected Object performRequest(Object request) throws Exception
+ {
+ ResourceInvocation invocation = (ResourceInvocation)request;
+ String resourceId = invocation.getResourceId();
+
+ URL url = new URL(resourceId);
+ URLConnection urlConnection = url.openConnection();
+ String contentType = urlConnection.getContentType();
+
+ // init ResponseProperties for ContentResponse result
+ Map<String, List<String>> headers = urlConnection.getHeaderFields();
+ ResponseProperties props = new ResponseProperties();
+ MultiValuedPropertyMap<String> transportHeaders =
props.getTransportHeaders();
+ for (Map.Entry<String, List<String>> entry : headers.entrySet())
+ {
+ String key = entry.getKey();
+ if (key != null)
+ {
+ List<String> values = entry.getValue();
+ if (values != null)
+ {
+ if (CookieUtil.SET_COOKIE.equals(key))
+ {
+ Cookie[] cookies = CookieUtil.extractCookiesFrom(url,
values.toArray(new String[values.size()]));
+ List<javax.servlet.http.Cookie> propCookies =
props.getCookies();
+ for (Cookie cookie : cookies)
+ {
+ propCookies.add(CookieUtil.convertFrom(cookie));
+ }
+ }
+ else
+ {
+ for (String value : values)
+ {
+ transportHeaders.addValue(key, value);
+ }
+ }
+ }
+ }
+ }
+
+ int length = urlConnection.getContentLength();
+ byte[] bytes = IOTools.getBytes(urlConnection.getInputStream(), length);
+
+ ContentResponse result;
+ MediaType type = MediaType.create(contentType);
+ if (TypeDef.TEXT.equals(type.getType()))
+ {
+ // determine the charset of the content, if any
+ String charset = "UTF-8";
+ if (contentType != null)
+ {
+ for (String part : contentType.split(";"))
+ {
+ if (part.startsWith("charset="))
+ {
+ charset = part.substring("charset=".length());
+ }
+ }
+ }
+
+ // build a String-based content response
+ result = new ContentResponse(props, Collections.<String,
Object>emptyMap(), contentType, null, new String(bytes, charset), null);
+ }
+ else
+ {
+ // build a byte-based content response
+ result = new ContentResponse(props, Collections.<String,
Object>emptyMap(), contentType, bytes, null, null);
+ }
+
+ return result;
+ }
+
+ @Override
+ protected Object prepareRequest(RequestPrecursor requestPrecursor, PortletInvocation
invocation)
+ {
+ if (!(invocation instanceof ResourceInvocation))
+ {
+ throw new IllegalArgumentException("ResourceHandler can only handle
ResourceInvocations!");
+ }
+
+ return invocation;
+ }
+
+ @Override
+ protected PortletInvocationResponse processResponse(Object response, PortletInvocation
invocation, RequestPrecursor requestPrecursor) throws PortletInvokerException
+ {
+ if (response instanceof ContentResponse)
+ {
+ return (ContentResponse)response;
+ }
+ else
+ {
+ throw new PortletInvokerException("Invalid response object: " +
response);
+ }
+ }
+}
Modified:
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/SessionHandler.java
===================================================================
---
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/SessionHandler.java 2010-03-30
21:32:46 UTC (rev 2402)
+++
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/SessionHandler.java 2010-03-31
00:58:27 UTC (rev 2403)
@@ -275,7 +275,10 @@
invalidateSession(invocation);
// set the session id to null
- runtimeContext.setSessionID(null);
+ if (runtimeContext != null)
+ {
+ runtimeContext.setSessionID(null);
+ }
}
private void invalidateSession(PortletInvocation invocation)
Modified:
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/WSRPConsumerImpl.java
===================================================================
---
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/WSRPConsumerImpl.java 2010-03-30
21:32:46 UTC (rev 2402)
+++
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/consumer/WSRPConsumerImpl.java 2010-03-31
00:58:27 UTC (rev 2403)
@@ -34,6 +34,7 @@
import org.gatein.pc.api.invocation.InvocationException;
import org.gatein.pc.api.invocation.PortletInvocation;
import org.gatein.pc.api.invocation.RenderInvocation;
+import org.gatein.pc.api.invocation.ResourceInvocation;
import org.gatein.pc.api.invocation.response.PortletInvocationResponse;
import org.gatein.pc.api.spi.UserContext;
import org.gatein.pc.api.state.DestroyCloneFailure;
@@ -87,6 +88,7 @@
{
private ActionHandler actionHandler;
private RenderHandler renderHandler;
+ private ResourceHandler resourceHandler;
private SessionHandler sessionHandler;
private ProducerInfo producerInfo;
@@ -128,6 +130,7 @@
actionHandler = new ActionHandler(this);
renderHandler = new RenderHandler(this);
sessionHandler = new SessionHandler(this);
+ resourceHandler = new ResourceHandler(this);
}
public ProducerInfo getProducerInfo()
@@ -178,6 +181,10 @@
{
handler = actionHandler;
}
+ else if (invocation instanceof ResourceInvocation)
+ {
+ handler = resourceHandler;
+ }
else
{
throw new InvocationException("Unknown invocation type: " +
invocation);
Added:
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/handler/CookieUtil.java
===================================================================
--- components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/handler/CookieUtil.java
(rev 0)
+++
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/handler/CookieUtil.java 2010-03-31
00:58:27 UTC (rev 2403)
@@ -0,0 +1,154 @@
+/*
+ * JBoss, a division of Red Hat
+ * Copyright 2010, Red Hat Middleware, LLC, and individual
+ * contributors as indicated by the @authors tag. See the
+ * copyright.txt in the distribution for a full listing of
+ * individual contributors.
+ *
+ * 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.wsrp.handler;
+
+import org.apache.commons.httpclient.Cookie;
+import org.apache.commons.httpclient.cookie.MalformedCookieException;
+import org.apache.commons.httpclient.cookie.RFC2109Spec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.URL;
+import java.util.Date;
+
+/**
+ * @author <a href="mailto:chris.laprun@jboss.com">Chris
Laprun</a>
+ * @version $Revision$
+ */
+public class CookieUtil
+{
+ private static final RFC2109Spec cookieParser = new RFC2109Spec();
+ private static final Logger log =
LoggerFactory.getLogger(RequestHeaderClientHandler.class);
+ public static final String SET_COOKIE = "Set-Cookie";
+ public static final String COOKIE = "Cookie";
+
+ public static Cookie[] extractCookiesFrom(URL remoteAddress, String[] cookieValues)
+ {
+ return extractCookies(remoteAddress, coalesceCookies(cookieValues));
+ }
+
+ /**
+ * Coalesce several Set-Cookie headers into one and returning the resulting
concatenated String.
+ *
+ * @param cookieValues the array containing the values of the different Set-Cookie
headers to be coalesced
+ * @return the concatenated value that could be used as one Set-Cookie header
+ */
+ private static String coalesceCookies(String[] cookieValues)
+ {
+ assert cookieValues != null;
+
+ StringBuffer logBuffer = null;
+ if (log.isDebugEnabled())
+ {
+ logBuffer = new StringBuffer(128);
+ logBuffer.append("Cookie headers:\n");
+ }
+
+ int cookieNumber = cookieValues.length;
+ StringBuffer cookieBuffer = new StringBuffer(cookieNumber * 128);
+ String cookieValue;
+ for (int i = 0; i < cookieNumber; i++)
+ {
+ cookieValue = cookieValues[i];
+ cookieBuffer.append(cookieValue);
+
+ // multiple cookies are separated by commas:
http://www.ietf.org/rfc/rfc2109.txt, 4.2.2
+ if (i < cookieNumber - 1)
+ {
+ cookieBuffer.append(',');
+ }
+
+ if (log.isDebugEnabled())
+ {
+
logBuffer.append("\t").append(i).append(":\t").append(cookieValue).append("\n");
+ }
+ }
+
+ if (log.isDebugEnabled())
+ {
+ log.debug(logBuffer.toString());
+ }
+
+ return cookieBuffer.toString();
+ }
+
+ private static Cookie[] extractCookies(URL hostURL, String cookieValue)
+ {
+ Cookie[] cookies;
+ try
+ {
+ String host = hostURL.getHost();
+ int port = hostURL.getPort();
+ if (port == -1)
+ {
+ port = 80; // if the port is not set in the endpoint address, assume it's
80.
+ }
+ String path = hostURL.getPath();
+ boolean secure = hostURL.getProtocol().endsWith("s"); // todo: is that
correct?
+
+ cookies = cookieParser.parse(host, port, path, secure, cookieValue);
+
+ for (Cookie cookie : cookies)
+ {
+ cookieParser.validate(host, port, path, secure, cookie);
+ }
+ }
+ catch (MalformedCookieException e)
+ {
+ throw new IllegalArgumentException("Malformed cookie: " +
cookieValue);
+ }
+ return cookies;
+ }
+
+ public static javax.servlet.http.Cookie convertFrom(Cookie cookie)
+ {
+ if (cookie == null)
+ {
+ return null;
+ }
+
+
+ javax.servlet.http.Cookie result = new javax.servlet.http.Cookie(cookie.getName(),
cookie.getValue());
+ result.setComment(cookie.getComment());
+ result.setDomain(cookie.getDomain());
+
+ long maxAgeLong = cookie.getExpiryDate().getTime() - new Date().getTime();
+ int maxAge;
+ if (maxAgeLong >= Integer.MAX_VALUE)
+ {
+ maxAge = Integer.MAX_VALUE;
+ }
+ else
+ {
+ maxAge = (int)maxAgeLong;
+ }
+ result.setMaxAge(maxAge);
+
+ result.setPath(cookie.getPath());
+ result.setSecure(cookie.getSecure());
+ result.setVersion(cookie.getVersion());
+
+ return result;
+ }
+}
Modified:
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/handler/RequestHeaderClientHandler.java
===================================================================
---
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/handler/RequestHeaderClientHandler.java 2010-03-30
21:32:46 UTC (rev 2402)
+++
components/wsrp/trunk/consumer/src/main/java/org/gatein/wsrp/handler/RequestHeaderClientHandler.java 2010-03-31
00:58:27 UTC (rev 2403)
@@ -24,11 +24,7 @@
package org.gatein.wsrp.handler;
import org.apache.commons.httpclient.Cookie;
-import org.apache.commons.httpclient.cookie.MalformedCookieException;
-import org.apache.commons.httpclient.cookie.RFC2109Spec;
import org.gatein.wsrp.consumer.ProducerSessionInformation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import javax.xml.namespace.QName;
import javax.xml.soap.MimeHeaders;
@@ -51,10 +47,10 @@
public class RequestHeaderClientHandler implements SOAPHandler<SOAPMessageContext>
{
private static final ThreadLocal<CurrentInfo> local = new
ThreadLocal<CurrentInfo>();
- private static final RFC2109Spec cookieParser = new RFC2109Spec();
+ /*private static final RFC2109Spec cookieParser = new RFC2109Spec();
private static final Logger log =
LoggerFactory.getLogger(RequestHeaderClientHandler.class);
private static final String SET_COOKIE = "Set-Cookie";
- private static final String COOKIE = "Cookie";
+ private static final String COOKIE = "Cookie";*/
public Set<QName> getHeaders()
{
@@ -127,7 +123,7 @@
if (cookie.length() != 0)
{
- mimeHeaders.setHeader(COOKIE, cookie.toString());
+ mimeHeaders.setHeader(CookieUtil.COOKIE, cookie.toString());
}
return true;
@@ -138,13 +134,27 @@
SOAPMessageContext smc = (SOAPMessageContext)msgContext;
SOAPMessage message = smc.getMessage();
MimeHeaders mimeHeaders = message.getMimeHeaders();
- String[] cookieValues = mimeHeaders.getHeader(SET_COOKIE);
+ String[] cookieValues = mimeHeaders.getHeader(CookieUtil.SET_COOKIE);
+ String endpointAddress =
(String)msgContext.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
if (cookieValues != null)
{
- String cookieValue = coalesceCookies(cookieValues);
+ if (endpointAddress == null)
+ {
+ throw new NullPointerException("Was expecting an endpoint address but
none was provided in the MessageContext");
+ }
- Cookie[] cookies =
extractCookies((String)msgContext.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY),
cookieValue);
+ URL hostURL;
+ try
+ {
+ hostURL = new URL(endpointAddress);
+ }
+ catch (MalformedURLException e)
+ {
+ // should not happen
+ throw new IllegalArgumentException(endpointAddress + " is not a valid
URL for the endpoint address.");
+ }
+ Cookie[] cookies = CookieUtil.extractCookiesFrom(hostURL, cookieValues);
CurrentInfo info = getCurrentInfo(true);
ProducerSessionInformation sessionInfo = info.sessionInfo;
@@ -167,95 +177,6 @@
return true;
}
- /**
- * Coalesce several Set-Cookie headers into one and returning the resulting
concatenated String.
- *
- * @param cookieValues the array containing the values of the different Set-Cookie
headers to be coalesced
- * @return the concatenated value that could be used as one Set-Cookie header
- */
- private String coalesceCookies(String[] cookieValues)
- {
- assert cookieValues != null;
-
- StringBuffer logBuffer = null;
- if (log.isDebugEnabled())
- {
- logBuffer = new StringBuffer(128);
- logBuffer.append("Cookie headers:\n");
- }
-
- int cookieNumber = cookieValues.length;
- StringBuffer cookieBuffer = new StringBuffer(cookieNumber * 128);
- String cookieValue;
- for (int i = 0; i < cookieNumber; i++)
- {
- cookieValue = cookieValues[i];
- cookieBuffer.append(cookieValue);
-
- // multiple cookies are separated by commas:
http://www.ietf.org/rfc/rfc2109.txt, 4.2.2
- if (i < cookieNumber - 1)
- {
- cookieBuffer.append(',');
- }
-
- if (log.isDebugEnabled())
- {
-
logBuffer.append("\t").append(i).append(":\t").append(cookieValue).append("\n");
- }
- }
-
- if (log.isDebugEnabled())
- {
- log.debug(logBuffer.toString());
- }
-
- return cookieBuffer.toString();
- }
-
- private Cookie[] extractCookies(String endpointAddress, String cookieValue)
- {
- if (endpointAddress == null)
- {
- throw new NullPointerException("Was expecting an endpoint address but none
was provided in the MessageContext");
- }
-
- URL hostURL;
- try
- {
- hostURL = new URL(endpointAddress);
- }
- catch (MalformedURLException e)
- {
- // should not happen
- throw new IllegalArgumentException(endpointAddress + " is not a valid URL
for the endpoint address.");
- }
-
- Cookie[] cookies;
- try
- {
- String host = hostURL.getHost();
- int port = hostURL.getPort();
- if (port == -1)
- {
- port = 80; // if the port is not set in the endpoint address, assume it's
80.
- }
- String path = hostURL.getPath();
- boolean secure = hostURL.getProtocol().endsWith("s"); // todo: is that
correct?
-
- cookies = cookieParser.parse(host, port, path, secure, cookieValue);
-
- for (Cookie cookie : cookies)
- {
- cookieParser.validate(host, port, path, secure, cookie);
- }
- }
- catch (MalformedCookieException e)
- {
- throw new IllegalArgumentException("Malformed cookie: " +
cookieValue);
- }
- return cookies;
- }
-
public static void setCurrentInfo(String groupId, ProducerSessionInformation
sessionInformation)
{
local.set(new CurrentInfo(groupId, sessionInformation));
Modified:
components/wsrp/trunk/consumer/src/test/java/org/gatein/wsrp/consumer/RenderHandlerTestCase.java
===================================================================
---
components/wsrp/trunk/consumer/src/test/java/org/gatein/wsrp/consumer/RenderHandlerTestCase.java 2010-03-30
21:32:46 UTC (rev 2402)
+++
components/wsrp/trunk/consumer/src/test/java/org/gatein/wsrp/consumer/RenderHandlerTestCase.java 2010-03-31
00:58:27 UTC (rev 2403)
@@ -24,7 +24,6 @@
package org.gatein.wsrp.consumer;
import junit.framework.TestCase;
-import org.gatein.common.net.URLTools;
import org.gatein.pc.api.PortletContext;
import org.gatein.pc.api.URLFormat;
import org.gatein.wsrp.WSRPRewritingConstants;
@@ -64,7 +63,7 @@
processMarkupAndCheck(markup, expected);
}
- public void testResourceURLs()
+ /*public void testResourceURLs()
{
String markup;
String expected;
@@ -80,7 +79,7 @@
markup =
"wsrp_rewrite?wsrp-urlType=resource&wsrp-url=http%3A%2F%2Flocalhost%3A8080%2Fhelloworld&wsrp-requiresRewrite=true/wsrp_rewrite&foo=bar/helloworld.jar";
processMarkupAndCheck(markup,
"http://localhost:8080/helloworld&foo=bar/helloworld.jar");
- }
+ }*/
public void testRegularURLIsNotAffected()
{
@@ -92,7 +91,7 @@
processMarkupAndCheck(markup, markup);
}
- public void testProcessMarkupResourceFromTemplate()
+ /*public void testProcessMarkupResourceFromTemplate()
{
String url =
"http%3a%2f%2fwsrp.netunitysoftware.com%2fWSRPTestService%2fWSRPTestService.asmx%3ftimeout%3d30000%2fgetResource%3fportletHandle%3d781F3EE5-22DF-4ef9-9664-F5FC759065DB%26Function%3dResource%26Name%3dNetUnity%26Type%3dGIF";
String markup = "<table cellpadding=\"2\"
cellspacing=\"0\" border=\"0\" width=\"100%\">\n" +
@@ -121,6 +120,41 @@
"<A HREF=\"http://www.netunitysoftware.com\"
TITLE=\"NetUnity WSRP .NET Framework\" >" +
"<img src=\"" + URLTools.decodeXWWWFormURL(url) +
"\" border=\"0\" /></A>";
processMarkupAndCheck(markup, expected);
+ }*/
+
+ public void testGTNWSRP12Workaround()
+ {
+ String timeout = "%3ftimeout%3d100000";
+ String beforeTimeout =
"http%3a%2f%2fwsrp.netunitysoftware.com%2fWSRPTestService%2fWSRPTestService.asmx";
+ String afterTimeout =
"%2fgetResource%3fportletHandle%3d781F3EE5-22DF-4ef9-9664-F5FC759065DB%26Function%3dResource%26Name%3dNetUnity%26Type%3dGIF";
+ String originalURL = beforeTimeout + timeout + afterTimeout;
+ String markup = "<table cellpadding=\"2\"
cellspacing=\"0\" border=\"0\" width=\"100%\">\n" +
+ "\t<tr class=\"portlet-table-header\">\n" +
+ "\t\t<td>Symbol</td>\n" +
+ "\t\t<td>Name</td>\n" +
+ "\t\t<td align=\"right\">Price</td>\n" +
+ "\t\t<td></td>\n" +
+ "\t\t<td align=\"right\">Change</td>\n" +
+ "\t\t<td align=\"right\">% Chg</td>\n" +
+ "\t</tr>\n" +
+ "</table>\n" +
+ "<A HREF=\"http://www.netunitysoftware.com\"
TITLE=\"NetUnity WSRP .NET Framework\" >" +
+ "<img src=\"" + originalURL + "\"
border=\"0\" /></A>";
+
+ String expected = "<table cellpadding=\"2\"
cellspacing=\"0\" border=\"0\" width=\"100%\">\n" +
+ "\t<tr class=\"portlet-table-header\">\n" +
+ "\t\t<td>Symbol</td>\n" +
+ "\t\t<td>Name</td>\n" +
+ "\t\t<td align=\"right\">Price</td>\n" +
+ "\t\t<td></td>\n" +
+ "\t\t<td align=\"right\">Change</td>\n" +
+ "\t\t<td align=\"right\">% Chg</td>\n" +
+ "\t</tr>\n" +
+ "</table>\n" +
+ "<A HREF=\"http://www.netunitysoftware.com\"
TITLE=\"NetUnity WSRP .NET Framework\" >" +
+ "<img src=\"" + beforeTimeout + afterTimeout + "\"
border=\"0\" /></A>";
+
+ processMarkupAndCheck(markup, expected);
}
private void processMarkupAndCheck(String markup, String expected)