/* * 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; import org.gatein.common.net.URLTools; import org.gatein.common.util.ParameterValidation; import org.gatein.pc.api.Mode; import org.gatein.pc.api.StateString; import org.gatein.pc.api.WindowState; import org.gatein.pc.api.cache.CacheLevel; import org.oasis.wsrp.v2.GetResource; import org.oasis.wsrp.v2.NamedString; import org.oasis.wsrp.v2.PortletContext; import org.oasis.wsrp.v2.RegistrationContext; import org.oasis.wsrp.v2.ResourceParams; import org.oasis.wsrp.v2.RuntimeContext; import org.oasis.wsrp.v2.StateChange; import javax.servlet.http.HttpServletRequest; import java.net.URI; import java.net.URL; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.Map; /** * @author <a href="mailto:chris.laprun@jboss.com">Chris Laprun</a> * @version $Revision$ */ public class ResourceServingUtil { private static final String REG_HANDLE = "regHandle"; private static final String INSTANCE_KEY = "instanceKey"; private static final String NS = "ns"; private static final String MODE = "mode"; private static final String WINDOW_STATE = "windowState"; private static final String RESOURCE_STATE = "resourceState"; private static final String NAV_STATE = "navState"; private static final String SLASH_REPLACEMENT = "__"; private static final String QMARK = "?"; public static GetResource decode(HttpServletRequest req) { String path = req.getPathInfo(); int portletHandleEnd = path.indexOf(URLTools.SLASH, 1); String portletHandle = path.substring(1, portletHandleEnd); PortletContext portletContext = decode(portletHandle); String resourceId = path.substring(portletHandleEnd); String registrationHandle = req.getParameter(REG_HANDLE); RegistrationContext registrationContext = null; if (!ParameterValidation.isNullOrEmpty(registrationHandle)) { registrationContext = WSRPTypeFactory.createRegistrationContext(registrationHandle); } String instanceKey = URLTools.decodeXWWWFormURL(req.getParameter(INSTANCE_KEY)); String ns = req.getParameter(NS); RuntimeContext runtimeContext = WSRPTypeFactory.createRuntimeContext(WSRPConstants.NONE_USER_AUTHENTICATION, instanceKey, ns); Enumeration reqLocales = req.getLocales(); List<String> locales = WSRPUtils.convertLocalesToRFC3066LanguageTags(Collections.list(reqLocales)); List<String> mimeTypes = WSRPConstants.getDefaultMimeTypes(); Map<String, String[]> parameters = req.getParameterMap(); ResourceParams resourceParams = WSRPTypeFactory.createResourceParams(req.isSecure(), locales, mimeTypes, WSRPConstants.VIEW_MODE, WSRPConstants.NORMAL_WINDOW_STATE, resourceId, StateChange.READ_ONLY, parameters); resourceParams.setResourceState(req.getParameter(RESOURCE_STATE)); String navState = req.getParameter(NAV_STATE); if (!ParameterValidation.isNullOrEmpty(navState)) { resourceParams.setNavigationalContext(WSRPTypeFactory.createNavigationalContext(navState, Collections.<NamedString>emptyList())); } return WSRPTypeFactory.createGetResource(registrationContext, portletContext, runtimeContext, null, resourceParams); } public static URL encode(Mode mode, WindowState windowState, boolean secure, StateString navigationalState, StateString resourceState, String resourceId, CacheLevel cacheability, WSRPPortletURL.URLContext context) { // Generate a resource URL based on the resource Id String serverAddress = (String)context.getValueFor(WSRPPortletURL.URLContext.SERVER_ADDRESS); org.gatein.pc.api.PortletContext portletContext = (org.gatein.pc.api.PortletContext)context.getValueFor(WSRPPortletURL.URLContext.PORTLET_CONTEXT); try { StringBuilder sb = new StringBuilder(createAbsoluteURLFrom(resourceId, serverAddress, portletContext)); appendParameter(sb, MODE, mode); appendParameter(sb, WINDOW_STATE, windowState); // instance key can contain a space if it's based on the portlet context so we need to also encode it String instanceKey = (String)context.getValueFor(WSRPPortletURL.URLContext.INSTANCE_KEY); instanceKey = URLTools.encodeXWWWFormURL(instanceKey); appendParameter(sb, INSTANCE_KEY, instanceKey); appendParameter(sb, NS, context.getValueFor(WSRPPortletURL.URLContext.NAMESPACE)); appendParameter(sb, REG_HANDLE, context.getValueFor(WSRPPortletURL.URLContext.REGISTRATION_HANDLE)); if (resourceState != null) { appendParameter(sb, RESOURCE_STATE, resourceState.getStringValue()); } if (navigationalState != null) { appendParameter(sb, NAV_STATE, navigationalState.getStringValue()); } return new URI(sb.toString()).toURL(); } catch (Exception e) { throw new RuntimeException("Couldn't create an absolute URL from resourceId: " + resourceId + ", server address: " + serverAddress + ", portlet: " + portletContext, e); } } private static String createAbsoluteURLFrom(String resourceId, String serverAddress, org.gatein.pc.api.PortletContext portletContext) { ParameterValidation.throwIllegalArgExceptionIfNullOrEmpty(resourceId, "resource ID", null); ParameterValidation.throwIllegalArgExceptionIfNullOrEmpty(serverAddress, "server address", null); ParameterValidation.throwIllegalArgExceptionIfNull(portletContext, "portlet context"); String url = serverAddress + "/wsrp-producer/resource/"; url += encode(portletContext); if (resourceId.startsWith(URLTools.SLASH)) { url += resourceId + QMARK; } else { url += URLTools.SLASH + resourceId + QMARK; } return url; } private static String encode(org.gatein.pc.api.PortletContext portletContext) { String id = portletContext.getId(); if (id.startsWith(URLTools.SLASH)) { id = id.replace(URLTools.SLASH, SLASH_REPLACEMENT); } return URLTools.encodeXWWWFormURL(id); } private static PortletContext decode(String encodedPortletContext) { if (encodedPortletContext.startsWith(SLASH_REPLACEMENT)) { encodedPortletContext = encodedPortletContext.replace(SLASH_REPLACEMENT, URLTools.SLASH); } return WSRPTypeFactory.createPortletContext(URLTools.decodeXWWWFormURL(encodedPortletContext)); } private static void appendParameter(StringBuilder builder, String name, Object value) { if (value != null) { builder.append("&").append(name).append("=").append(value); } } }