PageRenderTime 53ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/struts-2.2.1/src/plugins/portlet/src/main/java/org/apache/struts2/portlet/util/PortletUrlHelper.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 298 lines | 194 code | 18 blank | 86 comment | 48 complexity | 30e99a3a7a132dce6f2d677edba0418a MD5 | raw file
  1. /*
  2. * $Id: PortletUrlHelper.java 833239 2009-11-05 23:46:50Z rgielen $
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one
  5. * or more contributor license agreements. See the NOTICE file
  6. * distributed with this work for additional information
  7. * regarding copyright ownership. The ASF licenses this file
  8. * to you under the Apache License, Version 2.0 (the
  9. * "License"); you may not use this file except in compliance
  10. * with the License. You may obtain a copy of the License at
  11. *
  12. * http://www.apache.org/licenses/LICENSE-2.0
  13. *
  14. * Unless required by applicable law or agreed to in writing,
  15. * software distributed under the License is distributed on an
  16. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  17. * KIND, either express or implied. See the License for the
  18. * specific language governing permissions and limitations
  19. * under the License.
  20. */
  21. package org.apache.struts2.portlet.util;
  22. import com.opensymphony.xwork2.util.logging.Logger;
  23. import com.opensymphony.xwork2.util.logging.LoggerFactory;
  24. import org.apache.commons.lang.xwork.StringUtils;
  25. import org.apache.struts2.StrutsException;
  26. import org.apache.struts2.portlet.PortletActionConstants;
  27. import org.apache.struts2.portlet.context.PortletActionContext;
  28. import javax.portlet.*;
  29. import java.io.UnsupportedEncodingException;
  30. import java.net.URLEncoder;
  31. import java.util.Iterator;
  32. import java.util.LinkedHashMap;
  33. import java.util.Map;
  34. import java.util.StringTokenizer;
  35. /**
  36. * Helper class for creating Portlet URLs. Portlet URLs are fundamentally different from regular
  37. * servlet URLs since they never target the application itself; all requests go through the portlet
  38. * container and must therefore be programatically constructed using the
  39. * {@link javax.portlet.RenderResponse#createActionURL()} and
  40. * {@link javax.portlet.RenderResponse#createRenderURL()} APIs.
  41. *
  42. */
  43. public class PortletUrlHelper {
  44. public static final String ENCODING = "UTF-8";
  45. private static final Logger LOG = LoggerFactory.getLogger(PortletUrlHelper.class);
  46. /**
  47. * Create a portlet URL with for the specified action and namespace.
  48. *
  49. * @param action The action the URL should invoke.
  50. * @param namespace The namespace of the action to invoke.
  51. * @param method The method of the action to invoke.
  52. * @param params The parameters of the URL.
  53. * @param type The type of the url, either <tt>action</tt> or <tt>render</tt>
  54. * @param mode The PortletMode of the URL.
  55. * @param state The WindowState of the URL.
  56. * @return The URL String.
  57. */
  58. public static String buildUrl(String action, String namespace, String method, Map params,
  59. String type, String mode, String state) {
  60. return buildUrl(action, namespace, method, params, null, type, mode, state,
  61. true, true);
  62. }
  63. /**
  64. * Create a portlet URL with for the specified action and namespace.
  65. *
  66. * @see #buildUrl(String, String, Map, String, String, String)
  67. */
  68. public static String buildUrl(String action, String namespace, String method, Map params,
  69. String scheme, String type, String portletMode, String windowState,
  70. boolean includeContext, boolean encodeResult) {
  71. StringBuffer resultingAction = new StringBuffer();
  72. RenderRequest request = PortletActionContext.getRenderRequest();
  73. RenderResponse response = PortletActionContext.getRenderResponse();
  74. LOG.debug("Creating url. Action = " + action + ", Namespace = "
  75. + namespace + ", Type = " + type);
  76. namespace = prependNamespace(namespace, portletMode);
  77. if (StringUtils.isEmpty(portletMode)) {
  78. portletMode = PortletActionContext.getRenderRequest().getPortletMode().toString();
  79. }
  80. String result = null;
  81. int paramStartIndex = action.indexOf('?');
  82. if (paramStartIndex > 0) {
  83. String value = action;
  84. action = value.substring(0, value.indexOf('?'));
  85. String queryStr = value.substring(paramStartIndex + 1);
  86. StringTokenizer tok = new StringTokenizer(queryStr, "&");
  87. while (tok.hasMoreTokens()) {
  88. String paramVal = tok.nextToken();
  89. String key = paramVal.substring(0, paramVal.indexOf('='));
  90. String val = paramVal.substring(paramVal.indexOf('=') + 1);
  91. params.put(key, new String[] { val });
  92. }
  93. }
  94. if (StringUtils.isNotEmpty(namespace)) {
  95. resultingAction.append(namespace);
  96. if(!action.startsWith("/") && !namespace.endsWith("/")) {
  97. resultingAction.append("/");
  98. }
  99. }
  100. resultingAction.append(action);
  101. if(StringUtils.isNotEmpty(method)) {
  102. resultingAction.append("!").append(method);
  103. }
  104. if (LOG.isDebugEnabled()) LOG.debug("Resulting actionPath: " + resultingAction);
  105. params.put(PortletActionConstants.ACTION_PARAM, new String[] { resultingAction.toString() });
  106. PortletURL url = null;
  107. if ("action".equalsIgnoreCase(type)) {
  108. if (LOG.isDebugEnabled()) LOG.debug("Creating action url");
  109. url = response.createActionURL();
  110. } else {
  111. if (LOG.isDebugEnabled()) LOG.debug("Creating render url");
  112. url = response.createRenderURL();
  113. }
  114. params.put(PortletActionConstants.MODE_PARAM, portletMode);
  115. url.setParameters(ensureParamsAreStringArrays(params));
  116. if ("HTTPS".equalsIgnoreCase(scheme)) {
  117. try {
  118. url.setSecure(true);
  119. } catch (PortletSecurityException e) {
  120. LOG.error("Cannot set scheme to https", e);
  121. }
  122. }
  123. try {
  124. url.setPortletMode(getPortletMode(request, portletMode));
  125. url.setWindowState(getWindowState(request, windowState));
  126. } catch (Exception e) {
  127. LOG.error("Unable to set mode or state:" + e.getMessage(), e);
  128. }
  129. result = url.toString();
  130. // TEMP BUG-WORKAROUND FOR DOUBLE ESCAPING OF AMPERSAND
  131. if(result.indexOf("&amp;") >= 0) {
  132. result = result.replace("&amp;", "&");
  133. }
  134. return result;
  135. }
  136. /**
  137. *
  138. * Prepend the namespace configuration for the specified namespace and PortletMode.
  139. *
  140. * @param namespace The base namespace.
  141. * @param portletMode The PortletMode.
  142. *
  143. * @return prepended namespace.
  144. */
  145. private static String prependNamespace(String namespace, String portletMode) {
  146. StringBuffer sb = new StringBuffer();
  147. PortletMode mode = PortletActionContext.getRenderRequest().getPortletMode();
  148. if(StringUtils.isNotEmpty(portletMode)) {
  149. mode = new PortletMode(portletMode);
  150. }
  151. String portletNamespace = PortletActionContext.getPortletNamespace();
  152. String modeNamespace = (String)PortletActionContext.getModeNamespaceMap().get(mode);
  153. if (LOG.isDebugEnabled()) LOG.debug("PortletNamespace: " + portletNamespace + ", modeNamespace: " + modeNamespace);
  154. if(StringUtils.isNotEmpty(portletNamespace)) {
  155. sb.append(portletNamespace);
  156. }
  157. if(StringUtils.isNotEmpty(modeNamespace)) {
  158. if(!modeNamespace.startsWith("/")) {
  159. sb.append("/");
  160. }
  161. sb.append(modeNamespace);
  162. }
  163. if(StringUtils.isNotEmpty(namespace)) {
  164. if(!namespace.startsWith("/")) {
  165. sb.append("/");
  166. }
  167. sb.append(namespace);
  168. }
  169. if (LOG.isDebugEnabled()) LOG.debug("Resulting namespace: " + sb);
  170. return sb.toString();
  171. }
  172. /**
  173. * Encode an url to a non Struts action resource, like stylesheet, image or
  174. * servlet.
  175. *
  176. * @param value
  177. * @return encoded url to non Struts action resources.
  178. */
  179. public static String buildResourceUrl(String value, Map<String, Object> params) {
  180. StringBuffer sb = new StringBuffer();
  181. // Relative URLs are not allowed in a portlet
  182. if (!value.startsWith("/")) {
  183. sb.append("/");
  184. }
  185. sb.append(value);
  186. if(params != null && params.size() > 0) {
  187. sb.append("?");
  188. Iterator<Map.Entry<String, Object>> it = params.entrySet().iterator();
  189. try {
  190. while(it.hasNext()) {
  191. Map.Entry<String, Object> entry = it.next();
  192. sb.append(URLEncoder.encode(entry.getKey(), ENCODING)).append("=");
  193. sb.append(URLEncoder.encode(entry.getValue().toString(), ENCODING));
  194. if(it.hasNext()) {
  195. sb.append("&");
  196. }
  197. }
  198. } catch (UnsupportedEncodingException e) {
  199. throw new StrutsException("Encoding "+ENCODING+" not found");
  200. }
  201. }
  202. RenderResponse resp = PortletActionContext.getRenderResponse();
  203. RenderRequest req = PortletActionContext.getRenderRequest();
  204. return resp.encodeURL(req.getContextPath() + sb.toString());
  205. }
  206. /**
  207. * Will ensure that all entries in <code>params</code> are String arrays,
  208. * as requried by the setParameters on the PortletURL.
  209. *
  210. * @param params The parameters to the URL.
  211. * @return A Map with all parameters as String arrays.
  212. */
  213. public static Map ensureParamsAreStringArrays(Map<String, Object> params) {
  214. Map<String, String[]> result = null;
  215. if (params != null) {
  216. result = new LinkedHashMap<String, String[]>(params.size());
  217. Iterator<Map.Entry<String, Object>> it = params.entrySet().iterator();
  218. while (it.hasNext()) {
  219. Map.Entry<String, Object> entry = it.next();
  220. Object val = entry.getValue();
  221. if (val instanceof String[]) {
  222. result.put(entry.getKey(), (String[])val);
  223. } else {
  224. result.put(entry.getKey(), new String[] { val.toString() });
  225. }
  226. }
  227. }
  228. return result;
  229. }
  230. /**
  231. * Convert the given String to a WindowState object.
  232. *
  233. * @param portletReq The RenderRequest.
  234. * @param windowState The WindowState as a String.
  235. * @return The WindowState that mathces the <tt>windowState</tt> String, or if
  236. * the String is blank, the current WindowState.
  237. */
  238. private static WindowState getWindowState(RenderRequest portletReq,
  239. String windowState) {
  240. WindowState state = portletReq.getWindowState();
  241. if (StringUtils.isNotEmpty(windowState)) {
  242. if ("maximized".equalsIgnoreCase(windowState)) {
  243. state = WindowState.MAXIMIZED;
  244. } else if ("normal".equalsIgnoreCase(windowState)) {
  245. state = WindowState.NORMAL;
  246. } else if ("minimized".equalsIgnoreCase(windowState)) {
  247. state = WindowState.MINIMIZED;
  248. }
  249. }
  250. if(state == null) {
  251. state = WindowState.NORMAL;
  252. }
  253. return state;
  254. }
  255. /**
  256. * Convert the given String to a PortletMode object.
  257. *
  258. * @param portletReq The RenderRequest.
  259. * @param portletMode The PortletMode as a String.
  260. * @return The PortletMode that mathces the <tt>portletMode</tt> String, or if
  261. * the String is blank, the current PortletMode.
  262. */
  263. private static PortletMode getPortletMode(RenderRequest portletReq,
  264. String portletMode) {
  265. PortletMode mode = portletReq.getPortletMode();
  266. if (StringUtils.isNotEmpty(portletMode)) {
  267. if ("edit".equalsIgnoreCase(portletMode)) {
  268. mode = PortletMode.EDIT;
  269. } else if ("view".equalsIgnoreCase(portletMode)) {
  270. mode = PortletMode.VIEW;
  271. } else if ("help".equalsIgnoreCase(portletMode)) {
  272. mode = PortletMode.HELP;
  273. }
  274. }
  275. if(mode == null) {
  276. mode = PortletMode.VIEW;
  277. }
  278. return mode;
  279. }
  280. }