Source Code Cross Referenced for ImportSupport.java in  » Template-Engine » Velocity » org » apache » velocity » tools » view » 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 » Template Engine » Velocity » org.apache.velocity.tools.view 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.apache.velocity.tools.view;
002:
003:        /*
004:         * Licensed to the Apache Software Foundation (ASF) under one
005:         * or more contributor license agreements.  See the NOTICE file
006:         * distributed with this work for additional information
007:         * regarding copyright ownership.  The ASF licenses this file
008:         * to you under the Apache License, Version 2.0 (the
009:         * "License"); you may not use this file except in compliance
010:         * with the License.  You may obtain a copy of the License at
011:         *
012:         *   http://www.apache.org/licenses/LICENSE-2.0
013:         *
014:         * Unless required by applicable law or agreed to in writing,
015:         * software distributed under the License is distributed on an
016:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017:         * KIND, either express or implied.  See the License for the
018:         * specific language governing permissions and limitations
019:         * under the License.
020:         */
021:
022:        import java.io.BufferedReader;
023:        import java.io.ByteArrayOutputStream;
024:        import java.io.IOException;
025:        import java.io.InputStream;
026:        import java.io.InputStreamReader;
027:        import java.io.PrintWriter;
028:        import java.io.Reader;
029:        import java.io.StringReader;
030:        import java.io.StringWriter;
031:        import java.io.UnsupportedEncodingException;
032:        import java.net.HttpURLConnection;
033:        import java.net.URL;
034:        import java.net.URLConnection;
035:        import java.util.Locale;
036:
037:        import javax.servlet.RequestDispatcher;
038:        import javax.servlet.ServletContext;
039:        import javax.servlet.ServletOutputStream;
040:        import javax.servlet.http.HttpServletRequest;
041:        import javax.servlet.http.HttpServletResponse;
042:        import javax.servlet.http.HttpServletResponseWrapper;
043:
044:        import org.apache.commons.logging.Log;
045:        import org.apache.commons.logging.LogFactory;
046:
047:        /**
048:         * <p>Provides methods to import arbitrary local or remote resources as strings.</p>
049:         * <p>Based on ImportSupport from the JSTL taglib by Shawn Bayern</p>
050:         *
051:         * @author <a href="mailto:marinoj@centrum.is">Marino A. Jonsson</a>
052:         * @since VelocityTools 1.1
053:         * @version $Revision: 477914 $ $Date: 2006-11-21 13:52:11 -0800 (Tue, 21 Nov 2006) $
054:         */
055:        public abstract class ImportSupport {
056:
057:            protected static final Log LOG = LogFactory
058:                    .getLog(ImportSupport.class);
059:
060:            protected ServletContext application;
061:            protected HttpServletRequest request;
062:            protected HttpServletResponse response;
063:
064:            protected static final String VALID_SCHEME_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+.-";
065:
066:            /** Default character encoding for response. */
067:            protected static final String DEFAULT_ENCODING = "ISO-8859-1";
068:
069:            //*********************************************************************
070:            // URL importation logic
071:
072:            /*
073:             * Overall strategy:  we have two entry points, acquireString() and
074:             * acquireReader().  The latter passes data through unbuffered if
075:             * possible (but note that it is not always possible -- specifically
076:             * for cases where we must use the RequestDispatcher.  The remaining
077:             * methods handle the common.core logic of loading either a URL or a local
078:             * resource.
079:             *
080:             * We consider the 'natural' form of absolute URLs to be Readers and
081:             * relative URLs to be Strings.  Thus, to avoid doing extra work,
082:             * acquireString() and acquireReader() delegate to one another as
083:             * appropriate.  (Perhaps I could have spelled things out more clearly,
084:             * but I thought this implementation was instructive, not to mention
085:             * somewhat cute...)
086:             */
087:
088:            /**
089:             *
090:             * @param url the URL resource to return as string
091:             * @return the URL resource as string
092:             * @throws IOException
093:             * @throws java.lang.Exception
094:             */
095:            protected String acquireString(String url) throws IOException,
096:                    Exception {
097:                // Record whether our URL is absolute or relative
098:                if (isAbsoluteUrl(url)) {
099:                    // for absolute URLs, delegate to our peer
100:                    BufferedReader r = null;
101:                    try {
102:                        r = new BufferedReader(acquireReader(url));
103:                        StringBuffer sb = new StringBuffer();
104:                        int i;
105:                        // under JIT, testing seems to show this simple loop is as fast
106:                        // as any of the alternatives
107:                        while ((i = r.read()) != -1) {
108:                            sb.append((char) i);
109:                        }
110:                        return sb.toString();
111:                    } finally {
112:                        if (r != null) {
113:                            try {
114:                                r.close();
115:                            } catch (IOException ioe) {
116:                                LOG.error("Could not close reader.", ioe);
117:                            }
118:                        }
119:                    }
120:                } else // handle relative URLs ourselves
121:                {
122:                    // URL is relative, so we must be an HTTP request
123:                    if (!(request instanceof  HttpServletRequest && response instanceof  HttpServletResponse)) {
124:                        throw new Exception(
125:                                "Relative import from non-HTTP request not allowed");
126:                    }
127:
128:                    // retrieve an appropriate ServletContext
129:                    // normalize the URL if we have an HttpServletRequest
130:                    if (!url.startsWith("/")) {
131:                        String sp = ((HttpServletRequest) request)
132:                                .getServletPath();
133:                        url = sp.substring(0, sp.lastIndexOf('/')) + '/' + url;
134:                    }
135:
136:                    // strip the session id from the url
137:                    url = stripSession(url);
138:
139:                    // from this context, get a dispatcher
140:                    RequestDispatcher rd = application
141:                            .getRequestDispatcher(url);
142:                    if (rd == null) {
143:                        throw new Exception(
144:                                "Couldn't get a RequestDispatcher for \"" + url
145:                                        + "\"");
146:                    }
147:
148:                    // include the resource, using our custom wrapper
149:                    ImportResponseWrapper irw = new ImportResponseWrapper(
150:                            (HttpServletResponse) response);
151:                    try {
152:                        rd.include(request, irw);
153:                    } catch (IOException ex) {
154:                        throw new Exception(
155:                                "Problem importing the relative URL \"" + url
156:                                        + "\". " + ex);
157:                    } catch (RuntimeException ex) {
158:                        throw new Exception(
159:                                "Problem importing the relative URL \"" + url
160:                                        + "\". " + ex);
161:                    }
162:
163:                    // disallow inappropriate response codes per JSTL spec
164:                    if (irw.getStatus() < 200 || irw.getStatus() > 299) {
165:                        throw new Exception("Invalid response code '"
166:                                + irw.getStatus() + "' for \"" + url + "\"");
167:                    }
168:
169:                    // recover the response String from our wrapper
170:                    return irw.getString();
171:                }
172:            }
173:
174:            /**
175:             *
176:             * @param url the URL to read
177:             * @return a Reader for the InputStream created from the supplied URL
178:             * @throws IOException
179:             * @throws java.lang.Exception
180:             */
181:            protected Reader acquireReader(String url) throws IOException,
182:                    Exception {
183:                if (!isAbsoluteUrl(url)) {
184:                    // for relative URLs, delegate to our peer
185:                    return new StringReader(acquireString(url));
186:                } else {
187:                    // absolute URL
188:                    URLConnection uc = null;
189:                    HttpURLConnection huc = null;
190:                    InputStream i = null;
191:
192:                    try {
193:                        // handle absolute URLs ourselves, using java.net.URL
194:                        URL u = new URL(url);
195:                        // URL u = new URL("http", "proxy.hi.is", 8080, target);
196:                        uc = u.openConnection();
197:                        i = uc.getInputStream();
198:
199:                        // check response code for HTTP URLs, per spec,
200:                        if (uc instanceof  HttpURLConnection) {
201:                            huc = (HttpURLConnection) uc;
202:
203:                            int status = huc.getResponseCode();
204:                            if (status < 200 || status > 299) {
205:                                throw new Exception(status + " " + url);
206:                            }
207:                        }
208:
209:                        // okay, we've got a stream; encode it appropriately
210:                        Reader r = null;
211:                        String charSet;
212:
213:                        // charSet extracted according to RFC 2045, section 5.1
214:                        String contentType = uc.getContentType();
215:                        if (contentType != null) {
216:                            charSet = ImportSupport.getContentTypeAttribute(
217:                                    contentType, "charset");
218:                            if (charSet == null) {
219:                                charSet = DEFAULT_ENCODING;
220:                            }
221:                        } else {
222:                            charSet = DEFAULT_ENCODING;
223:                        }
224:
225:                        try {
226:                            r = new InputStreamReader(i, charSet);
227:                        } catch (UnsupportedEncodingException ueex) {
228:                            r = new InputStreamReader(i, DEFAULT_ENCODING);
229:                        }
230:
231:                        if (huc == null) {
232:                            return r;
233:                        } else {
234:                            return new SafeClosingHttpURLConnectionReader(r,
235:                                    huc);
236:                        }
237:                    } catch (IOException ex) {
238:                        if (i != null) {
239:                            try {
240:                                i.close();
241:                            } catch (IOException ioe) {
242:                                LOG.error("Could not close InputStream", ioe);
243:                            }
244:                        }
245:
246:                        if (huc != null) {
247:                            huc.disconnect();
248:                        }
249:                        throw new Exception(
250:                                "Problem accessing the absolute URL \"" + url
251:                                        + "\". " + ex);
252:                    } catch (RuntimeException ex) {
253:                        if (i != null) {
254:                            try {
255:                                i.close();
256:                            } catch (IOException ioe) {
257:                                LOG.error("Could not close InputStream", ioe);
258:                            }
259:                        }
260:
261:                        if (huc != null) {
262:                            huc.disconnect();
263:                        }
264:                        // because the spec makes us
265:                        throw new Exception(
266:                                "Problem accessing the absolute URL \"" + url
267:                                        + "\". " + ex);
268:                    }
269:                }
270:            }
271:
272:            protected static class SafeClosingHttpURLConnectionReader extends
273:                    Reader {
274:                private HttpURLConnection huc;
275:                private Reader wrappedReader;
276:
277:                SafeClosingHttpURLConnectionReader(Reader r,
278:                        HttpURLConnection huc) {
279:                    this .wrappedReader = r;
280:                    this .huc = huc;
281:                }
282:
283:                public void close() throws IOException {
284:                    if (null != huc) {
285:                        huc.disconnect();
286:                    }
287:
288:                    wrappedReader.close();
289:                }
290:
291:                // Pass-through methods.
292:                public void mark(int readAheadLimit) throws IOException {
293:                    wrappedReader.mark(readAheadLimit);
294:                }
295:
296:                public boolean markSupported() {
297:                    return wrappedReader.markSupported();
298:                }
299:
300:                public int read() throws IOException {
301:                    return wrappedReader.read();
302:                }
303:
304:                public int read(char[] buf) throws IOException {
305:                    return wrappedReader.read(buf);
306:                }
307:
308:                public int read(char[] buf, int off, int len)
309:                        throws IOException {
310:                    return wrappedReader.read(buf, off, len);
311:                }
312:
313:                public boolean ready() throws IOException {
314:                    return wrappedReader.ready();
315:                }
316:
317:                public void reset() throws IOException {
318:                    wrappedReader.reset();
319:                }
320:
321:                public long skip(long n) throws IOException {
322:                    return wrappedReader.skip(n);
323:                }
324:            }
325:
326:            /** Wraps responses to allow us to retrieve results as Strings. */
327:            protected class ImportResponseWrapper extends
328:                    HttpServletResponseWrapper {
329:                /*
330:                 * We provide either a Writer or an OutputStream as requested.
331:                 * We actually have a true Writer and an OutputStream backing
332:                 * both, since we don't want to use a character encoding both
333:                 * ways (Writer -> OutputStream -> Writer).  So we use no
334:                 * encoding at all (as none is relevant) when the target resource
335:                 * uses a Writer.  And we decode the OutputStream's bytes
336:                 * using OUR tag's 'charEncoding' attribute, or ISO-8859-1
337:                 * as the default.  We thus ignore setLocale() and setContentType()
338:                 * in this wrapper.
339:                 *
340:                 * In other words, the target's asserted encoding is used
341:                 * to convert from a Writer to an OutputStream, which is typically
342:                 * the medium through with the target will communicate its
343:                 * ultimate response.  Since we short-circuit that mechanism
344:                 * and read the target's characters directly if they're offered
345:                 * as such, we simply ignore the target's encoding assertion.
346:                 */
347:
348:                /** The Writer we convey. */
349:                private StringWriter sw;
350:
351:                /** A buffer, alternatively, to accumulate bytes. */
352:                private ByteArrayOutputStream bos;
353:
354:                /** 'True' if getWriter() was called; false otherwise. */
355:                private boolean isWriterUsed;
356:
357:                /** 'True if getOutputStream() was called; false otherwise. */
358:                private boolean isStreamUsed;
359:
360:                /** The HTTP status set by the target. */
361:                private int status = 200;
362:
363:                //************************************************************
364:                // Constructor and methods
365:
366:                /**
367:                 * Constructs a new ImportResponseWrapper.
368:                 * @param response the response to wrap
369:                 */
370:                public ImportResponseWrapper(HttpServletResponse response) {
371:                    super (response);
372:                }
373:
374:                /**
375:                 * @return a Writer designed to buffer the output.
376:                 */
377:                public PrintWriter getWriter() {
378:                    if (isStreamUsed) {
379:                        throw new IllegalStateException(
380:                                "Unexpected internal error during import: "
381:                                        + "Target servlet called getWriter(), then getOutputStream()");
382:                    }
383:                    isWriterUsed = true;
384:                    if (sw == null) {
385:                        sw = new StringWriter();
386:                    }
387:                    return new PrintWriter(sw);
388:                }
389:
390:                /**
391:                 * @return a ServletOutputStream designed to buffer the output.
392:                 */
393:                public ServletOutputStream getOutputStream() {
394:                    if (isWriterUsed) {
395:                        throw new IllegalStateException(
396:                                "Unexpected internal error during import: "
397:                                        + "Target servlet called getOutputStream(), then getWriter()");
398:                    }
399:                    isStreamUsed = true;
400:                    if (bos == null) {
401:                        bos = new ByteArrayOutputStream();
402:                    }
403:                    ServletOutputStream sos = new ServletOutputStream() {
404:                        public void write(int b) throws IOException {
405:                            bos.write(b);
406:                        }
407:                    };
408:                    return sos;
409:                }
410:
411:                /** Has no effect. */
412:                public void setContentType(String x) {
413:                    // ignore
414:                }
415:
416:                /** Has no effect. */
417:                public void setLocale(Locale x) {
418:                    // ignore
419:                }
420:
421:                /**
422:                 * Sets the status of the response
423:                 * @param status the status code
424:                 */
425:                public void setStatus(int status) {
426:                    this .status = status;
427:                }
428:
429:                /**
430:                 * @return the status of the response
431:                 */
432:                public int getStatus() {
433:                    return status;
434:                }
435:
436:                /**
437:                 * Retrieves the buffered output, using the containing tag's
438:                 * 'charEncoding' attribute, or the tag's default encoding,
439:                 * <b>if necessary</b>.
440:                 * @return the buffered output
441:                 * @throws UnsupportedEncodingException if the encoding is not supported
442:                 */
443:                public String getString() throws UnsupportedEncodingException {
444:                    if (isWriterUsed) {
445:                        return sw.toString();
446:                    } else if (isStreamUsed) {
447:                        return bos.toString(this .getCharacterEncoding());
448:                    } else {
449:                        return ""; // target didn't write anything
450:                    }
451:                }
452:            }
453:
454:            //*********************************************************************
455:            // Public utility methods
456:
457:            /**
458:             * Returns <tt>true</tt> if our current URL is absolute,
459:             * <tt>false</tt> otherwise.
460:             *
461:             * @param url the url to check out
462:             * @return true if the url is absolute
463:             */
464:            public static boolean isAbsoluteUrl(String url) {
465:                // a null URL is not absolute, by our definition
466:                if (url == null) {
467:                    return false;
468:                }
469:
470:                // do a fast, simple check first
471:                int colonPos;
472:                if ((colonPos = url.indexOf(":")) == -1) {
473:                    return false;
474:                }
475:
476:                // if we DO have a colon, make sure that every character
477:                // leading up to it is a valid scheme character
478:                for (int i = 0; i < colonPos; i++) {
479:                    if (VALID_SCHEME_CHARS.indexOf(url.charAt(i)) == -1) {
480:                        return false;
481:                    }
482:                }
483:                // if so, we've got an absolute url
484:                return true;
485:            }
486:
487:            /**
488:             * Strips a servlet session ID from <tt>url</tt>.  The session ID
489:             * is encoded as a URL "path parameter" beginning with "jsessionid=".
490:             * We thus remove anything we find between ";jsessionid=" (inclusive)
491:             * and either EOS or a subsequent ';' (exclusive).
492:             *
493:             * @param url the url to strip the session id from
494:             * @return the stripped url
495:             */
496:            public static String stripSession(String url) {
497:                StringBuffer u = new StringBuffer(url);
498:                int sessionStart;
499:                while ((sessionStart = u.toString().indexOf(";jsessionid=")) != -1) {
500:                    int sessionEnd = u.toString()
501:                            .indexOf(";", sessionStart + 1);
502:                    if (sessionEnd == -1) {
503:                        sessionEnd = u.toString()
504:                                .indexOf("?", sessionStart + 1);
505:                    }
506:                    if (sessionEnd == -1) {
507:                        // still
508:                        sessionEnd = u.length();
509:                    }
510:                    u.delete(sessionStart, sessionEnd);
511:                }
512:                return u.toString();
513:            }
514:
515:            /**
516:             * Get the value associated with a content-type attribute.
517:             * Syntax defined in RFC 2045, section 5.1.
518:             *
519:             * @param input the string containing the attributes
520:             * @param name the name of the content-type attribute
521:             * @return the value associated with a content-type attribute
522:             */
523:            public static String getContentTypeAttribute(String input,
524:                    String name) {
525:                int begin;
526:                int end;
527:                int index = input.toUpperCase().indexOf(name.toUpperCase());
528:                if (index == -1) {
529:                    return null;
530:                }
531:                index = index + name.length(); // positioned after the attribute name
532:                index = input.indexOf('=', index); // positioned at the '='
533:                if (index == -1) {
534:                    return null;
535:                }
536:                index += 1; // positioned after the '='
537:                input = input.substring(index).trim();
538:
539:                if (input.charAt(0) == '"') {
540:                    // attribute value is a quoted string
541:                    begin = 1;
542:                    end = input.indexOf('"', begin);
543:                    if (end == -1) {
544:                        return null;
545:                    }
546:                } else {
547:                    begin = 0;
548:                    end = input.indexOf(';');
549:                    if (end == -1) {
550:                        end = input.indexOf(' ');
551:                    }
552:                    if (end == -1) {
553:                        end = input.length();
554:                    }
555:                }
556:                return input.substring(begin, end).trim();
557:            }
558:
559:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.