1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet;
24  
25  import com.liferay.portal.PortalException;
26  import com.liferay.portal.SystemException;
27  import com.liferay.portal.kernel.portlet.LiferayPortletURL;
28  import com.liferay.portal.kernel.servlet.URLEncoder;
29  import com.liferay.portal.kernel.util.GetterUtil;
30  import com.liferay.portal.kernel.util.Validator;
31  import com.liferay.portal.model.Layout;
32  import com.liferay.portal.model.Portlet;
33  import com.liferay.portal.model.PortletApp;
34  import com.liferay.portal.model.PortletURLListener;
35  import com.liferay.portal.service.PortletLocalServiceUtil;
36  import com.liferay.portal.util.PortalUtil;
37  import com.liferay.portal.util.WebKeys;
38  
39  import java.lang.reflect.Constructor;
40  import java.lang.reflect.Method;
41  
42  import java.util.HashMap;
43  import java.util.Map;
44  import java.util.Set;
45  
46  import javax.portlet.PortletException;
47  import javax.portlet.PortletModeException;
48  import javax.portlet.PortletPreferences;
49  import javax.portlet.PortletRequest;
50  import javax.portlet.PortletResponse;
51  import javax.portlet.PortletURL;
52  import javax.portlet.PortletURLGenerationListener;
53  import javax.portlet.ResourceURL;
54  import javax.portlet.WindowStateException;
55  
56  import javax.servlet.http.Cookie;
57  import javax.servlet.http.HttpServletRequest;
58  import javax.servlet.http.HttpServletResponse;
59  
60  import org.apache.commons.logging.Log;
61  import org.apache.commons.logging.LogFactory;
62  
63  import org.w3c.dom.DOMException;
64  import org.w3c.dom.Element;
65  
66  /**
67   * <a href="PortletResponseImpl.java.html"><b><i>View Source</i></b></a>
68   *
69   * @author Brian Wing Shun Chan
70   *
71   */
72  public abstract class PortletResponseImpl implements PortletResponse {
73  
74      public static PortletResponseImpl getPortletResponseImpl(
75          PortletResponse res) {
76  
77          PortletResponseImpl resImpl = null;
78  
79          if (res instanceof PortletResponseImpl) {
80              resImpl = (PortletResponseImpl)res;
81          }
82          else {
83  
84              // LEP-4033
85  
86              try {
87                  Method method = res.getClass().getMethod("getResponse");
88  
89                  Object obj = method.invoke(res, (Object[])null);
90  
91                  resImpl = getPortletResponseImpl((PortletResponse)obj);
92              }
93              catch (Exception e) {
94                  throw new RuntimeException(
95                      "Unable to get the HTTP servlet resuest from " +
96                          res.getClass().getName());
97              }
98          }
99  
100         return resImpl;
101     }
102 
103     public void addProperty(Cookie cookie) {
104         if (cookie == null) {
105             throw new IllegalArgumentException();
106         }
107     }
108 
109     public void addProperty(String key, Element element) {
110         if (key == null) {
111             throw new IllegalArgumentException();
112         }
113     }
114 
115     public void addProperty(String key, String value) {
116         if (key == null) {
117             throw new IllegalArgumentException();
118         }
119     }
120 
121     public PortletURL createActionURL() {
122         return createActionURL(_portletName);
123     }
124 
125     public LiferayPortletURL createActionURL(String portletName) {
126         return createPortletURLImpl(portletName, PortletRequest.ACTION_PHASE);
127     }
128 
129     public Element createElement(String tagName) throws DOMException {
130         return null;
131     }
132 
133     public PortletURLImpl createPortletURLImpl(String lifecycle) {
134         return createPortletURLImpl(_portletName, lifecycle);
135     }
136 
137     public PortletURLImpl createPortletURLImpl(
138         String portletName, String lifecycle) {
139 
140         long plid = _plid;
141 
142         try {
143             Layout layout = (Layout)_req.getAttribute(WebKeys.LAYOUT);
144 
145             PortletPreferences portletSetup =
146                 PortletPreferencesFactoryUtil.getPortletSetup(
147                     layout, _portletName);
148 
149             plid = GetterUtil.getLong(portletSetup.getValue(
150                 "portlet-setup-link-to-plid", String.valueOf(_plid)));
151 
152             if (plid <= 0) {
153                 plid = _plid;
154             }
155         }
156         catch (PortalException e) {
157             if (_log.isWarnEnabled()) {
158                 _log.warn(e);
159             }
160         }
161         catch (SystemException e) {
162             if (_log.isWarnEnabled()) {
163                 _log.warn(e);
164             }
165         }
166 
167         PortletURLImpl portletURLImpl = null;
168 
169         Portlet portlet = getPortlet();
170 
171         String portletURLClass = portlet.getPortletURLClass();
172 
173         if (portlet.getPortletId().equals(portletName) &&
174             Validator.isNotNull(portletURLClass)) {
175 
176             try {
177                 Class<?> portletURLClassObj = Class.forName(portletURLClass);
178 
179                 Constructor<?> constructor = portletURLClassObj.getConstructor(
180                     new Class[] {
181                         com.liferay.portlet.PortletResponseImpl.class,
182                         long.class, String.class
183                     });
184 
185                 portletURLImpl = (PortletURLImpl)constructor.newInstance(
186                     new Object[] {this, plid, lifecycle});
187             }
188             catch (Exception e) {
189                 _log.error(e);
190             }
191         }
192 
193         if (portletURLImpl == null) {
194             portletURLImpl = new PortletURLImpl(
195                 _req, portletName, plid, lifecycle);
196         }
197 
198         PortletApp portletApp = portlet.getPortletApp();
199 
200         Set<PortletURLListener> portletURLListeners =
201             portletApp.getPortletURLListeners();
202 
203         for (PortletURLListener portletURLListener : portletURLListeners) {
204             try {
205                 PortletURLGenerationListener portletURLGenerationListener =
206                     PortletURLListenerFactory.create(portletURLListener);
207 
208                 if (lifecycle.equals(PortletRequest.ACTION_PHASE)) {
209                     portletURLGenerationListener.filterActionURL(
210                         portletURLImpl);
211                 }
212                 else if (lifecycle.equals(PortletRequest.RENDER_PHASE)) {
213                     portletURLGenerationListener.filterRenderURL(
214                         portletURLImpl);
215                 }
216                 else if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
217                     portletURLGenerationListener.filterResourceURL(
218                         portletURLImpl);
219                 }
220             }
221             catch (PortletException pe) {
222                 _log.error(pe, pe);
223             }
224         }
225 
226         try {
227             portletURLImpl.setWindowState(_req.getWindowState());
228         }
229         catch (WindowStateException wse) {
230             _log.error(wse.getMessage());
231         }
232 
233         try {
234             portletURLImpl.setPortletMode(_req.getPortletMode());
235         }
236         catch (PortletModeException pme) {
237             _log.error(pme.getMessage());
238         }
239 
240         if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
241             portletURLImpl.setCopyCurrentRenderParameters(true);
242         }
243 
244         return portletURLImpl;
245     }
246 
247     public PortletURL createRenderURL() {
248         return createRenderURL(_portletName);
249     }
250 
251     public LiferayPortletURL createRenderURL(String portletName) {
252         return createPortletURLImpl(portletName, PortletRequest.RENDER_PHASE);
253     }
254 
255     public ResourceURL createResourceURL() {
256         return createResourceURL(_portletName);
257     }
258 
259     public LiferayPortletURL createResourceURL(String portletName) {
260         return createPortletURLImpl(portletName, PortletRequest.RESOURCE_PHASE);
261     }
262 
263     public String encodeURL(String path) {
264         if ((path == null) ||
265             (!path.startsWith("#") && !path.startsWith("/") &&
266                 (path.indexOf("://") == -1))) {
267 
268             // Allow '#' as well to workaround a bug in Oracle ADF 10.1.3
269 
270             throw new IllegalArgumentException(
271                 "URL path must start with a '/' or include '://'");
272         }
273 
274         if (_urlEncoder != null) {
275             return _urlEncoder.encodeURL(_res, path);
276         }
277         else {
278             return path;
279         }
280     }
281 
282     public long getCompanyId() {
283         return _companyId;
284     }
285 
286     public HttpServletRequest getHttpServletRequest() {
287         return _req.getHttpServletRequest();
288     }
289 
290     public HttpServletResponse getHttpServletResponse() {
291         return _res;
292     }
293 
294     public abstract String getLifecycle();
295 
296     public String getNamespace() {
297         if (_namespace == null) {
298             _namespace = PortalUtil.getPortletNamespace(_portletName);
299         }
300 
301         return _namespace;
302     }
303 
304     public long getPlid() {
305         return _plid;
306     }
307 
308     public Portlet getPortlet() {
309         if (_portlet == null) {
310             try {
311                 _portlet = PortletLocalServiceUtil.getPortletById(
312                     _companyId, _portletName);
313             }
314             catch (Exception e) {
315                 _log.error(e);
316             }
317         }
318 
319         return _portlet;
320     }
321 
322     public String getPortletName() {
323         return _portletName;
324     }
325 
326     public PortletRequestImpl getPortletRequest() {
327         return _req;
328     }
329 
330     public Map<String, String[]> getProperties() {
331         return _properties;
332     }
333 
334     public URLEncoder getUrlEncoder() {
335         return _urlEncoder;
336     }
337 
338     public void setPlid(long plid) {
339         _plid = plid;
340 
341         if (_plid <= 0) {
342             Layout layout = (Layout)_req.getAttribute(WebKeys.LAYOUT);
343 
344             if (layout != null) {
345                 _plid = layout.getPlid();
346             }
347         }
348     }
349 
350     public void setProperty(String key, String value) {
351         if (key == null) {
352             throw new IllegalArgumentException();
353         }
354 
355         if (_properties == null) {
356             _properties = new HashMap<String, String[]>();
357         }
358 
359         _properties.put(key, new String[] {value});
360     }
361 
362     public void setURLEncoder(URLEncoder urlEncoder) {
363         _urlEncoder = urlEncoder;
364     }
365 
366     protected void init(
367         PortletRequestImpl req, HttpServletResponse res, String portletName,
368         long companyId, long plid) {
369 
370         _req = req;
371         _res = res;
372         _portletName = portletName;
373         _companyId = companyId;
374         setPlid(plid);
375     }
376 
377     protected void recycle() {
378         _req = null;
379         _res = null;
380         _portletName = null;
381         _portlet = null;
382         _namespace = null;
383         _companyId = 0;
384         _plid = 0;
385     }
386 
387     private static Log _log = LogFactory.getLog(PortletResponseImpl.class);
388 
389     private PortletRequestImpl _req;
390     private HttpServletResponse _res;
391     private String _portletName;
392     private Portlet _portlet;
393     private String _namespace;
394     private long _companyId;
395     private long _plid;
396     private Map<String, String[]> _properties;
397     private URLEncoder _urlEncoder;
398 
399 }