001
014
015 package com.liferay.portal.kernel.servlet;
016
017 import com.liferay.portal.kernel.util.CharPool;
018 import com.liferay.portal.kernel.util.StringBundler;
019 import com.liferay.portal.kernel.util.StringPool;
020
021 import java.io.IOException;
022 import java.io.PrintWriter;
023 import java.io.Serializable;
024
025 import java.util.ArrayList;
026 import java.util.Collection;
027 import java.util.Collections;
028 import java.util.HashMap;
029 import java.util.HashSet;
030 import java.util.List;
031 import java.util.Locale;
032 import java.util.Map;
033 import java.util.Set;
034
035 import javax.servlet.ServletOutputStream;
036 import javax.servlet.ServletResponse;
037 import javax.servlet.http.Cookie;
038 import javax.servlet.http.HttpServletResponse;
039 import javax.servlet.http.HttpServletResponseWrapper;
040
041
044 public class MetaInfoCacheServletResponse extends HttpServletResponseWrapper {
045
046 @SuppressWarnings("deprecation")
047 public static void finishResponse(
048 MetaData metaInfoDataBag, HttpServletResponse response)
049 throws IOException {
050
051 if (response.isCommitted()) {
052 return;
053 }
054
055 for (Map.Entry<String, Set<Header>> entry :
056 metaInfoDataBag._headers.entrySet()) {
057
058 String key = entry.getKey();
059
060 boolean first = true;
061
062 for (Header header : entry.getValue()) {
063 if (first) {
064 header.setToResponse(key, response);
065
066 first = false;
067 }
068 else {
069 header.addToResponse(key, response);
070 }
071 }
072 }
073
074 if (metaInfoDataBag._location != null) {
075 response.sendRedirect(metaInfoDataBag._location);
076 }
077 else if (metaInfoDataBag._error) {
078 response.sendError(
079 metaInfoDataBag._status, metaInfoDataBag._errorMessage);
080 }
081 else {
082 if (metaInfoDataBag._charsetName != null) {
083 response.setCharacterEncoding(metaInfoDataBag._charsetName);
084 }
085
086 if (metaInfoDataBag._contentLength != -1) {
087 response.setContentLength(metaInfoDataBag._contentLength);
088 }
089
090 if (metaInfoDataBag._contentType != null) {
091 response.setContentType(metaInfoDataBag._contentType);
092 }
093
094 if (metaInfoDataBag._locale != null) {
095 response.setLocale(metaInfoDataBag._locale);
096 }
097
098 if (metaInfoDataBag._status != SC_OK) {
099 response.setStatus(
100 metaInfoDataBag._status, metaInfoDataBag._statusMessage);
101 }
102 }
103 }
104
105 public MetaInfoCacheServletResponse(HttpServletResponse response) {
106 super(response);
107 }
108
109 @Override
110 public void addCookie(Cookie cookie) {
111
112
113
114
115
116 Set<Header> values = _metaData._headers.get(HttpHeaders.SET_COOKIE);
117
118 if (values == null) {
119 values = new HashSet<Header>();
120
121 _metaData._headers.put(HttpHeaders.SET_COOKIE, values);
122 }
123
124 Header header = new Header(cookie);
125
126 values.add(header);
127
128 super.addCookie(cookie);
129 }
130
131 @Override
132 public void addDateHeader(String name, long value) {
133 Set<Header> values = _metaData._headers.get(name);
134
135 if (values == null) {
136 values = new HashSet<Header>();
137
138 _metaData._headers.put(name, values);
139 }
140
141 Header header = new Header(value);
142
143 values.add(header);
144
145 super.addDateHeader(name, value);
146 }
147
148 @Override
149 public void addHeader(String name, String value) {
150 if (name.equals(HttpHeaders.CONTENT_TYPE)) {
151 setContentType(value);
152
153 return;
154 }
155
156 Set<Header> values = _metaData._headers.get(name);
157
158 if (values == null) {
159 values = new HashSet<Header>();
160
161 _metaData._headers.put(name, values);
162 }
163
164 Header header = new Header(value);
165
166 values.add(header);
167
168 super.addHeader(name, value);
169 }
170
171 @Override
172 public void addIntHeader(String name, int value) {
173 Set<Header> values = _metaData._headers.get(name);
174
175 if (values == null) {
176 values = new HashSet<Header>();
177
178 _metaData._headers.put(name, values);
179 }
180
181 Header header = new Header(value);
182
183 values.add(header);
184
185 super.addIntHeader(name, value);
186 }
187
188 @Override
189 public boolean containsHeader(String name) {
190 return _metaData._headers.containsKey(name);
191 }
192
193 public void finishResponse() throws IOException {
194 HttpServletResponse response = (HttpServletResponse)getResponse();
195
196 finishResponse(_metaData, response);
197
198 _committed = true;
199 }
200
201 @Override
202 @SuppressWarnings("unused")
203 public void flushBuffer() throws IOException {
204 _committed = true;
205 }
206
207 @Override
208 public int getBufferSize() {
209 return _metaData._bufferSize;
210 }
211
212 @Override
213 public String getCharacterEncoding() {
214
215
216
217
218
219
220 if (_metaData._charsetName == null) {
221 return StringPool.DEFAULT_CHARSET_NAME;
222 }
223
224 return _metaData._charsetName;
225 }
226
227 @Override
228 public String getContentType() {
229 String contentType = _metaData._contentType;
230
231 if ((contentType != null) && (_metaData._charsetName != null)) {
232 contentType = contentType.concat("; charset=").concat(
233 _metaData._charsetName);
234 }
235
236 return contentType;
237 }
238
239
245 @Override
246 public String getHeader(String name) {
247 Set<Header> values = _metaData._headers.get(name);
248
249 if (values == null) {
250 return null;
251 }
252
253 Header header = values.iterator().next();
254
255 return header.toString();
256 }
257
258 @Override
259 public Collection<String> getHeaderNames() {
260 return _metaData._headers.keySet();
261 }
262
263 public Map<String, Set<Header>> getHeaders() {
264 return _metaData._headers;
265 }
266
267
273 @Override
274 public Collection<String> getHeaders(String name) {
275 Set<Header> values = _metaData._headers.get(name);
276
277 if (values == null) {
278 return Collections.emptyList();
279 }
280
281 List<String> stringValues = new ArrayList<String>();
282
283 for (Header header : values) {
284 stringValues.add(header.toString());
285 }
286
287 return stringValues;
288 }
289
290 @Override
291 public Locale getLocale() {
292 return _metaData._locale;
293 }
294
295 public MetaData getMetaData() {
296 return _metaData;
297 }
298
299 @Override
300 public ServletOutputStream getOutputStream() throws IOException {
301 calledGetOutputStream = true;
302
303 return super.getOutputStream();
304 }
305
306 @Override
307 public int getStatus() {
308 return _metaData._status;
309 }
310
311 @Override
312 public PrintWriter getWriter() throws IOException {
313 calledGetWriter = true;
314
315 return super.getWriter();
316 }
317
318 @Override
319 public boolean isCommitted() {
320 ServletResponse servletResponse = getResponse();
321
322 return _committed || servletResponse.isCommitted();
323 }
324
325 @Override
326 public void reset() {
327 if (isCommitted()) {
328 throw new IllegalStateException("Reset after commit");
329 }
330
331
332
333
334 _metaData._charsetName = null;
335 _metaData._contentLength = -1;
336 _metaData._contentType = null;
337 _metaData._headers.clear();
338 _metaData._locale = null;
339 _metaData._status = SC_OK;
340 _metaData._statusMessage = null;
341
342
343
344
345 resetBuffer();
346
347 super.reset();
348 }
349
350 @Override
351 public void resetBuffer() {
352 if (isCommitted()) {
353 throw new IllegalStateException("Reset buffer after commit");
354 }
355
356 resetBuffer(false);
357 }
358
359 @Override
360 public void sendError(int status) throws IOException {
361 if (isCommitted()) {
362 throw new IllegalStateException("Send error after commit");
363 }
364
365 _metaData._error = true;
366 _metaData._status = status;
367
368 resetBuffer();
369
370 _committed = true;
371
372 super.sendError(status);
373 }
374
375 @Override
376 public void sendError(int status, String errorMessage) throws IOException {
377 if (isCommitted()) {
378 throw new IllegalStateException("Send error after commit");
379 }
380
381 _metaData._error = true;
382 _metaData._errorMessage = errorMessage;
383 _metaData._status = status;
384
385 resetBuffer();
386
387 _committed = true;
388
389 super.sendError(status, errorMessage);
390 }
391
392 @Override
393 public void sendRedirect(String location) throws IOException {
394 if (isCommitted()) {
395 throw new IllegalStateException("Send redirect after commit");
396 }
397
398 resetBuffer(true);
399
400 setStatus(SC_FOUND);
401
402 _metaData._location = location;
403
404 _committed = true;
405
406 super.sendRedirect(location);
407 }
408
409 @Override
410 public void setBufferSize(int bufferSize) {
411 if (isCommitted()) {
412 throw new IllegalStateException("Set buffer size after commit");
413 }
414
415 _metaData._bufferSize = bufferSize;
416
417 super.setBufferSize(bufferSize);
418 }
419
420 @Override
421 public void setCharacterEncoding(String charsetName) {
422 if (isCommitted()) {
423 return;
424 }
425
426 if (calledGetWriter) {
427 return;
428 }
429
430 if (charsetName == null) {
431 return;
432 }
433
434 _metaData._charsetName = charsetName;
435
436 super.setCharacterEncoding(charsetName);
437 }
438
439 @Override
440 public void setContentLength(int contentLength) {
441 if (isCommitted()) {
442 return;
443 }
444
445 _metaData._contentLength = contentLength;
446
447 super.setContentLength(contentLength);
448 }
449
450 @Override
451 public void setContentType(String contentType) {
452 if (isCommitted()) {
453 return;
454 }
455
456 if (contentType == null) {
457 return;
458 }
459
460 int index = contentType.indexOf(CharPool.SEMICOLON);
461
462 if (index != -1) {
463 String firstPart = contentType.substring(0, index);
464
465 _metaData._contentType = firstPart.trim();
466
467 index = contentType.indexOf("charset=");
468
469 if (index != -1) {
470 String charsetName = contentType.substring(index + 8);
471
472 charsetName = charsetName.trim();
473
474 setCharacterEncoding(charsetName);
475 }
476 else {
477 _metaData._charsetName = null;
478 }
479 }
480 else {
481 _metaData._contentType = contentType;
482
483 _metaData._charsetName = null;
484 }
485
486 super.setContentType(contentType);
487 }
488
489 @Override
490 public void setDateHeader(String name, long value) {
491 Set<Header> values = new HashSet<Header>();
492
493 _metaData._headers.put(name, values);
494
495 Header header = new Header(value);
496
497 values.add(header);
498
499 super.setDateHeader(name, value);
500 }
501
502 @Override
503 public void setHeader(String name, String value) {
504 if (name.equals(HttpHeaders.CONTENT_TYPE)) {
505 setContentType(value);
506
507 return;
508 }
509
510 Set<Header> values = new HashSet<Header>();
511
512 _metaData._headers.put(name, values);
513
514 Header header = new Header(value);
515
516 values.add(header);
517
518 super.setHeader(name, value);
519 }
520
521 @Override
522 public void setIntHeader(String name, int value) {
523 Set<Header> values = new HashSet<Header>();
524
525 _metaData._headers.put(name, values);
526
527 Header header = new Header(value);
528
529 values.add(header);
530
531 super.setIntHeader(name, value);
532 }
533
534 @Override
535 public void setLocale(Locale locale) {
536 if (isCommitted()) {
537 return;
538 }
539
540 _metaData._locale = locale;
541
542 super.setLocale(locale);
543 }
544
545 @Override
546 public void setStatus(int status) {
547 if (isCommitted()) {
548 return;
549 }
550
551 _metaData._status = status;
552
553 super.setStatus(status);
554 }
555
556 @Override
557 @SuppressWarnings("deprecation")
558 public void setStatus(int status, String statusMessage) {
559 if (isCommitted()) {
560 return;
561 }
562
563 _metaData._status = status;
564 _metaData._statusMessage = statusMessage;
565
566 super.setStatus(status, statusMessage);
567 }
568
569 @Override
570 public String toString() {
571 StringBundler sb = new StringBundler(23);
572
573 sb.append("{bufferSize=");
574 sb.append(_metaData._bufferSize);
575 sb.append(", charsetName=");
576 sb.append(_metaData._charsetName);
577 sb.append(", committed=");
578 sb.append(_committed);
579 sb.append(", contentLength=");
580 sb.append(_metaData._contentLength);
581 sb.append(", contentType=");
582 sb.append(_metaData._contentType);
583 sb.append(", error=");
584 sb.append(_metaData._error);
585 sb.append(", errorMessage=");
586 sb.append(_metaData._errorMessage);
587 sb.append(", headers=");
588 sb.append(_metaData._headers);
589 sb.append(", location=");
590 sb.append(_metaData._location);
591 sb.append(", locale=");
592 sb.append(_metaData._locale);
593 sb.append(", status=");
594 sb.append(_metaData._status);
595 sb.append("}");
596
597 return sb.toString();
598 }
599
600 public static class MetaData implements Serializable {
601
602 private int _bufferSize;
603 private String _charsetName;
604 private int _contentLength = -1;
605 private String _contentType;
606 private boolean _error;
607 private String _errorMessage;
608 private final Map<String, Set<Header>> _headers =
609 new HashMap<String, Set<Header>>();
610 private Locale _locale;
611 private String _location;
612 private int _status = SC_OK;
613 private String _statusMessage;
614
615 }
616
617
624 protected void resetBuffer(boolean nullOutReferences) {
625 super.resetBuffer();
626 }
627
628 protected boolean calledGetOutputStream;
629 protected boolean calledGetWriter;
630
631 private boolean _committed;
632 private final MetaData _metaData = new MetaData();
633
634 }