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 sendError(status, null);
362 }
363
364 @Override
365 public void sendError(int status, String errorMessage) throws IOException {
366 if (isCommitted()) {
367 throw new IllegalStateException("Send error after commit");
368 }
369
370 _metaData._error = true;
371 _metaData._errorMessage = errorMessage;
372 _metaData._status = status;
373
374 resetBuffer();
375
376 _committed = true;
377
378 super.sendError(status, errorMessage);
379 }
380
381 @Override
382 public void sendRedirect(String location) throws IOException {
383 if (isCommitted()) {
384 throw new IllegalStateException("Send redirect after commit");
385 }
386
387 resetBuffer(true);
388
389 _metaData._location = location;
390
391 _committed = true;
392
393 super.sendRedirect(location);
394 }
395
396 @Override
397 public void setBufferSize(int bufferSize) {
398 if (isCommitted()) {
399 throw new IllegalStateException("Set buffer size after commit");
400 }
401
402 _metaData._bufferSize = bufferSize;
403
404 super.setBufferSize(bufferSize);
405 }
406
407 @Override
408 public void setCharacterEncoding(String charsetName) {
409 if (isCommitted()) {
410 return;
411 }
412
413 if (calledGetWriter) {
414 return;
415 }
416
417 if (charsetName == null) {
418 return;
419 }
420
421 _metaData._charsetName = charsetName;
422
423 super.setCharacterEncoding(charsetName);
424 }
425
426 @Override
427 public void setContentLength(int contentLength) {
428 if (isCommitted()) {
429 return;
430 }
431
432 _metaData._contentLength = contentLength;
433
434 super.setContentLength(contentLength);
435 }
436
437 @Override
438 public void setContentType(String contentType) {
439 if (isCommitted()) {
440 return;
441 }
442
443 if (contentType == null) {
444 return;
445 }
446
447 int index = contentType.indexOf(CharPool.SEMICOLON);
448
449 if (index != -1) {
450 String firstPart = contentType.substring(0, index);
451
452 _metaData._contentType = firstPart.trim();
453
454 index = contentType.indexOf("charset=");
455
456 if (index != -1) {
457 String charsetName = contentType.substring(index + 8);
458
459 charsetName = charsetName.trim();
460
461 setCharacterEncoding(charsetName);
462 }
463 else {
464 _metaData._charsetName = null;
465 }
466 }
467 else {
468 _metaData._contentType = contentType;
469
470 _metaData._charsetName = null;
471 }
472
473 super.setContentType(contentType);
474 }
475
476 @Override
477 public void setDateHeader(String name, long value) {
478 Set<Header> values = new HashSet<Header>();
479
480 _metaData._headers.put(name, values);
481
482 Header header = new Header(value);
483
484 values.add(header);
485
486 super.setDateHeader(name, value);
487 }
488
489 @Override
490 public void setHeader(String name, String value) {
491 if (name.equals(HttpHeaders.CONTENT_TYPE)) {
492 setContentType(value);
493
494 return;
495 }
496
497 Set<Header> values = new HashSet<Header>();
498
499 _metaData._headers.put(name, values);
500
501 Header header = new Header(value);
502
503 values.add(header);
504
505 super.setHeader(name, value);
506 }
507
508 @Override
509 public void setIntHeader(String name, int value) {
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.setIntHeader(name, value);
519 }
520
521 @Override
522 public void setLocale(Locale locale) {
523 if (isCommitted()) {
524 return;
525 }
526
527 _metaData._locale = locale;
528
529 super.setLocale(locale);
530 }
531
532 @Override
533 public void setStatus(int status) {
534 setStatus(status, null);
535 }
536
537
540 @Override
541 public void setStatus(int status, String statusMessage) {
542 if (isCommitted()) {
543 return;
544 }
545
546 _metaData._status = status;
547 _metaData._statusMessage = statusMessage;
548
549 super.setStatus(status, statusMessage);
550 }
551
552 @Override
553 public String toString() {
554 StringBundler sb = new StringBundler(23);
555
556 sb.append("{bufferSize=");
557 sb.append(_metaData._bufferSize);
558 sb.append(", charsetName=");
559 sb.append(_metaData._charsetName);
560 sb.append(", committed=");
561 sb.append(_committed);
562 sb.append(", contentLength=");
563 sb.append(_metaData._contentLength);
564 sb.append(", contentType=");
565 sb.append(_metaData._contentType);
566 sb.append(", error=");
567 sb.append(_metaData._error);
568 sb.append(", errorMessage=");
569 sb.append(_metaData._errorMessage);
570 sb.append(", headers=");
571 sb.append(_metaData._headers);
572 sb.append(", location=");
573 sb.append(_metaData._location);
574 sb.append(", locale=");
575 sb.append(_metaData._locale);
576 sb.append(", status=");
577 sb.append(_metaData._status);
578 sb.append("}");
579
580 return sb.toString();
581 }
582
583 public static class MetaData implements Serializable {
584
585 private int _bufferSize;
586 private String _charsetName;
587 private int _contentLength = -1;
588 private String _contentType;
589 private boolean _error;
590 private String _errorMessage;
591 private Map<String, Set<Header>> _headers =
592 new HashMap<String, Set<Header>>();
593 private Locale _locale;
594 private String _location;
595 private int _status = SC_OK;
596 private String _statusMessage;
597
598 }
599
600
607 protected void resetBuffer(boolean nullOutReferences) {
608 super.resetBuffer();
609 }
610
611 protected boolean calledGetOutputStream;
612 protected boolean calledGetWriter;
613
614 private boolean _committed;
615 private MetaData _metaData = new MetaData();
616
617 }