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 PortletPreferences portletSetup =
256 PortletPreferencesFactoryUtil.getStrictLayoutPortletSetup(
257 layout, _portletName);
258
259 String linkToLayoutUuid = GetterUtil.getString(
260 portletSetup.getValue("portletSetupLinkToLayoutUuid", null));
261
262 if (Validator.isNotNull(linkToLayoutUuid)) {
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 e) {
275 if (_log.isWarnEnabled()) {
276 _log.warn(e);
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.indexOf(":
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 HttpServletResponse _response;
684 private URLEncoder _urlEncoder;
685 private boolean _wsrp;
686
687 }