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