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.LiferayRenderResponse;
28  import com.liferay.portal.kernel.portlet.LiferayWindowState;
29  import com.liferay.portal.kernel.servlet.URLEncoder;
30  import com.liferay.portal.kernel.util.ArrayUtil;
31  import com.liferay.portal.kernel.util.GetterUtil;
32  import com.liferay.portal.kernel.util.Validator;
33  import com.liferay.portal.model.Layout;
34  import com.liferay.portal.model.Portlet;
35  import com.liferay.portal.service.PortletLocalServiceUtil;
36  import com.liferay.portal.theme.PortletDisplay;
37  import com.liferay.portal.theme.ThemeDisplay;
38  import com.liferay.portal.util.PortalUtil;
39  import com.liferay.portal.util.WebKeys;
40  import com.liferay.util.CollectionFactory;
41  
42  import java.io.IOException;
43  import java.io.OutputStream;
44  import java.io.PrintWriter;
45  
46  import java.lang.reflect.Constructor;
47  
48  import java.util.Enumeration;
49  import java.util.Iterator;
50  import java.util.LinkedHashMap;
51  import java.util.Locale;
52  import java.util.Map;
53  
54  import javax.portlet.PortletModeException;
55  import javax.portlet.PortletPreferences;
56  import javax.portlet.PortletURL;
57  import javax.portlet.WindowStateException;
58  
59  import javax.servlet.http.HttpServletResponse;
60  
61  import org.apache.commons.logging.Log;
62  import org.apache.commons.logging.LogFactory;
63  
64  /**
65   * <a href="RenderResponseImpl.java.html"><b><i>View Source</i></b></a>
66   *
67   * @author Brian Wing Shun Chan
68   *
69   */
70  public class RenderResponseImpl implements LiferayRenderResponse {
71  
72      public void addProperty(String key, String value) {
73      }
74  
75      public void setProperty(String key, String value) {
76          if (_properties == null) {
77              _properties = CollectionFactory.getHashMap();
78          }
79  
80          _properties.put(key, new String[] {value});
81      }
82  
83      public PortletURL createPortletURL(boolean action) {
84          return createPortletURL(_portletName, action);
85      }
86  
87      public PortletURL createPortletURL(String portletName, boolean action) {
88  
89          // Wrap portlet URL with a custom wrapper if and only if a custom
90          // wrapper for the portlet has been defined
91  
92          Portlet portlet = getPortlet();
93  
94          String portletURLClass = portlet.getPortletURLClass();
95  
96          if (portlet.getPortletId().equals(portletName) &&
97                  Validator.isNotNull(portletURLClass)) {
98  
99              try {
100                 Class portletURLClassObj = Class.forName(portletURLClass);
101 
102                 Constructor constructor = portletURLClassObj.getConstructor(
103                     new Class[] {
104                         com.liferay.portlet.RenderResponseImpl.class,
105                         boolean.class
106                     });
107 
108                 return (PortletURL)constructor.newInstance(
109                     new Object[] {this, Boolean.valueOf(action)});
110             }
111             catch (Exception e) {
112                 _log.error(e);
113             }
114         }
115 
116         long plid = _plid;
117 
118         try {
119             PortletPreferences portletSetup =
120                 PortletPreferencesFactoryUtil.getPortletSetup(
121                     _req, _portletName, true, true);
122 
123             plid = GetterUtil.getLong(portletSetup.getValue(
124                 "portlet-setup-link-to-plid", String.valueOf(_plid)));
125 
126             if (plid <= 0) {
127                 plid = _plid;
128             }
129         }
130         catch (PortalException e) {
131             if (_log.isWarnEnabled()) {
132                 _log.warn(e);
133             }
134         }
135         catch (SystemException e) {
136             if (_log.isWarnEnabled()) {
137                 _log.warn(e);
138             }
139         }
140 
141         return new PortletURLImpl(_req, portletName, plid, action);
142     }
143 
144     public PortletURL createActionURL() {
145         return createActionURL(_portletName);
146     }
147 
148     public PortletURL createActionURL(String portletName) {
149         PortletURL portletURL = createPortletURL(portletName, true);
150 
151         try {
152             portletURL.setWindowState(_req.getWindowState());
153         }
154         catch (WindowStateException wse) {
155         }
156 
157         try {
158             portletURL.setPortletMode(_req.getPortletMode());
159         }
160         catch (PortletModeException pme) {
161         }
162 
163         return portletURL;
164     }
165 
166     public PortletURL createRenderURL() {
167         return createRenderURL(_portletName);
168     }
169 
170     public PortletURL createRenderURL(String portletName) {
171         PortletURL portletURL = createPortletURL(portletName, false);
172 
173         try {
174             portletURL.setWindowState(_req.getWindowState());
175         }
176         catch (WindowStateException wse) {
177         }
178 
179         try {
180             portletURL.setPortletMode(_req.getPortletMode());
181         }
182         catch (PortletModeException pme) {
183         }
184 
185         return portletURL;
186     }
187 
188     public String getNamespace() {
189         if (_namespace == null) {
190             _namespace = PortalUtil.getPortletNamespace(_portletName);
191         }
192 
193         return _namespace;
194     }
195 
196     public void setURLEncoder(URLEncoder urlEncoder) {
197         _urlEncoder = urlEncoder;
198     }
199 
200     public String encodeURL(String path) {
201         if ((path == null) ||
202             (!path.startsWith("#") && !path.startsWith("/") &&
203                 (path.indexOf("://") == -1))) {
204 
205             // Allow '#' as well to workaround a bug in Oracle ADF 10.1.3
206 
207             throw new IllegalArgumentException(
208                 "URL path must start with a '/' or include '://'");
209         }
210 
211         if (_urlEncoder != null) {
212             return _urlEncoder.encodeURL(_res, path);
213         }
214         else {
215             return path;
216         }
217     }
218 
219     public String getCharacterEncoding() {
220         return _res.getCharacterEncoding();
221     }
222 
223     public String getContentType() {
224         return _contentType;
225     }
226 
227     public void setContentType(String contentType) {
228         if (Validator.isNull(contentType)) {
229             throw new IllegalArgumentException();
230         }
231 
232         Enumeration enu = _req.getResponseContentTypes();
233 
234         boolean valid = false;
235 
236         while (enu.hasMoreElements()) {
237             String resContentType = (String)enu.nextElement();
238 
239             if (contentType.startsWith(resContentType)) {
240                 valid = true;
241 
242                 break;
243             }
244         }
245 
246         if (_req.getWindowState().equals(LiferayWindowState.EXCLUSIVE)) {
247             valid = true;
248         }
249 
250         if (!valid) {
251             throw new IllegalArgumentException();
252         }
253 
254         _contentType = contentType;
255     }
256 
257     public Locale getLocale() {
258         return _req.getLocale();
259     }
260 
261     public OutputStream getPortletOutputStream() throws IOException {
262         if (_calledGetWriter) {
263             throw new IllegalStateException();
264         }
265 
266         if (_contentType == null) {
267             throw new IllegalStateException();
268         }
269 
270         _calledGetPortletOutputStream = true;
271 
272         return _res.getOutputStream();
273     }
274 
275     public String getTitle() {
276         return _title;
277     }
278 
279     public void setTitle(String title) {
280         _title = title;
281 
282         // See LEP-2188
283 
284         ThemeDisplay themeDisplay =
285             (ThemeDisplay)_req.getAttribute(WebKeys.THEME_DISPLAY);
286 
287         PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
288 
289         portletDisplay.setTitle(_title);
290     }
291 
292     public Boolean getUseDefaultTemplate() {
293         return _useDefaultTemplate;
294     }
295 
296     public void setUseDefaultTemplate(Boolean useDefaultTemplate) {
297         _useDefaultTemplate = useDefaultTemplate;
298     }
299 
300     public PrintWriter getWriter() throws IOException {
301         if (_calledGetPortletOutputStream) {
302             throw new IllegalStateException();
303         }
304 
305         if (_contentType == null) {
306             throw new IllegalStateException();
307         }
308 
309         _calledGetWriter = true;
310 
311         return _res.getWriter();
312     }
313 
314     public int getBufferSize() {
315         return _res.getBufferSize();
316     }
317 
318     public void setBufferSize(int size) {
319         _res.setBufferSize(size);
320     }
321 
322     public void flushBuffer() throws IOException {
323         _res.flushBuffer();
324     }
325 
326     public void resetBuffer() {
327         _res.resetBuffer();
328     }
329 
330     public boolean isCommitted() {
331         return false;
332     }
333 
334     public void reset() {
335     }
336 
337     public HttpServletResponse getHttpServletResponse() {
338         return _res;
339     }
340 
341     public Portlet getPortlet() {
342         if (_portlet == null) {
343             try {
344                 _portlet = PortletLocalServiceUtil.getPortletById(
345                     _companyId, _portletName);
346             }
347             catch (Exception e) {
348                 _log.error(e);
349             }
350         }
351 
352         return _portlet;
353     }
354 
355     public void addDateHeader(String name, long date) {
356         if (Validator.isNull(name)) {
357             throw new IllegalArgumentException();
358         }
359 
360         if (_headers.containsKey(name)) {
361             Long[] values = (Long[])_headers.get(name);
362 
363             ArrayUtil.append(values, new Long(date));
364 
365             _headers.put(name, values);
366         }
367         else {
368             setDateHeader(name, date);
369         }
370     }
371 
372     public void setDateHeader(String name, long date) {
373         if (Validator.isNull(name)) {
374             throw new IllegalArgumentException();
375         }
376 
377         if (date <= 0) {
378             _headers.remove(name);
379         }
380         else {
381             _headers.put(name, new Long[] {new Long(date)});
382         }
383     }
384 
385     public void addHeader(String name, String value) {
386         if (Validator.isNull(name)) {
387             throw new IllegalArgumentException();
388         }
389 
390         if (_headers.containsKey(name)) {
391             String[] values = (String[])_headers.get(name);
392 
393             ArrayUtil.append(values, value);
394 
395             _headers.put(name, values);
396         }
397         else {
398             setHeader(name, value);
399         }
400     }
401 
402     public void setHeader(String name, String value) {
403         if (Validator.isNull(name)) {
404             throw new IllegalArgumentException();
405         }
406 
407         if (Validator.isNull(value)) {
408             _headers.remove(name);
409         }
410         else {
411             _headers.put(name, new String[] {value});
412         }
413     }
414 
415     public void addIntHeader(String name, int value) {
416         if (Validator.isNull(name)) {
417             throw new IllegalArgumentException();
418         }
419 
420         if (_headers.containsKey(name)) {
421             Integer[] values = (Integer[])_headers.get(name);
422 
423             ArrayUtil.append(values, new Integer(value));
424 
425             _headers.put(name, values);
426         }
427         else {
428             setIntHeader(name, value);
429         }
430     }
431 
432     public void setIntHeader(String name, int value) {
433         if (Validator.isNull(name)) {
434             throw new IllegalArgumentException();
435         }
436 
437         if (value <= 0) {
438             _headers.remove(name);
439         }
440         else {
441             _headers.put(name, new Integer[] {new Integer(value)});
442         }
443     }
444 
445     public String getResourceName() {
446         return _resourceName;
447     }
448 
449     public void setResourceName(String resourceName) {
450         _resourceName = resourceName;
451     }
452 
453     public void transferHeaders(HttpServletResponse res) {
454         Iterator itr = _headers.entrySet().iterator();
455 
456         while (itr.hasNext()) {
457             Map.Entry entry = (Map.Entry)itr.next();
458 
459             String name = (String)entry.getKey();
460             Object values = entry.getValue();
461 
462             if (values instanceof Integer[]) {
463                 Integer[] intValues = (Integer[])values;
464 
465                 for (int i = 0; i < intValues.length; i++) {
466                     if (res.containsHeader(name)) {
467                         res.addIntHeader(name, intValues[i].intValue());
468                     }
469                     else {
470                         res.addIntHeader(name, intValues[i].intValue());
471                     }
472                 }
473             }
474             else if (values instanceof Long[]) {
475                 Long[] dateValues = (Long[])values;
476 
477                 for (int i = 0; i < dateValues.length; i++) {
478                     if (res.containsHeader(name)) {
479                         res.addDateHeader(name, dateValues[i].longValue());
480                     }
481                     else {
482                         res.addDateHeader(name, dateValues[i].longValue());
483                     }
484                 }
485             }
486             else if (values instanceof String[]) {
487                 String[] stringValues = (String[])values;
488 
489                 for (int i = 0; i < stringValues.length; i++) {
490                     if (res.containsHeader(name)) {
491                         res.addHeader(name, stringValues[i]);
492                     }
493                     else {
494                         res.addHeader(name, stringValues[i]);
495                     }
496                 }
497             }
498         }
499     }
500 
501     protected RenderResponseImpl() {
502         if (_log.isDebugEnabled()) {
503             _log.debug("Creating new instance " + hashCode());
504         }
505     }
506 
507     protected void init(
508         RenderRequestImpl req, HttpServletResponse res, String portletName,
509         long companyId, long plid) {
510 
511         _req = req;
512         _res = res;
513         _portletName = portletName;
514         _companyId = companyId;
515         setPlid(plid);
516         _headers.clear();
517     }
518 
519     protected void recycle() {
520         if (_log.isDebugEnabled()) {
521             _log.debug("Recycling instance " + hashCode());
522         }
523 
524         _req = null;
525         _res = null;
526         _portletName = null;
527         _portlet = null;
528         _namespace = null;
529         _companyId = 0;
530         _plid = 0;
531         _urlEncoder = null;
532         _title = null;
533         _useDefaultTemplate = null;
534         _contentType = null;
535         _calledGetPortletOutputStream = false;
536         _calledGetWriter = false;
537         _headers = null;
538         _resourceName = null;
539     }
540 
541     protected RenderRequestImpl getReq() {
542         return _req;
543     }
544 
545     protected String getPortletName() {
546         return _portletName;
547     }
548 
549     protected long getCompanyId() {
550         return _companyId;
551     }
552 
553     protected long getPlid() {
554         return _plid;
555     }
556 
557     protected void setPlid(long plid) {
558         _plid = plid;
559 
560         if (_plid <= 0) {
561             Layout layout = (Layout)_req.getAttribute(WebKeys.LAYOUT);
562 
563             if (layout != null) {
564                 _plid = layout.getPlid();
565             }
566         }
567     }
568 
569     protected Map getProperties() {
570         return _properties;
571     }
572 
573     protected URLEncoder getUrlEncoder() {
574         return _urlEncoder;
575     }
576 
577     protected boolean isCalledGetPortletOutputStream() {
578         return _calledGetPortletOutputStream;
579     }
580 
581     protected boolean isCalledGetWriter() {
582         return _calledGetWriter;
583     }
584 
585     private static Log _log = LogFactory.getLog(RenderRequestImpl.class);
586 
587     private RenderRequestImpl _req;
588     private HttpServletResponse _res;
589     private String _portletName;
590     private Portlet _portlet;
591     private String _namespace;
592     private long _companyId;
593     private long _plid;
594     private Map _properties;
595     private URLEncoder _urlEncoder;
596     private String _title;
597     private Boolean _useDefaultTemplate;
598     private String _contentType;
599     private boolean _calledGetPortletOutputStream;
600     private boolean _calledGetWriter;
601     private LinkedHashMap _headers = new LinkedHashMap();
602     private String _resourceName;
603 
604 }