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 public String getHeader(String name) {
246 Set<Header> values = _metaData._headers.get(name);
247
248 if (values == null) {
249 return null;
250 }
251
252 Header header = values.iterator().next();
253
254 return header.toString();
255 }
256
257 public Collection<String> getHeaderNames() {
258 return _metaData._headers.keySet();
259 }
260
261 public Map<String, Set<Header>> getHeaders() {
262 return _metaData._headers;
263 }
264
265
271 public Collection<String> getHeaders(String name) {
272 Set<Header> values = _metaData._headers.get(name);
273
274 if (values == null) {
275 return Collections.emptyList();
276 }
277
278 List<String> stringValues = new ArrayList<String>();
279
280 for (Header header : values) {
281 stringValues.add(header.toString());
282 }
283
284 return stringValues;
285 }
286
287 @Override
288 public Locale getLocale() {
289 return _metaData._locale;
290 }
291
292 public MetaData getMetaData() {
293 return _metaData;
294 }
295
296 @Override
297 public ServletOutputStream getOutputStream() throws IOException {
298 calledGetOutputStream = true;
299
300 return super.getOutputStream();
301 }
302
303 public int getStatus() {
304 return _metaData._status;
305 }
306
307 @Override
308 public PrintWriter getWriter() throws IOException {
309 calledGetWriter = true;
310
311 return super.getWriter();
312 }
313
314 @Override
315 public boolean isCommitted() {
316 ServletResponse servletResponse = getResponse();
317
318 return _committed || servletResponse.isCommitted();
319 }
320
321 @Override
322 public void reset() {
323 if (isCommitted()) {
324 throw new IllegalStateException("Reset after commit");
325 }
326
327
328
329
330 _metaData._charsetName = null;
331 _metaData._contentLength = -1;
332 _metaData._contentType = null;
333 _metaData._headers.clear();
334 _metaData._locale = null;
335 _metaData._status = SC_OK;
336 _metaData._statusMessage = null;
337
338
339
340
341 resetBuffer();
342
343 super.reset();
344 }
345
346 @Override
347 public void resetBuffer() {
348 if (isCommitted()) {
349 throw new IllegalStateException("Reset buffer after commit");
350 }
351
352 resetBuffer(false);
353 }
354
355 @Override
356 public void sendError(int status) throws IOException {
357 sendError(status, null);
358 }
359
360 @Override
361 public void sendError(int status, String errorMessage) throws IOException {
362 if (isCommitted()) {
363 throw new IllegalStateException("Send error after commit");
364 }
365
366 _metaData._error = true;
367 _metaData._errorMessage = errorMessage;
368 _metaData._status = status;
369
370 resetBuffer();
371
372 _committed = true;
373
374 super.sendError(status, errorMessage);
375 }
376
377 @Override
378 public void sendRedirect(String location) throws IOException {
379 if (isCommitted()) {
380 throw new IllegalStateException("Send redirect after commit");
381 }
382
383 resetBuffer(true);
384
385 setStatus(SC_FOUND);
386
387 _metaData._location = location;
388
389 _committed = true;
390
391 super.sendRedirect(location);
392 }
393
394 @Override
395 public void setBufferSize(int bufferSize) {
396 if (isCommitted()) {
397 throw new IllegalStateException("Set buffer size after commit");
398 }
399
400 _metaData._bufferSize = bufferSize;
401
402 super.setBufferSize(bufferSize);
403 }
404
405 @Override
406 public void setCharacterEncoding(String charsetName) {
407 if (isCommitted()) {
408 return;
409 }
410
411 if (calledGetWriter) {
412 return;
413 }
414
415 if (charsetName == null) {
416 return;
417 }
418
419 _metaData._charsetName = charsetName;
420
421 super.setCharacterEncoding(charsetName);
422 }
423
424 @Override
425 public void setContentLength(int contentLength) {
426 if (isCommitted()) {
427 return;
428 }
429
430 _metaData._contentLength = contentLength;
431
432 super.setContentLength(contentLength);
433 }
434
435 @Override
436 public void setContentType(String contentType) {
437 if (isCommitted()) {
438 return;
439 }
440
441 if (contentType == null) {
442 return;
443 }
444
445 int index = contentType.indexOf(CharPool.SEMICOLON);
446
447 if (index != -1) {
448 String firstPart = contentType.substring(0, index);
449
450 _metaData._contentType = firstPart.trim();
451
452 index = contentType.indexOf("charset=");
453
454 if (index != -1) {
455 String charsetName = contentType.substring(index + 8);
456
457 charsetName = charsetName.trim();
458
459 setCharacterEncoding(charsetName);
460 }
461 else {
462 _metaData._charsetName = null;
463 }
464 }
465 else {
466 _metaData._contentType = contentType;
467
468 _metaData._charsetName = null;
469 }
470
471 super.setContentType(contentType);
472 }
473
474 @Override
475 public void setDateHeader(String name, long value) {
476 Set<Header> values = new HashSet<Header>();
477
478 _metaData._headers.put(name, values);
479
480 Header header = new Header(value);
481
482 values.add(header);
483
484 super.setDateHeader(name, value);
485 }
486
487 @Override
488 public void setHeader(String name, String value) {
489 if (name.equals(HttpHeaders.CONTENT_TYPE)) {
490 setContentType(value);
491
492 return;
493 }
494
495 Set<Header> values = new HashSet<Header>();
496
497 _metaData._headers.put(name, values);
498
499 Header header = new Header(value);
500
501 values.add(header);
502
503 super.setHeader(name, value);
504 }
505
506 @Override
507 public void setIntHeader(String name, int value) {
508 Set<Header> values = new HashSet<Header>();
509
510 _metaData._headers.put(name, values);
511
512 Header header = new Header(value);
513
514 values.add(header);
515
516 super.setIntHeader(name, value);
517 }
518
519 @Override
520 public void setLocale(Locale locale) {
521 if (isCommitted()) {
522 return;
523 }
524
525 _metaData._locale = locale;
526
527 super.setLocale(locale);
528 }
529
530 @Override
531 public void setStatus(int status) {
532 setStatus(status, null);
533 }
534
535 @Override
536 public void setStatus(int status, String statusMessage) {
537 if (isCommitted()) {
538 return;
539 }
540
541 _metaData._status = status;
542 _metaData._statusMessage = statusMessage;
543
544 super.setStatus(status, statusMessage);
545 }
546
547 @Override
548 public String toString() {
549 StringBundler sb = new StringBundler(23);
550
551 sb.append("{bufferSize=");
552 sb.append(_metaData._bufferSize);
553 sb.append(", charsetName=");
554 sb.append(_metaData._charsetName);
555 sb.append(", committed=");
556 sb.append(_committed);
557 sb.append(", contentLength=");
558 sb.append(_metaData._contentLength);
559 sb.append(", contentType=");
560 sb.append(_metaData._contentType);
561 sb.append(", error=");
562 sb.append(_metaData._error);
563 sb.append(", errorMessage=");
564 sb.append(_metaData._errorMessage);
565 sb.append(", headers=");
566 sb.append(_metaData._headers);
567 sb.append(", location=");
568 sb.append(_metaData._location);
569 sb.append(", locale=");
570 sb.append(_metaData._locale);
571 sb.append(", status=");
572 sb.append(_metaData._status);
573 sb.append("}");
574
575 return sb.toString();
576 }
577
578 public static class MetaData implements Serializable {
579
580 private int _bufferSize;
581 private String _charsetName;
582 private int _contentLength = -1;
583 private String _contentType;
584 private boolean _error;
585 private String _errorMessage;
586 private Map<String, Set<Header>> _headers =
587 new HashMap<String, Set<Header>>();
588 private Locale _locale;
589 private String _location;
590 private int _status = SC_OK;
591 private String _statusMessage;
592
593 }
594
595
602 protected void resetBuffer(boolean nullOutReferences) {
603 super.resetBuffer();
604 }
605
606 protected boolean calledGetOutputStream;
607 protected boolean calledGetWriter;
608
609 private boolean _committed;
610 private MetaData _metaData = new MetaData();
611
612 }