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