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