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