1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.struts;
16  
17  import com.liferay.portal.kernel.log.Log;
18  import com.liferay.portal.kernel.log.LogFactoryUtil;
19  import com.liferay.portal.kernel.portlet.LiferayPortletURL;
20  import com.liferay.portal.kernel.portlet.PortletModeFactory;
21  import com.liferay.portal.kernel.portlet.WindowStateFactory;
22  import com.liferay.portal.kernel.servlet.URLEncoder;
23  import com.liferay.portal.kernel.util.CharPool;
24  import com.liferay.portal.kernel.util.GetterUtil;
25  import com.liferay.portal.kernel.util.HttpUtil;
26  import com.liferay.portal.kernel.util.StringPool;
27  import com.liferay.portal.kernel.util.StringUtil;
28  import com.liferay.portal.kernel.util.Validator;
29  
30  import java.util.HashMap;
31  
32  import javax.portlet.PortletMode;
33  import javax.portlet.PortletModeException;
34  import javax.portlet.PortletRequest;
35  import javax.portlet.WindowState;
36  import javax.portlet.WindowStateException;
37  
38  import javax.servlet.http.HttpServletResponse;
39  
40  /**
41   * <a href="StrutsURLEncoder.java.html"><b><i>View Source</i></b></a>
42   *
43   * @author Brian Wing Shun Chan
44   */
45  public class StrutsURLEncoder implements URLEncoder {
46  
47      public static void setParameters(
48          LiferayPortletURL portletURL, String queryString) {
49  
50          String[] params = StringUtil.split(queryString, "&");
51  
52          for (int i = 0; i < params.length; i++) {
53              int pos = params[i].indexOf("=");
54  
55              if (pos != -1) {
56                  String param = params[i].substring(0, pos);
57                  String value = params[i].substring(pos + 1, params[i].length());
58  
59                  if (param.equals("windowState")) {
60                      try {
61                          portletURL.setWindowState(
62                              WindowStateFactory.getWindowState(value));
63                      }
64                      catch (WindowStateException wse) {
65                          _log.error(wse.getMessage());
66                      }
67                  }
68                  else if (param.equals("portletMode")) {
69                      try {
70                          portletURL.setPortletMode(
71                              PortletModeFactory.getPortletMode(value));
72                      }
73                      catch (PortletModeException pme) {
74                          _log.error(pme.getMessage());
75                      }
76                  }
77                  else if (param.equals("actionURL")) {
78                      String lifecycle = PortletRequest.RENDER_PHASE;
79  
80                      if (GetterUtil.getBoolean(value)) {
81                          lifecycle = PortletRequest.ACTION_PHASE;
82                      }
83  
84                      portletURL.setLifecycle(lifecycle);
85                  }
86                  else {
87                      portletURL.setParameter(
88                          param, HttpUtil.decodeURL(value), true);
89                  }
90              }
91          }
92      }
93  
94      public StrutsURLEncoder(
95          String contextPath, String mainPath, String servletMapping,
96          LiferayPortletURL portletURL) {
97  
98          _contextPath = contextPath;
99          _mainPath = mainPath;
100         _setServletMapping(servletMapping);
101         _portletURL = portletURL;
102         _windowState = portletURL.getWindowState();
103         _portletMode = portletURL.getPortletMode();
104     }
105 
106     public String encodeURL(HttpServletResponse response, String path) {
107         if (_log.isDebugEnabled()) {
108             _log.debug("Path " + path);
109             _log.debug("Context path " + _contextPath);
110             _log.debug("Servlet mapping " + _servletMapping);
111         }
112 
113         String encodedURL = path;
114 
115         if (path.startsWith("//") ||
116             path.startsWith(_contextPath) ||
117             path.startsWith(_servletMapping)) {
118 
119             // Struts uses &amp; instead of & to delimit parameter key value
120             // pairs when you set the "name" attribute for html:link.
121 
122             path = StringUtil.replace(path, "&amp;", "&");
123 
124             // Reset portlet URL settings so it can be reused
125 
126             _portletURL.setLifecycle(PortletRequest.RENDER_PHASE);
127             _portletURL.setParameters(new HashMap<String, String[]>());
128 
129             try {
130                 _portletURL.setWindowState(_windowState);
131             }
132             catch (WindowStateException wse) {
133             }
134 
135             try {
136                 _portletURL.setPortletMode(_portletMode);
137             }
138             catch (PortletModeException pme) {
139             }
140 
141             // Separate the Struts action from the query string
142 
143             String strutsAction = path;
144             String queryString = StringPool.BLANK;
145 
146             int pos = strutsAction.indexOf(CharPool.QUESTION);
147 
148             if (pos != -1) {
149                 strutsAction = path.substring(0, pos);
150                 queryString = path.substring(pos + 1, path.length());
151             }
152 
153             // Set the Struts action
154 
155             if (strutsAction.startsWith("c/")) {
156                 strutsAction = strutsAction.substring(1);
157             }
158             else if (strutsAction.startsWith("/c/")) {
159                 strutsAction = strutsAction.substring(2);
160             }
161 
162             if (Validator.isNotNull(_contextPath)) {
163                 strutsAction = strutsAction.substring(
164                     _contextPath.length(), strutsAction.length());
165             }
166 
167             if (strutsAction.startsWith(_servletMapping)) {
168                 strutsAction = strutsAction.substring(
169                     _servletMapping.length(), strutsAction.length());
170             }
171 
172             if (!strutsAction.startsWith(StringPool.SLASH)) {
173                 strutsAction = StringPool.SLASH + strutsAction;
174             }
175 
176             if (_log.isDebugEnabled()) {
177                 _log.debug("Struts action " + strutsAction);
178             }
179 
180             _portletURL.setParameter("struts_action", strutsAction);
181 
182             // Set the query string
183 
184             setParameters(_portletURL, queryString);
185 
186             // Return the portlet URL
187 
188             encodedURL = _portletURL.toString();
189 
190             if (_log.isDebugEnabled()) {
191                 _log.debug("Encoded portlet URL " + encodedURL);
192             }
193         }
194 
195         return encodedURL;
196     }
197 
198     private void _setServletMapping(String servletMapping) {
199         if (servletMapping != null) {
200 
201             // See org.apache.struts.util.RequestUtils.getActionMappingURL
202 
203             if (servletMapping.endsWith("/*")) {
204                 int pos = 0;
205 
206                 if (servletMapping.startsWith(_mainPath)) {
207                     pos = _mainPath.length() - 2;
208                 }
209 
210                 _servletMapping = servletMapping.substring(
211                     pos, servletMapping.length() - 1);
212             }
213         }
214     }
215 
216     private static Log _log = LogFactoryUtil.getLog(StrutsURLEncoder.class);
217 
218     private String _contextPath;
219     private String _mainPath;
220     private String _servletMapping = StringPool.BLANK;
221     private LiferayPortletURL _portletURL;
222     private WindowState _windowState;
223     private PortletMode _portletMode;
224 
225 }