1
14
15 package com.liferay.portlet;
16
17 import com.liferay.portal.PortalException;
18 import com.liferay.portal.SystemException;
19 import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
20 import com.liferay.portal.kernel.log.Log;
21 import com.liferay.portal.kernel.log.LogFactoryUtil;
22 import com.liferay.portal.kernel.portlet.LiferayPortletResponse;
23 import com.liferay.portal.kernel.portlet.LiferayPortletURL;
24 import com.liferay.portal.kernel.servlet.URLEncoder;
25 import com.liferay.portal.kernel.util.ArrayUtil;
26 import com.liferay.portal.kernel.util.GetterUtil;
27 import com.liferay.portal.kernel.util.ParamUtil;
28 import com.liferay.portal.kernel.util.Validator;
29 import com.liferay.portal.model.Layout;
30 import com.liferay.portal.model.LayoutConstants;
31 import com.liferay.portal.model.Portlet;
32 import com.liferay.portal.model.PortletApp;
33 import com.liferay.portal.model.PortletURLListener;
34 import com.liferay.portal.service.LayoutLocalServiceUtil;
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.io.Writer;
40
41 import java.lang.reflect.Constructor;
42 import java.lang.reflect.Method;
43
44 import java.util.ArrayList;
45 import java.util.LinkedHashMap;
46 import java.util.List;
47 import java.util.Map;
48 import java.util.Set;
49
50 import javax.portlet.MimeResponse;
51 import javax.portlet.PortletException;
52 import javax.portlet.PortletModeException;
53 import javax.portlet.PortletPreferences;
54 import javax.portlet.PortletRequest;
55 import javax.portlet.PortletResponse;
56 import javax.portlet.PortletURL;
57 import javax.portlet.PortletURLGenerationListener;
58 import javax.portlet.ResourceURL;
59 import javax.portlet.WindowStateException;
60
61 import javax.servlet.http.Cookie;
62 import javax.servlet.http.HttpServletRequest;
63 import javax.servlet.http.HttpServletResponse;
64
65 import javax.xml.parsers.DocumentBuilder;
66 import javax.xml.parsers.DocumentBuilderFactory;
67 import javax.xml.parsers.ParserConfigurationException;
68 import javax.xml.transform.OutputKeys;
69 import javax.xml.transform.Transformer;
70 import javax.xml.transform.TransformerFactory;
71 import javax.xml.transform.dom.DOMSource;
72 import javax.xml.transform.stream.StreamResult;
73
74 import org.w3c.dom.DOMException;
75 import org.w3c.dom.Document;
76 import org.w3c.dom.Element;
77
78
83 public abstract class PortletResponseImpl implements LiferayPortletResponse {
84
85 public static PortletResponseImpl getPortletResponseImpl(
86 PortletResponse portletResponse) {
87
88 PortletResponseImpl portletResponseImpl = null;
89
90 if (portletResponse instanceof PortletResponseImpl) {
91 portletResponseImpl = (PortletResponseImpl)portletResponse;
92 }
93 else {
94
95
97 try {
98 Method method = portletResponse.getClass().getMethod(
99 "getResponse");
100
101 Object obj = method.invoke(portletResponse, (Object[])null);
102
103 portletResponseImpl = getPortletResponseImpl(
104 (PortletResponse)obj);
105 }
106 catch (Exception e) {
107 throw new RuntimeException(
108 "Unable to get the portlet response from " +
109 portletResponse.getClass().getName());
110 }
111 }
112
113 return portletResponseImpl;
114 }
115
116 public void addDateHeader(String name, long date) {
117 if (Validator.isNull(name)) {
118 throw new IllegalArgumentException();
119 }
120
121 Long[] values = (Long[])_headers.get(name);
122
123 if (values == null) {
124 setDateHeader(name, date);
125 }
126 else {
127 values = ArrayUtil.append(values, new Long(date));
128
129 _headers.put(name, values);
130 }
131 }
132
133 public void addHeader(String name, String value) {
134 if (Validator.isNull(name)) {
135 throw new IllegalArgumentException();
136 }
137
138 String[] values = (String[])_headers.get(name);
139
140 if (values == null) {
141 setHeader(name, value);
142 }
143 else {
144 values = ArrayUtil.append(values, value);
145
146 _headers.put(name, values);
147 }
148 }
149
150 public void addIntHeader(String name, int value) {
151 if (Validator.isNull(name)) {
152 throw new IllegalArgumentException();
153 }
154
155 Integer[] values = (Integer[])_headers.get(name);
156
157 if (values == null) {
158 setIntHeader(name, value);
159 }
160 else {
161 values = ArrayUtil.append(values, new Integer(value));
162
163 _headers.put(name, values);
164 }
165 }
166
167 public void addProperty(Cookie cookie) {
168 if (cookie == null) {
169 throw new IllegalArgumentException();
170 }
171
172 Cookie[] cookies = (Cookie[])_headers.get("cookies");
173
174 if (cookies == null) {
175 _headers.put("cookies", new Cookie[] {cookie});
176 }
177 else {
178 cookies = ArrayUtil.append(cookies, cookie);
179
180 _headers.put("cookies", cookies);
181 }
182 }
183
184 public void addProperty(String key, Element element) {
185 if (key == null) {
186 throw new IllegalArgumentException();
187 }
188
189 if (key.equalsIgnoreCase(MimeResponse.MARKUP_HEAD_ELEMENT)) {
190 List<Element> values = _markupHeadElements.get(key);
191
192 if (values != null) {
193 if (element != null) {
194 values.add(element);
195 }
196 else {
197 _markupHeadElements.remove(key);
198 }
199 }
200 else {
201 if (element != null) {
202 values = new ArrayList<Element>();
203
204 values.add(element);
205
206 _markupHeadElements.put(key, values);
207 }
208 }
209 }
210 }
211
212 public void addProperty(String key, String value) {
213 if (Validator.isNull(key)) {
214 throw new IllegalArgumentException();
215 }
216
217 addHeader(key, value);
218 }
219
220 public PortletURL createActionURL() {
221 return createActionURL(_portletName);
222 }
223
224 public LiferayPortletURL createActionURL(String portletName) {
225 return createLiferayPortletURL(
226 portletName, PortletRequest.ACTION_PHASE);
227 }
228
229 public Element createElement(String tagName) throws DOMException {
230 if (_document == null) {
231 try {
232 DocumentBuilderFactory documentBuilderFactory =
233 DocumentBuilderFactory.newInstance();
234
235 DocumentBuilder documentBuilder =
236 documentBuilderFactory.newDocumentBuilder();
237
238 _document = documentBuilder.newDocument();
239 }
240 catch (ParserConfigurationException pce) {
241 throw new DOMException(
242 DOMException.INVALID_STATE_ERR, pce.getMessage());
243 }
244 }
245
246 return _document.createElement(tagName);
247 }
248
249 public LiferayPortletURL createLiferayPortletURL(
250 long plid, String portletName, String lifecycle) {
251
252 try {
253 Layout layout = (Layout)_portletRequestImpl.getAttribute(
254 WebKeys.LAYOUT);
255
256 PortletPreferences portletSetup =
257 PortletPreferencesFactoryUtil.getLayoutPortletSetup(
258 layout, _portletName);
259
260 long layoutId = GetterUtil.getLong(portletSetup.getValue(
261 "portlet-setup-link-to-layout-id", null));
262
263 if (layoutId > 0) {
264 try {
265 Layout linkedLayout = LayoutLocalServiceUtil.getLayout(
266 layout.getGroupId(), layout.isPrivateLayout(),
267 layoutId);
268
269 plid = linkedLayout.getPlid();
270 }
271 catch (PortalException pe) {
272 }
273 }
274 else {
275
276
278 plid = GetterUtil.getLong(portletSetup.getValue(
279 "portlet-setup-link-to-plid", String.valueOf(plid)));
280 }
281 }
282 catch (SystemException e) {
283 if (_log.isWarnEnabled()) {
284 _log.warn(e);
285 }
286 }
287
288 if (plid == LayoutConstants.DEFAULT_PLID) {
289 plid = _plid;
290 }
291
292 PortletURLImpl portletURLImpl = null;
293
294 Portlet portlet = getPortlet();
295
296 String portletURLClass = portlet.getPortletURLClass();
297
298 if (portlet.getPortletId().equals(portletName) &&
299 Validator.isNotNull(portletURLClass)) {
300
301 try {
302 Class<?> portletURLClassObj = Class.forName(portletURLClass);
303
304 Constructor<?> constructor = portletURLClassObj.getConstructor(
305 new Class[] {
306 com.liferay.portlet.PortletResponseImpl.class,
307 long.class, String.class
308 });
309
310 portletURLImpl = (PortletURLImpl)constructor.newInstance(
311 new Object[] {this, plid, lifecycle});
312 }
313 catch (Exception e) {
314 _log.error(e);
315 }
316 }
317
318 if (portletURLImpl == null) {
319 portletURLImpl = new PortletURLImpl(
320 _portletRequestImpl, portletName, plid, lifecycle);
321 }
322
323 PortletApp portletApp = portlet.getPortletApp();
324
325 Set<PortletURLListener> portletURLListeners =
326 portletApp.getPortletURLListeners();
327
328 for (PortletURLListener portletURLListener : portletURLListeners) {
329 try {
330 PortletURLGenerationListener portletURLGenerationListener =
331 PortletURLListenerFactory.create(portletURLListener);
332
333 if (lifecycle.equals(PortletRequest.ACTION_PHASE)) {
334 portletURLGenerationListener.filterActionURL(
335 portletURLImpl);
336 }
337 else if (lifecycle.equals(PortletRequest.RENDER_PHASE)) {
338 portletURLGenerationListener.filterRenderURL(
339 portletURLImpl);
340 }
341 else if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
342 portletURLGenerationListener.filterResourceURL(
343 portletURLImpl);
344 }
345 }
346 catch (PortletException pe) {
347 _log.error(pe, pe);
348 }
349 }
350
351 try {
352 portletURLImpl.setWindowState(_portletRequestImpl.getWindowState());
353 }
354 catch (WindowStateException wse) {
355 _log.error(wse.getMessage());
356 }
357
358 try {
359 portletURLImpl.setPortletMode(_portletRequestImpl.getPortletMode());
360 }
361 catch (PortletModeException pme) {
362 _log.error(pme.getMessage());
363 }
364
365 if (lifecycle.equals(PortletRequest.ACTION_PHASE)) {
366 portletURLImpl.setCopyCurrentPublicRenderParameters(true);
367 }
368
369 if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
370 portletURLImpl.setCopyCurrentPublicRenderParameters(true);
371 portletURLImpl.setCopyCurrentRenderParameters(true);
372 }
373
374 return portletURLImpl;
375 }
376
377 public LiferayPortletURL createLiferayPortletURL(String lifecycle) {
378 return createLiferayPortletURL(_portletName, lifecycle);
379 }
380
381 public LiferayPortletURL createLiferayPortletURL(
382 String portletName, String lifecycle) {
383
384 return createLiferayPortletURL(_plid, portletName, lifecycle);
385 }
386
387 public PortletURL createRenderURL() {
388 return createRenderURL(_portletName);
389 }
390
391 public LiferayPortletURL createRenderURL(String portletName) {
392 return createLiferayPortletURL(
393 portletName, PortletRequest.RENDER_PHASE);
394 }
395
396 public ResourceURL createResourceURL() {
397 return createResourceURL(_portletName);
398 }
399
400 public LiferayPortletURL createResourceURL(String portletName) {
401 return createLiferayPortletURL(
402 portletName, PortletRequest.RESOURCE_PHASE);
403 }
404
405 public String encodeURL(String path) {
406 if ((path == null) ||
407 (!path.startsWith("#") && !path.startsWith("/") &&
408 (path.indexOf("://") == -1))) {
409
410
412 throw new IllegalArgumentException(
413 "URL path must start with a '/' or include '://'");
414 }
415
416 if (_urlEncoder != null) {
417 return _urlEncoder.encodeURL(_response, path);
418 }
419 else {
420 return path;
421 }
422 }
423
424 public long getCompanyId() {
425 return _companyId;
426 }
427
428 public HttpServletRequest getHttpServletRequest() {
429 return _portletRequestImpl.getHttpServletRequest();
430 }
431
432 public HttpServletResponse getHttpServletResponse() {
433 return _response;
434 }
435
436 public abstract String getLifecycle();
437
438 public String getNamespace() {
439 if (_wsrp) {
440 return "wsrp_rewrite_";
441 }
442
443 if (_namespace == null) {
444 _namespace = PortalUtil.getPortletNamespace(_portletName);
445 }
446
447 return _namespace;
448 }
449
450 public long getPlid() {
451 return _plid;
452 }
453
454 public Portlet getPortlet() {
455 if (_portlet == null) {
456 try {
457 _portlet = PortletLocalServiceUtil.getPortletById(
458 _companyId, _portletName);
459 }
460 catch (Exception e) {
461 _log.error(e);
462 }
463 }
464
465 return _portlet;
466 }
467
468 public String getPortletName() {
469 return _portletName;
470 }
471
472 public PortletRequestImpl getPortletRequest() {
473 return _portletRequestImpl;
474 }
475
476 public Map<String, String[]> getProperties() {
477 Map<String, String[]> properties =
478 new LinkedHashMap<String, String[]>();
479
480 for (Map.Entry<String, Object> entry : _headers.entrySet()) {
481 String name = entry.getKey();
482 Object[] values = (Object[])entry.getValue();
483
484 String[] valuesString = new String[values.length];
485
486 for (int i = 0; i < values.length; i++) {
487 valuesString[i] = values[i].toString();
488 }
489
490 properties.put(name, valuesString);
491 }
492
493 return properties;
494 }
495
496 public URLEncoder getUrlEncoder() {
497 return _urlEncoder;
498 }
499
500 public void setDateHeader(String name, long date) {
501 if (Validator.isNull(name)) {
502 throw new IllegalArgumentException();
503 }
504
505 if (date <= 0) {
506 _headers.remove(name);
507 }
508 else {
509 _headers.put(name, new Long[] {new Long(date)});
510 }
511 }
512
513 public void setHeader(String name, String value) {
514 if (Validator.isNull(name)) {
515 throw new IllegalArgumentException();
516 }
517
518 if (Validator.isNull(value)) {
519 _headers.remove(name);
520 }
521 else {
522 _headers.put(name, new String[] {value});
523 }
524 }
525
526 public void setIntHeader(String name, int value) {
527 if (Validator.isNull(name)) {
528 throw new IllegalArgumentException();
529 }
530
531 if (value <= 0) {
532 _headers.remove(name);
533 }
534 else {
535 _headers.put(name, new Integer[] {new Integer(value)});
536 }
537 }
538
539 public void setPlid(long plid) {
540 _plid = plid;
541
542 if (_plid <= 0) {
543 Layout layout = (Layout)_portletRequestImpl.getAttribute(
544 WebKeys.LAYOUT);
545
546 if (layout != null) {
547 _plid = layout.getPlid();
548 }
549 }
550 }
551
552 public void setProperty(String key, String value) {
553 if (key == null) {
554 throw new IllegalArgumentException();
555 }
556
557 setHeader(key, value);
558 }
559
560 public void setURLEncoder(URLEncoder urlEncoder) {
561 _urlEncoder = urlEncoder;
562 }
563
564 public void transferHeaders(HttpServletResponse response) {
565 for (Map.Entry<String, Object> entry : _headers.entrySet()) {
566 String name = entry.getKey();
567 Object values = entry.getValue();
568
569 if (values instanceof Integer[]) {
570 Integer[] intValues = (Integer[])values;
571
572 for (int value : intValues) {
573 if (response.containsHeader(name)) {
574 response.addIntHeader(name, value);
575 }
576 else {
577 response.setIntHeader(name, value);
578 }
579 }
580 }
581 else if (values instanceof Long[]) {
582 Long[] dateValues = (Long[])values;
583
584 for (long value : dateValues) {
585 if (response.containsHeader(name)) {
586 response.addDateHeader(name, value);
587 }
588 else {
589 response.setDateHeader(name, value);
590 }
591 }
592 }
593 else if (values instanceof String[]) {
594 String[] stringValues = (String[])values;
595
596 for (String value : stringValues) {
597 if (response.containsHeader(name)) {
598 response.addHeader(name, value);
599 }
600 else {
601 response.setHeader(name, value);
602 }
603 }
604 }
605 else if (values instanceof Cookie[]) {
606 Cookie[] cookies = (Cookie[])values;
607
608 for (Cookie cookie : cookies) {
609 response.addCookie(cookie);
610 }
611 }
612 }
613 }
614
615 public void transferMarkupHeadElements() {
616 List<Element> elements = _markupHeadElements.get(
617 MimeResponse.MARKUP_HEAD_ELEMENT);
618
619 if ((elements == null) || elements.isEmpty()) {
620 return;
621 }
622
623 HttpServletRequest request = getHttpServletRequest();
624
625 List<String> markupHeadElements = (List<String>)request.getAttribute(
626 MimeResponse.MARKUP_HEAD_ELEMENT);
627
628 if (markupHeadElements == null) {
629 markupHeadElements = new ArrayList<String>();
630
631 request.setAttribute(
632 MimeResponse.MARKUP_HEAD_ELEMENT, markupHeadElements);
633 }
634
635 for (Element element : elements) {
636 try {
637 Writer writer = new UnsyncStringWriter();
638
639 TransformerFactory transformerFactory =
640 TransformerFactory.newInstance();
641
642 Transformer transformer = transformerFactory.newTransformer();
643
644 transformer.setOutputProperty(
645 OutputKeys.OMIT_XML_DECLARATION, "yes");
646
647 transformer.transform(
648 new DOMSource(element), new StreamResult(writer));
649
650 markupHeadElements.add(writer.toString());
651 }
652 catch (Exception e) {
653 if (_log.isWarnEnabled()) {
654 _log.warn(e, e);
655 }
656 }
657 }
658 }
659
660 protected void init(
661 PortletRequestImpl portletRequestImpl, HttpServletResponse response,
662 String portletName, long companyId, long plid) {
663
664 _portletRequestImpl = portletRequestImpl;
665 _response = response;
666 _portletName = portletName;
667 _companyId = companyId;
668 _wsrp = ParamUtil.getBoolean(getHttpServletRequest(), "wsrp");
669
670 setPlid(plid);
671 }
672
673 private static Log _log = LogFactoryUtil.getLog(PortletResponseImpl.class);
674
675 private long _companyId;
676 private Document _document;
677 private Map<String, Object> _headers = new LinkedHashMap<String, Object>();
678 private Map<String, List<Element>> _markupHeadElements =
679 new LinkedHashMap<String, List<Element>>();
680 private String _namespace;
681 private long _plid;
682 private Portlet _portlet;
683 private String _portletName;
684 private PortletRequestImpl _portletRequestImpl;
685 private HttpServletResponse _response;
686 private URLEncoder _urlEncoder;
687 private boolean _wsrp;
688
689 }