Source Code Cross Referenced for WinstoneResponse.java in  » Web-Server » Winstone » winstone » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Server » Winstone » winstone 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
003:         * Distributed under the terms of either:
004:         * - the common development and distribution license (CDDL), v1.0; or
005:         * - the GNU Lesser General Public License, v2.1 or later
006:         */
007:        package winstone;
008:
009:        import java.io.IOException;
010:        import java.io.PrintWriter;
011:        import java.io.UnsupportedEncodingException;
012:        import java.io.Writer;
013:        import java.text.DateFormat;
014:        import java.text.SimpleDateFormat;
015:        import java.util.ArrayList;
016:        import java.util.Date;
017:        import java.util.Iterator;
018:        import java.util.List;
019:        import java.util.Locale;
020:        import java.util.Map;
021:        import java.util.StringTokenizer;
022:        import java.util.TimeZone;
023:
024:        import javax.servlet.ServletOutputStream;
025:        import javax.servlet.http.Cookie;
026:        import javax.servlet.http.HttpServletResponse;
027:
028:        /**
029:         * Response for servlet
030:         * 
031:         * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
032:         * @version $Id: WinstoneResponse.java,v 1.28 2005/04/19 07:33:41 rickknowles
033:         *          Exp $
034:         */
035:        public class WinstoneResponse implements  HttpServletResponse {
036:            private static final DateFormat HTTP_DF = new SimpleDateFormat(
037:                    "EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
038:            private static final DateFormat VERSION0_DF = new SimpleDateFormat(
039:                    "EEE, dd-MMM-yy HH:mm:ss z", Locale.US);
040:            static {
041:                HTTP_DF.setTimeZone(TimeZone.getTimeZone("GMT"));
042:                VERSION0_DF.setTimeZone(TimeZone.getTimeZone("GMT"));
043:            }
044:
045:            static final String CONTENT_LENGTH_HEADER = "Content-Length";
046:            static final String CONTENT_TYPE_HEADER = "Content-Type";
047:
048:            // Response header constants
049:            private static final String CONTENT_LANGUAGE_HEADER = "Content-Language";
050:            private static final String KEEP_ALIVE_HEADER = "Connection";
051:            private static final String KEEP_ALIVE_OPEN = "Keep-Alive";
052:            private static final String KEEP_ALIVE_CLOSE = "Close";
053:            private static final String DATE_HEADER = "Date";
054:            private static final String LOCATION_HEADER = "Location";
055:            private static final String OUT_COOKIE_HEADER1 = "Set-Cookie";
056:            private static final String X_POWERED_BY_HEADER = "X-Powered-By";
057:            private static final String X_POWERED_BY_HEADER_VALUE = Launcher.RESOURCES
058:                    .getString("PoweredByHeader");
059:
060:            private int statusCode;
061:            private WinstoneRequest req;
062:            private WebAppConfiguration webAppConfig;
063:            private WinstoneOutputStream outputStream;
064:            private PrintWriter outputWriter;
065:
066:            private List headers;
067:            private String explicitEncoding;
068:            private String implicitEncoding;
069:            private List cookies;
070:
071:            private Locale locale;
072:            private String protocol;
073:            private String reqKeepAliveHeader;
074:            private Integer errorStatusCode;
075:
076:            /**
077:             * Constructor
078:             */
079:            public WinstoneResponse() {
080:
081:                this .headers = new ArrayList();
082:                this .cookies = new ArrayList();
083:
084:                this .statusCode = SC_OK;
085:                this .locale = null; //Locale.getDefault();
086:                this .explicitEncoding = null;
087:                this .protocol = null;
088:                this .reqKeepAliveHeader = null;
089:            }
090:
091:            /**
092:             * Resets the request to be reused
093:             */
094:            public void cleanUp() {
095:                this .req = null;
096:                this .webAppConfig = null;
097:                this .outputStream = null;
098:                this .outputWriter = null;
099:                this .headers.clear();
100:                this .cookies.clear();
101:                this .protocol = null;
102:                this .reqKeepAliveHeader = null;
103:
104:                this .statusCode = SC_OK;
105:                this .errorStatusCode = null;
106:                this .locale = null; //Locale.getDefault();
107:                this .explicitEncoding = null;
108:                this .implicitEncoding = null;
109:            }
110:
111:            private String getEncodingFromLocale(Locale loc) {
112:                String localeString = loc.getLanguage() + "_"
113:                        + loc.getCountry();
114:                Map encMap = this .webAppConfig.getLocaleEncodingMap();
115:                Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
116:                        "WinstoneResponse.LookForLocaleEncoding", new String[] {
117:                                localeString, encMap + "" });
118:
119:                String fullMatch = (String) encMap.get(localeString);
120:                if (fullMatch != null) {
121:                    Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
122:                            "WinstoneResponse.FoundLocaleEncoding", fullMatch);
123:                    return fullMatch;
124:                } else {
125:                    localeString = loc.getLanguage();
126:                    Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
127:                            "WinstoneResponse.LookForLocaleEncoding",
128:                            new String[] { localeString, encMap + "" });
129:                    String match = (String) encMap.get(localeString);
130:                    if (match != null) {
131:                        Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
132:                                "WinstoneResponse.FoundLocaleEncoding", match);
133:                    }
134:                    return match;
135:                }
136:            }
137:
138:            public void setErrorStatusCode(int statusCode) {
139:                this .errorStatusCode = new Integer(statusCode);
140:                this .statusCode = statusCode;
141:            }
142:
143:            public WinstoneOutputStream getWinstoneOutputStream() {
144:                return this .outputStream;
145:            }
146:
147:            public void setOutputStream(WinstoneOutputStream outData) {
148:                this .outputStream = outData;
149:            }
150:
151:            public void setWebAppConfig(WebAppConfiguration webAppConfig) {
152:                this .webAppConfig = webAppConfig;
153:            }
154:
155:            public String getProtocol() {
156:                return this .protocol;
157:            }
158:
159:            public void setProtocol(String protocol) {
160:                this .protocol = protocol;
161:            }
162:
163:            public void extractRequestKeepAliveHeader(WinstoneRequest req) {
164:                this .reqKeepAliveHeader = req.getHeader(KEEP_ALIVE_HEADER);
165:            }
166:
167:            public List getHeaders() {
168:                return this .headers;
169:            }
170:
171:            public List getCookies() {
172:                return this .cookies;
173:            }
174:
175:            public WinstoneRequest getRequest() {
176:                return this .req;
177:            }
178:
179:            public void setRequest(WinstoneRequest req) {
180:                this .req = req;
181:            }
182:
183:            public void startIncludeBuffer() {
184:                this .outputStream.startIncludeBuffer();
185:            }
186:
187:            public void finishIncludeBuffer() throws IOException {
188:                if (isIncluding()) {
189:                    if (this .outputWriter != null) {
190:                        this .outputWriter.flush();
191:                    }
192:                    this .outputStream.finishIncludeBuffer();
193:                }
194:            }
195:
196:            public void clearIncludeStackForForward() throws IOException {
197:                this .outputStream.clearIncludeStackForForward();
198:            }
199:
200:            protected static String getCharsetFromContentTypeHeader(
201:                    String type, StringBuffer remainder) {
202:                if (type == null) {
203:                    return null;
204:                }
205:                // Parse type to set encoding if needed
206:                StringTokenizer st = new StringTokenizer(type, ";");
207:                String localEncoding = null;
208:                while (st.hasMoreTokens()) {
209:                    String clause = st.nextToken().trim();
210:                    if (clause.startsWith("charset="))
211:                        localEncoding = clause.substring(8);
212:                    else {
213:                        if (remainder.length() > 0) {
214:                            remainder.append(";");
215:                        }
216:                        remainder.append(clause);
217:                    }
218:                }
219:                if ((localEncoding == null) || !localEncoding.startsWith("\"")
220:                        || !localEncoding.endsWith("\"")) {
221:                    return localEncoding;
222:                } else {
223:                    return localEncoding.substring(1,
224:                            localEncoding.length() - 1);
225:                }
226:            }
227:
228:            /**
229:             * This ensures the bare minimum correct http headers are present
230:             */
231:            public void validateHeaders() {
232:                // Need this block for WebDAV support. "Connection:close" header is ignored
233:                String lengthHeader = getHeader(CONTENT_LENGTH_HEADER);
234:                if ((lengthHeader == null) && (this .statusCode >= 300)) {
235:                    int bodyBytes = this .outputStream.getOutputStreamLength();
236:                    if (getBufferSize() > bodyBytes) {
237:                        Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
238:                                "WinstoneResponse.ForcingContentLength", ""
239:                                        + bodyBytes);
240:                        forceHeader(CONTENT_LENGTH_HEADER, "" + bodyBytes);
241:                        lengthHeader = getHeader(CONTENT_LENGTH_HEADER);
242:                    }
243:                }
244:
245:                forceHeader(KEEP_ALIVE_HEADER,
246:                        !closeAfterRequest() ? KEEP_ALIVE_OPEN
247:                                : KEEP_ALIVE_CLOSE);
248:                String contentType = getHeader(CONTENT_TYPE_HEADER);
249:                if (this .statusCode != SC_MOVED_TEMPORARILY) {
250:                    if (contentType == null) {
251:                        // Bypass normal encoding
252:                        forceHeader(CONTENT_TYPE_HEADER, "text/html;charset="
253:                                + getCharacterEncoding());
254:                    } else if (contentType.startsWith("text/")) {
255:                        // replace charset in content
256:                        StringBuffer remainder = new StringBuffer();
257:                        getCharsetFromContentTypeHeader(contentType, remainder);
258:                        forceHeader(CONTENT_TYPE_HEADER, remainder.toString()
259:                                + ";charset=" + getCharacterEncoding());
260:                    }
261:                }
262:                if (getHeader(DATE_HEADER) == null) {
263:                    forceHeader(DATE_HEADER, formatHeaderDate(new Date()));
264:                }
265:                if (getHeader(X_POWERED_BY_HEADER) == null) {
266:                    forceHeader(X_POWERED_BY_HEADER, X_POWERED_BY_HEADER_VALUE);
267:                }
268:                if (this .locale != null) {
269:                    String lang = this .locale.getLanguage();
270:                    if ((this .locale.getCountry() != null)
271:                            && !this .locale.getCountry().equals("")) {
272:                        lang = lang + "-" + this .locale.getCountry();
273:                    }
274:                    forceHeader(CONTENT_LANGUAGE_HEADER, lang);
275:                }
276:
277:                // If we don't have a webappConfig, exit here, cause we definitely don't
278:                // have a session
279:                if (req.getWebAppConfig() == null) {
280:                    return;
281:                }
282:                // Write out the new session cookie if it's present
283:                HostConfiguration hostConfig = req.getHostGroup()
284:                        .getHostByName(req.getServerName());
285:                for (Iterator i = req.getCurrentSessionIds().keySet()
286:                        .iterator(); i.hasNext();) {
287:                    String prefix = (String) i.next();
288:                    String sessionId = (String) req.getCurrentSessionIds().get(
289:                            prefix);
290:                    WebAppConfiguration ownerContext = hostConfig
291:                            .getWebAppByURI(prefix);
292:                    if (ownerContext != null) {
293:                        WinstoneSession session = ownerContext.getSessionById(
294:                                sessionId, true);
295:                        if ((session != null) && session.isNew()) {
296:                            session.setIsNew(false);
297:                            Cookie cookie = new Cookie(
298:                                    WinstoneSession.SESSION_COOKIE_NAME,
299:                                    session.getId());
300:                            cookie.setMaxAge(-1);
301:                            cookie.setSecure(req.isSecure());
302:                            cookie.setVersion(0); //req.isSecure() ? 1 : 0);
303:                            cookie.setPath(req.getWebAppConfig()
304:                                    .getContextPath().equals("") ? "/" : req
305:                                    .getWebAppConfig().getContextPath());
306:                            this .cookies.add(cookie); // don't call addCookie because we might be including
307:                        }
308:                    }
309:                }
310:
311:                // Look for expired sessions: ie ones where the requested and current ids are different
312:                for (Iterator i = req.getRequestedSessionIds().keySet()
313:                        .iterator(); i.hasNext();) {
314:                    String prefix = (String) i.next();
315:                    String sessionId = (String) req.getRequestedSessionIds()
316:                            .get(prefix);
317:                    if (!req.getCurrentSessionIds().containsKey(prefix)) {
318:                        Cookie cookie = new Cookie(
319:                                WinstoneSession.SESSION_COOKIE_NAME, sessionId);
320:                        cookie.setMaxAge(0); // explicitly expire this cookie
321:                        cookie.setSecure(req.isSecure());
322:                        cookie.setVersion(0); //req.isSecure() ? 1 : 0);
323:                        cookie.setPath(prefix.equals("") ? "/" : prefix);
324:                        this .cookies.add(cookie); // don't call addCookie because we might be including
325:                    }
326:                }
327:
328:                Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
329:                        "WinstoneResponse.HeadersPreCommit", this .headers + "");
330:            }
331:
332:            /**
333:             * Writes out the http header for a single cookie
334:             */
335:            public String writeCookie(Cookie cookie) throws IOException {
336:
337:                Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
338:                        "WinstoneResponse.WritingCookie", cookie + "");
339:                StringBuffer out = new StringBuffer();
340:
341:                // Set-Cookie or Set-Cookie2
342:                if (cookie.getVersion() >= 1)
343:                    out.append(OUT_COOKIE_HEADER1).append(": "); // TCK doesn't like set-cookie2
344:                else
345:                    out.append(OUT_COOKIE_HEADER1).append(": ");
346:
347:                // name/value pair
348:                if (cookie.getVersion() == 0)
349:                    out.append(cookie.getName()).append("=").append(
350:                            cookie.getValue());
351:                else {
352:                    out.append(cookie.getName()).append("=");
353:                    quote(cookie.getValue(), out);
354:                }
355:
356:                if (cookie.getVersion() >= 1) {
357:                    out.append("; Version=1");
358:                    if (cookie.getDomain() != null) {
359:                        out.append("; Domain=");
360:                        quote(cookie.getDomain(), out);
361:                    }
362:                    if (cookie.getSecure())
363:                        out.append("; Secure");
364:
365:                    if (cookie.getMaxAge() >= 0)
366:                        out.append("; Max-Age=").append(cookie.getMaxAge());
367:                    else
368:                        out.append("; Discard");
369:                    if (cookie.getPath() != null) {
370:                        out.append("; Path=");
371:                        quote(cookie.getPath(), out);
372:                    }
373:                } else {
374:                    if (cookie.getDomain() != null) {
375:                        out.append("; Domain=");
376:                        out.append(cookie.getDomain());
377:                    }
378:                    if (cookie.getMaxAge() > 0) {
379:                        long expiryMS = System.currentTimeMillis()
380:                                + (1000 * (long) cookie.getMaxAge());
381:                        String expiryDate = null;
382:                        synchronized (VERSION0_DF) {
383:                            expiryDate = VERSION0_DF.format(new Date(expiryMS));
384:                        }
385:                        out.append("; Expires=").append(expiryDate);
386:                    } else if (cookie.getMaxAge() == 0) {
387:                        String expiryDate = null;
388:                        synchronized (VERSION0_DF) {
389:                            expiryDate = VERSION0_DF.format(new Date(5000));
390:                        }
391:                        out.append("; Expires=").append(expiryDate);
392:                    }
393:                    if (cookie.getPath() != null)
394:                        out.append("; Path=").append(cookie.getPath());
395:                    if (cookie.getSecure())
396:                        out.append("; Secure");
397:                }
398:                return out.toString();
399:            }
400:
401:            private static String formatHeaderDate(Date dateIn) {
402:                String date = null;
403:                synchronized (HTTP_DF) {
404:                    date = HTTP_DF.format(dateIn);
405:                }
406:                return date;
407:            }
408:
409:            /**
410:             * Quotes the necessary strings in a cookie header. The quoting is only
411:             * applied if the string contains special characters.
412:             */
413:            protected static void quote(String value, StringBuffer out) {
414:                if (value.startsWith("\"") && value.endsWith("\"")) {
415:                    out.append(value);
416:                } else {
417:                    boolean containsSpecial = false;
418:                    for (int n = 0; n < value.length(); n++) {
419:                        char this Char = value.charAt(n);
420:                        if ((this Char < 32) || (this Char >= 127)
421:                                || (specialCharacters.indexOf(this Char) != -1)) {
422:                            containsSpecial = true;
423:                            break;
424:                        }
425:                    }
426:                    if (containsSpecial)
427:                        out.append('"').append(value).append('"');
428:                    else
429:                        out.append(value);
430:                }
431:            }
432:
433:            private static final String specialCharacters = "()<>@,;:\\\"/[]?={} \t";
434:
435:            /**
436:             * Based on request/response headers and the protocol, determine whether or
437:             * not this connection should operate in keep-alive mode.
438:             */
439:            public boolean closeAfterRequest() {
440:                String inKeepAliveHeader = this .reqKeepAliveHeader;
441:                String outKeepAliveHeader = getHeader(KEEP_ALIVE_HEADER);
442:                boolean hasContentLength = (getHeader(CONTENT_LENGTH_HEADER) != null);
443:                if (this .protocol.startsWith("HTTP/0"))
444:                    return true;
445:                else if ((inKeepAliveHeader == null)
446:                        && (outKeepAliveHeader == null))
447:                    return this .protocol.equals("HTTP/1.0") ? true
448:                            : !hasContentLength;
449:                else if (outKeepAliveHeader != null)
450:                    return outKeepAliveHeader
451:                            .equalsIgnoreCase(KEEP_ALIVE_CLOSE)
452:                            || !hasContentLength;
453:                else if (inKeepAliveHeader != null)
454:                    return inKeepAliveHeader.equalsIgnoreCase(KEEP_ALIVE_CLOSE)
455:                            || !hasContentLength;
456:                else
457:                    return false;
458:            }
459:
460:            // ServletResponse interface methods
461:            public void flushBuffer() throws IOException {
462:                if (this .outputWriter != null) {
463:                    this .outputWriter.flush();
464:                }
465:                this .outputStream.flush();
466:            }
467:
468:            public void setBufferSize(int size) {
469:                this .outputStream.setBufferSize(size);
470:            }
471:
472:            public int getBufferSize() {
473:                return this .outputStream.getBufferSize();
474:            }
475:
476:            public String getCharacterEncoding() {
477:                String enc = getCurrentEncoding();
478:                return (enc == null ? "ISO-8859-1" : enc);
479:            }
480:
481:            public void setCharacterEncoding(String encoding) {
482:                if ((this .outputWriter == null) && !isCommitted()) {
483:                    Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
484:                            "WinstoneResponse.SettingEncoding", encoding);
485:                    this .explicitEncoding = encoding;
486:                    correctContentTypeHeaderEncoding(encoding);
487:                }
488:            }
489:
490:            private void correctContentTypeHeaderEncoding(String encoding) {
491:                String contentType = getContentType();
492:                if (contentType != null) {
493:                    StringBuffer remainderHeader = new StringBuffer();
494:                    getCharsetFromContentTypeHeader(contentType,
495:                            remainderHeader);
496:                    if (remainderHeader.length() != 0) {
497:                        forceHeader(CONTENT_TYPE_HEADER, remainderHeader
498:                                + ";charset=" + encoding);
499:                    }
500:                }
501:            }
502:
503:            public String getContentType() {
504:                return getHeader(CONTENT_TYPE_HEADER);
505:            }
506:
507:            public void setContentType(String type) {
508:                setHeader(CONTENT_TYPE_HEADER, type);
509:            }
510:
511:            public Locale getLocale() {
512:                return this .locale == null ? Locale.getDefault() : this .locale;
513:            }
514:
515:            private boolean isIncluding() {
516:                return this .outputStream.isIncluding();
517:            }
518:
519:            public void setLocale(Locale loc) {
520:                if (isIncluding()) {
521:                    return;
522:                } else if (isCommitted()) {
523:                    Logger.log(Logger.WARNING, Launcher.RESOURCES,
524:                            "WinstoneResponse.SetLocaleTooLate");
525:                } else {
526:                    if ((this .outputWriter == null)
527:                            && (this .explicitEncoding == null)) {
528:                        String localeEncoding = getEncodingFromLocale(loc);
529:                        if (localeEncoding != null) {
530:                            this .implicitEncoding = localeEncoding;
531:                            correctContentTypeHeaderEncoding(localeEncoding);
532:                        }
533:                    }
534:                    this .locale = loc;
535:                }
536:            }
537:
538:            public ServletOutputStream getOutputStream() throws IOException {
539:                Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
540:                        "WinstoneResponse.GetOutputStream");
541:                return this .outputStream;
542:            }
543:
544:            public PrintWriter getWriter() throws IOException {
545:                Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
546:                        "WinstoneResponse.GetWriter");
547:                if (this .outputWriter != null)
548:                    return this .outputWriter;
549:                else {
550:                    this .outputWriter = new WinstoneResponseWriter(
551:                            this .outputStream, this );
552:                    return this .outputWriter;
553:                }
554:            }
555:
556:            public boolean isCommitted() {
557:                return this .outputStream.isCommitted();
558:            }
559:
560:            public void reset() {
561:                if (!isIncluding()) {
562:                    resetBuffer();
563:                    this .statusCode = SC_OK;
564:                    this .headers.clear();
565:                    this .cookies.clear();
566:                }
567:            }
568:
569:            public void resetBuffer() {
570:                if (!isIncluding()) {
571:                    if (isCommitted())
572:                        throw new IllegalStateException(
573:                                Launcher.RESOURCES
574:                                        .getString("WinstoneResponse.ResponseCommitted"));
575:
576:                    // Disregard any output temporarily while we flush
577:                    this .outputStream.setDisregardMode(true);
578:
579:                    if (this .outputWriter != null) {
580:                        this .outputWriter.flush();
581:                    }
582:
583:                    this .outputStream.setDisregardMode(false);
584:                    this .outputStream.reset();
585:                }
586:            }
587:
588:            public void setContentLength(int len) {
589:                setIntHeader(CONTENT_LENGTH_HEADER, len);
590:            }
591:
592:            // HttpServletResponse interface methods
593:            public void addCookie(Cookie cookie) {
594:                if (!isIncluding()) {
595:                    this .cookies.add(cookie);
596:                }
597:            }
598:
599:            public boolean containsHeader(String name) {
600:                for (int n = 0; n < this .headers.size(); n++)
601:                    if (((String) this .headers.get(n)).startsWith(name))
602:                        return true;
603:                return false;
604:            }
605:
606:            public void addDateHeader(String name, long date) {
607:                addHeader(name, formatHeaderDate(new Date(date)));
608:            } // df.format(new Date(date)));}
609:
610:            public void addIntHeader(String name, int value) {
611:                addHeader(name, "" + value);
612:            }
613:
614:            public void addHeader(String name, String value) {
615:                if (isIncluding()) {
616:                    Logger.log(Logger.DEBUG, Launcher.RESOURCES,
617:                            "WinstoneResponse.HeaderInInclude", new String[] {
618:                                    name, value });
619:                } else if (isCommitted()) {
620:                    Logger.log(Logger.DEBUG, Launcher.RESOURCES,
621:                            "WinstoneResponse.HeaderAfterCommitted",
622:                            new String[] { name, value });
623:                } else if (value != null) {
624:                    if (name.equals(CONTENT_TYPE_HEADER)) {
625:                        StringBuffer remainderHeader = new StringBuffer();
626:                        String headerEncoding = getCharsetFromContentTypeHeader(
627:                                value, remainderHeader);
628:                        if (this .outputWriter != null) {
629:                            value = remainderHeader + ";charset="
630:                                    + getCharacterEncoding();
631:                        } else if (headerEncoding != null) {
632:                            this .explicitEncoding = headerEncoding;
633:                        }
634:                    }
635:                    this .headers.add(name + ": " + value);
636:                }
637:            }
638:
639:            public void setDateHeader(String name, long date) {
640:                setHeader(name, formatHeaderDate(new Date(date)));
641:            }
642:
643:            public void setIntHeader(String name, int value) {
644:                setHeader(name, "" + value);
645:            }
646:
647:            public void setHeader(String name, String value) {
648:                if (isIncluding()) {
649:                    Logger.log(Logger.DEBUG, Launcher.RESOURCES,
650:                            "WinstoneResponse.HeaderInInclude", new String[] {
651:                                    name, value });
652:                } else if (isCommitted()) {
653:                    Logger.log(Logger.DEBUG, Launcher.RESOURCES,
654:                            "WinstoneResponse.HeaderAfterCommitted",
655:                            new String[] { name, value });
656:                } else {
657:                    boolean found = false;
658:                    for (int n = 0; (n < this .headers.size()); n++) {
659:                        String header = (String) this .headers.get(n);
660:                        if (header.startsWith(name + ": ")) {
661:                            if (found) {
662:                                this .headers.remove(n);
663:                                continue;
664:                            }
665:                            if (name.equals(CONTENT_TYPE_HEADER)) {
666:                                if (value != null) {
667:                                    StringBuffer remainderHeader = new StringBuffer();
668:                                    String headerEncoding = getCharsetFromContentTypeHeader(
669:                                            value, remainderHeader);
670:                                    if (this .outputWriter != null) {
671:                                        value = remainderHeader + ";charset="
672:                                                + getCharacterEncoding();
673:                                    } else if (headerEncoding != null) {
674:                                        this .explicitEncoding = headerEncoding;
675:                                    }
676:                                }
677:                            }
678:
679:                            if (value != null) {
680:                                this .headers.set(n, name + ": " + value);
681:                            } else {
682:                                this .headers.remove(n);
683:                            }
684:                            found = true;
685:                        }
686:                    }
687:                    if (!found) {
688:                        addHeader(name, value);
689:                    }
690:                }
691:            }
692:
693:            private void forceHeader(String name, String value) {
694:                boolean found = false;
695:                for (int n = 0; (n < this .headers.size()); n++) {
696:                    String header = (String) this .headers.get(n);
697:                    if (header.startsWith(name + ": ")) {
698:                        found = true;
699:                        this .headers.set(n, name + ": " + value);
700:                    }
701:                }
702:                if (!found) {
703:                    this .headers.add(name + ": " + value);
704:                }
705:            }
706:
707:            private String getCurrentEncoding() {
708:                if (this .explicitEncoding != null) {
709:                    return this .explicitEncoding;
710:                } else if (this .implicitEncoding != null) {
711:                    return this .implicitEncoding;
712:                } else if ((this .req != null)
713:                        && (this .req.getCharacterEncoding() != null)) {
714:                    try {
715:                        "0".getBytes(this .req.getCharacterEncoding());
716:                        return this .req.getCharacterEncoding();
717:                    } catch (UnsupportedEncodingException err) {
718:                        return null;
719:                    }
720:                } else {
721:                    return null;
722:                }
723:            }
724:
725:            public String getHeader(String name) {
726:                for (int n = 0; n < this .headers.size(); n++) {
727:                    String header = (String) this .headers.get(n);
728:                    if (header.startsWith(name + ": "))
729:                        return header.substring(name.length() + 2);
730:                }
731:                return null;
732:            }
733:
734:            public String encodeRedirectURL(String url) {
735:                return url;
736:            }
737:
738:            public String encodeURL(String url) {
739:                return url;
740:            }
741:
742:            public int getStatus() {
743:                return this .statusCode;
744:            }
745:
746:            public Integer getErrorStatusCode() {
747:                return this .errorStatusCode;
748:            }
749:
750:            public void setStatus(int sc) {
751:                if (!isIncluding() && (this .errorStatusCode == null)) {
752:                    //        if (!isIncluding()) {
753:                    this .statusCode = sc;
754:                    //            if (this.errorStatusCode != null) {
755:                    //                this.errorStatusCode = new Integer(sc);
756:                    //            }
757:                }
758:            }
759:
760:            public void sendRedirect(String location) throws IOException {
761:                if (isIncluding()) {
762:                    Logger.log(Logger.ERROR, Launcher.RESOURCES,
763:                            "IncludeResponse.Redirect", location);
764:                    return;
765:                } else if (isCommitted()) {
766:                    throw new IllegalStateException(Launcher.RESOURCES
767:                            .getString("WinstoneOutputStream.AlreadyCommitted"));
768:                }
769:                resetBuffer();
770:
771:                // Build location
772:                StringBuffer fullLocation = new StringBuffer();
773:                if (location.startsWith("http://")
774:                        || location.startsWith("https://")) {
775:                    fullLocation.append(location);
776:                } else {
777:                    if (location.trim().equals(".")) {
778:                        location = "";
779:                    }
780:
781:                    fullLocation.append(this .req.getScheme()).append("://");
782:                    fullLocation.append(this .req.getServerName());
783:                    if (!((this .req.getServerPort() == 80) && this .req
784:                            .getScheme().equals("http"))
785:                            && !((this .req.getServerPort() == 443) && this .req
786:                                    .getScheme().equals("https")))
787:                        fullLocation.append(':').append(
788:                                this .req.getServerPort());
789:                    if (location.startsWith("/")) {
790:                        fullLocation.append(location);
791:                    } else {
792:                        fullLocation.append(this .req.getRequestURI());
793:                        int questionPos = fullLocation.toString().indexOf("?");
794:                        if (questionPos != -1) {
795:                            fullLocation.delete(questionPos, fullLocation
796:                                    .length());
797:                        }
798:                        fullLocation.delete(fullLocation.toString()
799:                                .lastIndexOf("/") + 1, fullLocation.length());
800:                        fullLocation.append(location);
801:                    }
802:                }
803:                if (this .req != null) {
804:                    this .req.discardRequestBody();
805:                }
806:                this .statusCode = HttpServletResponse.SC_MOVED_TEMPORARILY;
807:                setHeader(LOCATION_HEADER, fullLocation.toString());
808:                setContentLength(0);
809:                getWriter().flush();
810:            }
811:
812:            public void sendError(int sc) throws IOException {
813:                sendError(sc, null);
814:            }
815:
816:            public void sendError(int sc, String msg) throws IOException {
817:                if (isIncluding()) {
818:                    Logger.log(Logger.ERROR, Launcher.RESOURCES,
819:                            "IncludeResponse.Error", new String[] { "" + sc,
820:                                    msg });
821:                    return;
822:                }
823:
824:                Logger.log(Logger.DEBUG, Launcher.RESOURCES,
825:                        "WinstoneResponse.SendingError", new String[] {
826:                                "" + sc, msg });
827:
828:                if ((this .webAppConfig != null) && (this .req != null)) {
829:
830:                    RequestDispatcher rd = this .webAppConfig
831:                            .getErrorDispatcherByCode(sc, msg, null);
832:                    if (rd != null) {
833:                        try {
834:                            rd.forward(this .req, this );
835:                            return;
836:                        } catch (IllegalStateException err) {
837:                            throw err;
838:                        } catch (IOException err) {
839:                            throw err;
840:                        } catch (Throwable err) {
841:                            Logger
842:                                    .log(
843:                                            Logger.WARNING,
844:                                            Launcher.RESOURCES,
845:                                            "WinstoneResponse.ErrorInErrorPage",
846:                                            new String[] { rd.getName(),
847:                                                    sc + "" }, err);
848:                            return;
849:                        }
850:                    }
851:                }
852:                // If we are here there was no webapp and/or no request object, so 
853:                // show the default error page
854:                if (this .errorStatusCode == null) {
855:                    this .statusCode = sc;
856:                }
857:                String output = Launcher.RESOURCES.getString(
858:                        "WinstoneResponse.ErrorPage", new String[] { sc + "",
859:                                (msg == null ? "" : msg), "",
860:                                Launcher.RESOURCES.getString("ServerVersion"),
861:                                "" + new Date() });
862:                setContentLength(output.getBytes(getCharacterEncoding()).length);
863:                Writer out = getWriter();
864:                out.write(output);
865:                out.flush();
866:            }
867:
868:            /**
869:             * @deprecated
870:             */
871:            public String encodeRedirectUrl(String url) {
872:                return encodeRedirectURL(url);
873:            }
874:
875:            /**
876:             * @deprecated
877:             */
878:            public String encodeUrl(String url) {
879:                return encodeURL(url);
880:            }
881:
882:            /**
883:             * @deprecated
884:             */
885:            public void setStatus(int sc, String sm) {
886:                setStatus(sc);
887:            }
888:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.