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 layout.isPrivateLayout());
279
280 plid = linkedLayout.getPlid();
281 }
282 catch (PortalException pe) {
283 }
284 }
285 }
286 catch (SystemException se) {
287 if (_log.isWarnEnabled()) {
288 _log.warn(se);
289 }
290 }
291
292 if (plid == LayoutConstants.DEFAULT_PLID) {
293 plid = _plid;
294 }
295
296 PortletURLImpl portletURLImpl = null;
297
298 Portlet portlet = getPortlet();
299
300 String portletURLClass = portlet.getPortletURLClass();
301
302 if (portlet.getPortletId().equals(portletName) &&
303 Validator.isNotNull(portletURLClass)) {
304
305 try {
306 Constructor<? extends PortletURLImpl> constructor =
307 _constructors.get(portletURLClass);
308
309 if (constructor == null) {
310 Class<?> portletURLClassObj = Class.forName(
311 portletURLClass);
312
313 constructor = (Constructor<? extends PortletURLImpl>)
314 portletURLClassObj.getConstructor(
315 new Class[] {
316 com.liferay.portlet.PortletResponseImpl.class,
317 long.class, String.class
318 });
319
320 _constructors.put(portletURLClass, constructor);
321 }
322
323 portletURLImpl = constructor.newInstance(
324 new Object[] {this, plid, lifecycle});
325 }
326 catch (Exception e) {
327 _log.error(e);
328 }
329 }
330
331 if (portletURLImpl == null) {
332 portletURLImpl = new PortletURLImpl(
333 _portletRequestImpl, portletName, plid, lifecycle);
334 }
335
336 PortletApp portletApp = portlet.getPortletApp();
337
338 Set<PortletURLListener> portletURLListeners =
339 portletApp.getPortletURLListeners();
340
341 for (PortletURLListener portletURLListener : portletURLListeners) {
342 try {
343 PortletURLGenerationListener portletURLGenerationListener =
344 PortletURLListenerFactory.create(portletURLListener);
345
346 if (lifecycle.equals(PortletRequest.ACTION_PHASE)) {
347 portletURLGenerationListener.filterActionURL(
348 portletURLImpl);
349 }
350 else if (lifecycle.equals(PortletRequest.RENDER_PHASE)) {
351 portletURLGenerationListener.filterRenderURL(
352 portletURLImpl);
353 }
354 else if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
355 portletURLGenerationListener.filterResourceURL(
356 portletURLImpl);
357 }
358 }
359 catch (PortletException pe) {
360 _log.error(pe, pe);
361 }
362 }
363
364 try {
365 portletURLImpl.setWindowState(_portletRequestImpl.getWindowState());
366 }
367 catch (WindowStateException wse) {
368 _log.error(wse.getMessage());
369 }
370
371 try {
372 portletURLImpl.setPortletMode(_portletRequestImpl.getPortletMode());
373 }
374 catch (PortletModeException pme) {
375 _log.error(pme.getMessage());
376 }
377
378 if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
379 portletURLImpl.setCopyCurrentRenderParameters(true);
380 }
381
382 return portletURLImpl;
383 }
384
385 public LiferayPortletURL createLiferayPortletURL(String lifecycle) {
386 return createLiferayPortletURL(_portletName, lifecycle);
387 }
388
389 public LiferayPortletURL createLiferayPortletURL(
390 String portletName, String lifecycle) {
391
392 return createLiferayPortletURL(_plid, portletName, lifecycle);
393 }
394
395 public PortletURL createRenderURL() {
396 return createRenderURL(_portletName);
397 }
398
399 public LiferayPortletURL createRenderURL(String portletName) {
400 return createLiferayPortletURL(
401 portletName, PortletRequest.RENDER_PHASE);
402 }
403
404 public ResourceURL createResourceURL() {
405 return createResourceURL(_portletName);
406 }
407
408 public LiferayPortletURL createResourceURL(String portletName) {
409 return createLiferayPortletURL(
410 portletName, PortletRequest.RESOURCE_PHASE);
411 }
412
413 public String encodeURL(String path) {
414 if ((path == null) ||
415 (!path.startsWith("#") && !path.startsWith("/") &&
416 !path.contains(":
417
418
419
420 throw new IllegalArgumentException(
421 "URL path must start with a '/' or include ':
422 }
423
424 if (_urlEncoder != null) {
425 return _urlEncoder.encodeURL(_response, path);
426 }
427 else {
428 return path;
429 }
430 }
431
432 public long getCompanyId() {
433 return _companyId;
434 }
435
436 public HttpServletRequest getHttpServletRequest() {
437 return _portletRequestImpl.getHttpServletRequest();
438 }
439
440 public HttpServletResponse getHttpServletResponse() {
441 return _response;
442 }
443
444 public abstract String getLifecycle();
445
446 public String getNamespace() {
447 if (_wsrp) {
448 return "wsrp_rewrite_";
449 }
450
451 if (_namespace == null) {
452 _namespace = PortalUtil.getPortletNamespace(_portletName);
453 }
454
455 return _namespace;
456 }
457
458 public long getPlid() {
459 return _plid;
460 }
461
462 public Portlet getPortlet() {
463 if (_portlet == null) {
464 try {
465 _portlet = PortletLocalServiceUtil.getPortletById(
466 _companyId, _portletName);
467 }
468 catch (Exception e) {
469 _log.error(e);
470 }
471 }
472
473 return _portlet;
474 }
475
476 public String getPortletName() {
477 return _portletName;
478 }
479
480 public PortletRequestImpl getPortletRequest() {
481 return _portletRequestImpl;
482 }
483
484 public Map<String, String[]> getProperties() {
485 Map<String, String[]> properties =
486 new LinkedHashMap<String, String[]>();
487
488 for (Map.Entry<String, Object> entry : _headers.entrySet()) {
489 String name = entry.getKey();
490 Object[] values = (Object[])entry.getValue();
491
492 String[] valuesString = new String[values.length];
493
494 for (int i = 0; i < values.length; i++) {
495 valuesString[i] = values[i].toString();
496 }
497
498 properties.put(name, valuesString);
499 }
500
501 return properties;
502 }
503
504 public URLEncoder getUrlEncoder() {
505 return _urlEncoder;
506 }
507
508 public void setDateHeader(String name, long date) {
509 if (Validator.isNull(name)) {
510 throw new IllegalArgumentException();
511 }
512
513 if (date <= 0) {
514 _headers.remove(name);
515 }
516 else {
517 _headers.put(name, new Long[] {new Long(date)});
518 }
519 }
520
521 public void setHeader(String name, String value) {
522 if (Validator.isNull(name)) {
523 throw new IllegalArgumentException();
524 }
525
526 if (Validator.isNull(value)) {
527 _headers.remove(name);
528 }
529 else {
530 _headers.put(name, new String[] {value});
531 }
532 }
533
534 public void setIntHeader(String name, int value) {
535 if (Validator.isNull(name)) {
536 throw new IllegalArgumentException();
537 }
538
539 if (value <= 0) {
540 _headers.remove(name);
541 }
542 else {
543 _headers.put(name, new Integer[] {new Integer(value)});
544 }
545 }
546
547 public void setPlid(long plid) {
548 _plid = plid;
549
550 if (_plid <= 0) {
551 Layout layout = (Layout)_portletRequestImpl.getAttribute(
552 WebKeys.LAYOUT);
553
554 if (layout != null) {
555 _plid = layout.getPlid();
556 }
557 }
558 }
559
560 public void setProperty(String key, String value) {
561 if (key == null) {
562 throw new IllegalArgumentException();
563 }
564
565 setHeader(key, value);
566 }
567
568 public void setURLEncoder(URLEncoder urlEncoder) {
569 _urlEncoder = urlEncoder;
570 }
571
572 public void transferHeaders(HttpServletResponse response) {
573 for (Map.Entry<String, Object> entry : _headers.entrySet()) {
574 String name = entry.getKey();
575 Object values = entry.getValue();
576
577 if (values instanceof Integer[]) {
578 Integer[] intValues = (Integer[])values;
579
580 for (int value : intValues) {
581 if (response.containsHeader(name)) {
582 response.addIntHeader(name, value);
583 }
584 else {
585 response.setIntHeader(name, value);
586 }
587 }
588 }
589 else if (values instanceof Long[]) {
590 Long[] dateValues = (Long[])values;
591
592 for (long value : dateValues) {
593 if (response.containsHeader(name)) {
594 response.addDateHeader(name, value);
595 }
596 else {
597 response.setDateHeader(name, value);
598 }
599 }
600 }
601 else if (values instanceof String[]) {
602 String[] stringValues = (String[])values;
603
604 for (String value : stringValues) {
605 if (response.containsHeader(name)) {
606 response.addHeader(name, value);
607 }
608 else {
609 response.setHeader(name, value);
610 }
611 }
612 }
613 else if (values instanceof Cookie[]) {
614 Cookie[] cookies = (Cookie[])values;
615
616 for (Cookie cookie : cookies) {
617 response.addCookie(cookie);
618 }
619 }
620 }
621 }
622
623 public void transferMarkupHeadElements() {
624 List<Element> elements = _markupHeadElements.get(
625 MimeResponse.MARKUP_HEAD_ELEMENT);
626
627 if ((elements == null) || elements.isEmpty()) {
628 return;
629 }
630
631 HttpServletRequest request = getHttpServletRequest();
632
633 List<String> markupHeadElements = (List<String>)request.getAttribute(
634 MimeResponse.MARKUP_HEAD_ELEMENT);
635
636 if (markupHeadElements == null) {
637 markupHeadElements = new ArrayList<String>();
638
639 request.setAttribute(
640 MimeResponse.MARKUP_HEAD_ELEMENT, markupHeadElements);
641 }
642
643 for (Element element : elements) {
644 try {
645 Writer writer = new UnsyncStringWriter();
646
647 TransformerFactory transformerFactory =
648 TransformerFactory.newInstance();
649
650 Transformer transformer = transformerFactory.newTransformer();
651
652 transformer.setOutputProperty(
653 OutputKeys.OMIT_XML_DECLARATION, "yes");
654
655 transformer.transform(
656 new DOMSource(element), new StreamResult(writer));
657
658 markupHeadElements.add(writer.toString());
659 }
660 catch (Exception e) {
661 if (_log.isWarnEnabled()) {
662 _log.warn(e, e);
663 }
664 }
665 }
666 }
667
668 protected void init(
669 PortletRequestImpl portletRequestImpl, HttpServletResponse response,
670 String portletName, long companyId, long plid) {
671
672 _portletRequestImpl = portletRequestImpl;
673 _response = response;
674 _portletName = portletName;
675 _companyId = companyId;
676 _wsrp = ParamUtil.getBoolean(getHttpServletRequest(), "wsrp");
677
678 setPlid(plid);
679 }
680
681 private static Log _log = LogFactoryUtil.getLog(PortletResponseImpl.class);
682
683 private long _companyId;
684 private Map<String, Constructor<? extends PortletURLImpl>> _constructors =
685 new ConcurrentHashMap<String, Constructor<? extends PortletURLImpl>>();
686 private Document _document;
687 private Map<String, Object> _headers = new LinkedHashMap<String, Object>();
688 private Map<String, List<Element>> _markupHeadElements =
689 new LinkedHashMap<String, List<Element>>();
690 private String _namespace;
691 private long _plid;
692 private Portlet _portlet;
693 private String _portletName;
694 private PortletRequestImpl _portletRequestImpl;
695 private PortletPreferences _portletSetup;
696 private HttpServletResponse _response;
697 private URLEncoder _urlEncoder;
698 private boolean _wsrp;
699
700 }