001: /******************************************************************************
002: * JBoss, a division of Red Hat *
003: * Copyright 2006, Red Hat Middleware, LLC, and individual *
004: * contributors as indicated by the @authors tag. See the *
005: * copyright.txt in the distribution for a full listing of *
006: * individual contributors. *
007: * *
008: * This is free software; you can redistribute it and/or modify it *
009: * under the terms of the GNU Lesser General Public License as *
010: * published by the Free Software Foundation; either version 2.1 of *
011: * the License, or (at your option) any later version. *
012: * *
013: * This software is distributed in the hope that it will be useful, *
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of *
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
016: * Lesser General Public License for more details. *
017: * *
018: * You should have received a copy of the GNU Lesser General Public *
019: * License along with this software; if not, write to the Free *
020: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
021: * 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
022: ******************************************************************************/package org.jboss.portal.wsrp;
023:
024: import org.jboss.logging.Logger;
025: import org.jboss.portal.Mode;
026: import org.jboss.portal.WindowState;
027: import org.jboss.portal.common.util.Tools;
028: import org.jboss.portal.portlet.ActionURL;
029: import org.jboss.portal.portlet.PortletURL;
030: import org.jboss.portal.portlet.RenderURL;
031: import org.jboss.portal.portlet.StateString;
032:
033: import java.util.HashMap;
034: import java.util.Map;
035:
036: /**
037: * @author <a href="mailto:chris.laprun@jboss.com">Chris Laprun</a>
038: * @version $Revision: 8784 $
039: * @since 2.4 (Apr 28, 2006)
040: */
041: public abstract class WSRPPortletURL implements PortletURL {
042: private static final Logger log = Logger
043: .getLogger(WSRPPortletURL.class);
044:
045: private static final String EQUALS = "=";
046: private static final String AMPERSAND = "&";
047: private static final String PARAM_SEPARATOR = "|";
048: private static final int URL_TYPE_END = WSRPRewritingConstants.URL_TYPE_NAME
049: .length()
050: + EQUALS.length();
051:
052: private boolean secure;
053: private Mode mode;
054: private WindowState windowState;
055:
056: public static WSRPPortletURL create(PortletURL portletURL,
057: boolean secure) {
058: if (portletURL == null) {
059: throw new IllegalArgumentException(
060: "Cannot construct a WSRPPortletURL from a null PortletURL!");
061: }
062:
063: Mode mode = portletURL.getMode();
064: WindowState windowState = portletURL.getWindowState();
065:
066: if (portletURL instanceof ActionURL) {
067: StateString interactionState = ((ActionURL) portletURL)
068: .getInteractionState();
069: StateString navigationalState = ((ActionURL) portletURL)
070: .getNavigationalState();
071: return new WSRPActionURL(mode, windowState, secure,
072: navigationalState, interactionState);
073: } else if (portletURL instanceof RenderURL) {
074: StateString navigationalState = ((RenderURL) portletURL)
075: .getNavigationalState();
076: return new WSRPRenderURL(mode, windowState, secure,
077: navigationalState);
078: } else /*if(portletURL instanceof ResourceURL)*/
079: {
080: // return new WSRPResourceURL(mode, windowState, secure, ((ResourceURL) portletURL).getResourceURL(), false);
081: throw new IllegalArgumentException(
082: "Unknown PortletURL type: "
083: + portletURL.getClass().getName());
084: }
085: }
086:
087: /**
088: * Parses a WSRP rewritten URL and extracts each component. <p/> TODO: some values need to be in pairs or are
089: * mutually exclusive, check for this <p/> <p>URL are of the form: <code>wsrp_rewrite?wsrp-urlType=value&amp;name1=value1&amp;name2=value2
090: * .../wsrp_rewrite</code> </p> <ul>Examples: <li>Load a resource http://test.com/images/test.gif: <br/>
091: * <code>wsrp_rewrite?wsrp-urlType=resource&amp;wsrp-url=http%3A%2F%2Ftest.com%2Fimages%2Ftest.gif&amp;wsrp-requiresRewrite=true/wsrp_rewrite</code></li>
092: * <li>Declare a secure interaction back to the Portlet:<br/> <code>wsrp_rewrite?wsrp-urlType=blockingAction&amp;wsrp-secureURL=true&amp;wsrp-navigationalState=a8h4K5JD9&amp;wsrp-interactionState=fg4h923mdk/wsrp_rewrite</code></li>
093: * <li>Request the Consumer render the Portlet in a different mode and window state:
094: * <code>wsrp_rewrite?wsrp-urlType=render&amp;wsrp-mode=help&amp;wsrp-windowState=maximized/wsrp_rewrite</code></li>
095: * </ul>
096: *
097: * @param encodedURL
098: */
099: public static WSRPPortletURL create(String encodedURL) {
100: log.debug("Trying to build a WSRPPortletURL from <"
101: + encodedURL + ">");
102:
103: if (encodedURL == null || encodedURL.length() == 0) {
104: throw new IllegalArgumentException(
105: "Cannot construct a WSRPPortletURL from a null or empty URL!");
106: }
107:
108: String originalURL = encodedURL;
109:
110: // URL needs to start wsrp_rewrite? and end with /wsrp_rewrite
111: if (!encodedURL
112: .startsWith(WSRPRewritingConstants.BEGIN_WSRP_REWRITE)) {
113: throw new IllegalArgumentException(encodedURL
114: + " does not start with "
115: + WSRPRewritingConstants.BEGIN_WSRP_REWRITE);
116: }
117: if (!encodedURL
118: .endsWith(WSRPRewritingConstants.END_WSRP_REWRITE)) {
119: throw new IllegalArgumentException(encodedURL
120: + " does not end with "
121: + WSRPRewritingConstants.END_WSRP_REWRITE);
122: }
123:
124: // remove prefix and suffix
125: encodedURL = encodedURL
126: .substring(
127: WSRPRewritingConstants.WSRP_REWRITE_PREFIX_LENGTH,
128: encodedURL.length()
129: - WSRPRewritingConstants.WSRP_REWRITE_SUFFIX_LENGTH);
130:
131: // next param should be the url type
132: if (!encodedURL.startsWith(WSRPRewritingConstants.URL_TYPE_NAME
133: + EQUALS)) {
134: throw new IllegalArgumentException(encodedURL
135: + " does not specify a URL type.");
136: }
137:
138: // standardize parameter separators
139: encodedURL = Tools
140: .replace(encodedURL, "&", PARAM_SEPARATOR);
141: encodedURL = Tools.replace(encodedURL, "&", PARAM_SEPARATOR); // this second shouldn't be used but in case it is...
142:
143: // remove url type param name and extract value
144: encodedURL = encodedURL.substring(URL_TYPE_END);
145: String urlType;
146: WSRPPortletURL url;
147: if (encodedURL
148: .startsWith(WSRPRewritingConstants.URL_TYPE_RENDER)) {
149: urlType = WSRPRewritingConstants.URL_TYPE_RENDER;
150: url = new WSRPRenderURL();
151: } else if (encodedURL
152: .startsWith(WSRPRewritingConstants.URL_TYPE_BLOCKING_ACTION)) {
153: urlType = WSRPRewritingConstants.URL_TYPE_BLOCKING_ACTION;
154: url = new WSRPActionURL();
155: } else if (encodedURL
156: .startsWith(WSRPRewritingConstants.URL_TYPE_RESOURCE)) {
157: log.debug("Using experimental resource URL support...");
158: urlType = WSRPRewritingConstants.URL_TYPE_RESOURCE;
159: url = new WSRPResourceURL();
160: } else {
161: throw new IllegalArgumentException(
162: "Unrecognized URL type: "
163: + encodedURL.substring(0, encodedURL
164: .indexOf(PARAM_SEPARATOR)));
165: }
166:
167: // starting from now, everything else is optional so need to check if we still have some chars to parse
168: Map params = null;
169: int urlTypeLength = urlType.length();
170: if (encodedURL.length() != urlTypeLength) {
171: // truncate again once the value is extracted
172: encodedURL = encodedURL.substring(urlTypeLength + 1); // +1 for the param separator
173:
174: // extract the other parameters
175: params = extractParams(encodedURL, originalURL);
176: }
177:
178: url.setParams(params);
179: return url;
180: }
181:
182: protected WSRPPortletURL(Mode mode, WindowState windowState,
183: boolean secure) {
184: this .mode = mode;
185: this .windowState = windowState;
186: this .secure = secure;
187: }
188:
189: protected WSRPPortletURL(Map params) {
190: // populate values
191: setParams(params);
192: }
193:
194: protected WSRPPortletURL() {
195: }
196:
197: protected void setParams(Map params) {
198: String paramValue = getRawParameterValueFor(params,
199: WSRPRewritingConstants.MODE);
200: if (paramValue != null) {
201: mode = Mode.create(paramValue);
202: }
203:
204: //
205: paramValue = getRawParameterValueFor(params,
206: WSRPRewritingConstants.WINDOW_STATE);
207: if (paramValue != null) {
208: windowState = WindowState.create(paramValue);
209: }
210:
211: //
212: paramValue = getRawParameterValueFor(params,
213: WSRPRewritingConstants.SECURE_URL);
214: if (paramValue != null) {
215: secure = Boolean.valueOf(paramValue).booleanValue();
216: }
217: }
218:
219: public String getRawParameterValueFor(Map params,
220: String parameterName) {
221: if (params != null) {
222: return (String) params.get(parameterName);
223: } else {
224: return null;
225: }
226: }
227:
228: public Mode getMode() {
229: return mode;
230: }
231:
232: public WindowState getWindowState() {
233: return windowState;
234: }
235:
236: public boolean isSecure() {
237: return secure;
238: }
239:
240: protected abstract String getURLType();
241:
242: public String toString() {
243: StringBuffer sb = new StringBuffer(255);
244:
245: //
246: sb.append(WSRPRewritingConstants.BEGIN_WSRP_REWRITE).append(
247: WSRPRewritingConstants.URL_TYPE_NAME).append(EQUALS)
248: .append(getURLType());
249:
250: //
251: if (secure) {
252: createURLParameter(sb, WSRPRewritingConstants.SECURE_URL,
253: "true");
254: }
255:
256: //
257: if (mode != null) {
258: createURLParameter(sb, WSRPRewritingConstants.MODE, mode
259: .toString());
260: }
261:
262: //
263: if (windowState != null) {
264: createURLParameter(sb, WSRPRewritingConstants.WINDOW_STATE,
265: windowState.toString());
266: }
267:
268: // fix-me: not sure how to deal with authenticated
269:
270: //
271: appendEnd(sb);
272:
273: //
274: sb.append(WSRPRewritingConstants.END_WSRP_REWRITE);
275: return sb.toString();
276: }
277:
278: protected abstract void appendEnd(StringBuffer sb);
279:
280: protected final void createURLParameter(StringBuffer sb,
281: String name, String value) {
282: if (value != null) {
283: sb.append(AMPERSAND).append(name).append(EQUALS).append(
284: value);
285: }
286: }
287:
288: private static Map extractParams(String encodedURL,
289: String originalURL) {
290: Map params = new HashMap();
291: boolean finished = false;
292: while (encodedURL.length() > 0 && !finished) {
293: int endParamIndex = encodedURL.indexOf(PARAM_SEPARATOR);
294: String param;
295: if (endParamIndex < 0) {
296: // no param left: try the remainder of the String
297: param = encodedURL;
298: finished = true;
299: } else {
300: param = encodedURL.substring(0, endParamIndex);
301: }
302:
303: int equalsIndex = param.indexOf(EQUALS);
304: if (equalsIndex < 0) {
305: throw new IllegalArgumentException(param
306: + " is not a valid parameter for "
307: + originalURL);
308: }
309:
310: String name = param.substring(0, equalsIndex);
311: String value = param.substring(equalsIndex + 1, param
312: .length()); // +1 to ignore "="
313: params.put(name, value);
314: encodedURL = encodedURL.substring(endParamIndex + 1); // +1 for the param separator
315: }
316: return params;
317: }
318:
319: }
|