Source Code Cross Referenced for TldLocationsCache.java in  » Sevlet-Container » tomcat-jasper2 » org » apache » jasper » compiler » 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 » Sevlet Container » tomcat jasper2 » org.apache.jasper.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 1999,2004 The Apache Software Foundation.
003:         * 
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         * 
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         * 
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:
017:        package org.apache.jasper.compiler;
018:
019:        import java.io.InputStream;
020:        import java.net.JarURLConnection;
021:        import java.net.URL;
022:        import java.net.URLClassLoader;
023:        import java.net.URLConnection;
024:        import java.util.Enumeration;
025:        import java.util.Hashtable;
026:        import java.util.HashSet;
027:        import java.util.Iterator;
028:        import java.util.Set;
029:        import java.util.StringTokenizer;
030:        import java.util.jar.JarEntry;
031:        import java.util.jar.JarFile;
032:
033:        import javax.servlet.ServletContext;
034:
035:        import org.apache.commons.logging.Log;
036:        import org.apache.commons.logging.LogFactory;
037:        import org.apache.jasper.JasperException;
038:        import org.apache.jasper.xmlparser.ParserUtils;
039:        import org.apache.jasper.xmlparser.TreeNode;
040:
041:        /**
042:         * A container for all tag libraries that are defined "globally"
043:         * for the web application.
044:         * 
045:         * Tag Libraries can be defined globally in one of two ways:
046:         *   1. Via <taglib> elements in web.xml:
047:         *      the uri and location of the tag-library are specified in
048:         *      the <taglib> element.
049:         *   2. Via packaged jar files that contain .tld files
050:         *      within the META-INF directory, or some subdirectory
051:         *      of it. The taglib is 'global' if it has the <uri>
052:         *      element defined.
053:         *
054:         * A mapping between the taglib URI and its associated TaglibraryInfoImpl
055:         * is maintained in this container.
056:         * Actually, that's what we'd like to do. However, because of the
057:         * way the classes TagLibraryInfo and TagInfo have been defined,
058:         * it is not currently possible to share an instance of TagLibraryInfo
059:         * across page invocations. A bug has been submitted to the spec lead.
060:         * In the mean time, all we do is save the 'location' where the
061:         * TLD associated with a taglib URI can be found.
062:         *
063:         * When a JSP page has a taglib directive, the mappings in this container
064:         * are first searched (see method getLocation()).
065:         * If a mapping is found, then the location of the TLD is returned.
066:         * If no mapping is found, then the uri specified
067:         * in the taglib directive is to be interpreted as the location for
068:         * the TLD of this tag library.
069:         *
070:         * @author Pierre Delisle
071:         * @author Jan Luehe
072:         */
073:
074:        public class TldLocationsCache {
075:
076:            // Logger
077:            private static Log log = LogFactory.getLog(TldLocationsCache.class);
078:
079:            /**
080:             * The types of URI one may specify for a tag library
081:             */
082:            public static final int ABS_URI = 0;
083:            public static final int ROOT_REL_URI = 1;
084:            public static final int NOROOT_REL_URI = 2;
085:
086:            private static final String WEB_XML = "/WEB-INF/web.xml";
087:            private static final String FILE_PROTOCOL = "file:";
088:            private static final String JAR_FILE_SUFFIX = ".jar";
089:
090:            // Names of JARs that are known not to contain any TLDs
091:            private static HashSet noTldJars;
092:
093:            /**
094:             * The mapping of the 'global' tag library URI to the location (resource
095:             * path) of the TLD associated with that tag library. The location is
096:             * returned as a String array:
097:             *    [0] The location
098:             *    [1] If the location is a jar file, this is the location of the tld.
099:             */
100:            private Hashtable mappings;
101:
102:            private boolean initialized;
103:            private ServletContext ctxt;
104:            private boolean redeployMode;
105:
106:            //*********************************************************************
107:            // Constructor and Initilizations
108:
109:            /*
110:             * Initializes the set of JARs that are known not to contain any TLDs
111:             */
112:            static {
113:                noTldJars = new HashSet();
114:                noTldJars.add("ant.jar");
115:                noTldJars.add("catalina.jar");
116:                noTldJars.add("catalina-ant.jar");
117:                noTldJars.add("catalina-cluster.jar");
118:                noTldJars.add("catalina-optional.jar");
119:                noTldJars.add("catalina-i18n-fr.jar");
120:                noTldJars.add("catalina-i18n-ja.jar");
121:                noTldJars.add("catalina-i18n-es.jar");
122:                noTldJars.add("commons-dbcp.jar");
123:                noTldJars.add("commons-modeler.jar");
124:                noTldJars.add("commons-logging-api.jar");
125:                noTldJars.add("commons-beanutils.jar");
126:                noTldJars.add("commons-fileupload-1.0.jar");
127:                noTldJars.add("commons-pool.jar");
128:                noTldJars.add("commons-digester.jar");
129:                noTldJars.add("commons-logging.jar");
130:                noTldJars.add("commons-collections.jar");
131:                noTldJars.add("commons-el.jar");
132:                noTldJars.add("jakarta-regexp-1.2.jar");
133:                noTldJars.add("jasper-compiler.jar");
134:                noTldJars.add("jasper-runtime.jar");
135:                noTldJars.add("jmx.jar");
136:                noTldJars.add("jmx-tools.jar");
137:                noTldJars.add("jsp-api.jar");
138:                noTldJars.add("jkshm.jar");
139:                noTldJars.add("jkconfig.jar");
140:                noTldJars.add("naming-common.jar");
141:                noTldJars.add("naming-resources.jar");
142:                noTldJars.add("naming-factory.jar");
143:                noTldJars.add("naming-java.jar");
144:                noTldJars.add("servlet-api.jar");
145:                noTldJars.add("servlets-default.jar");
146:                noTldJars.add("servlets-invoker.jar");
147:                noTldJars.add("servlets-common.jar");
148:                noTldJars.add("servlets-webdav.jar");
149:                noTldJars.add("tomcat-util.jar");
150:                noTldJars.add("tomcat-http11.jar");
151:                noTldJars.add("tomcat-jni.jar");
152:                noTldJars.add("tomcat-jk.jar");
153:                noTldJars.add("tomcat-jk2.jar");
154:                noTldJars.add("tomcat-coyote.jar");
155:                noTldJars.add("xercesImpl.jar");
156:                noTldJars.add("xmlParserAPIs.jar");
157:                noTldJars.add("xml-apis.jar");
158:                // JARs from J2SE runtime
159:                noTldJars.add("sunjce_provider.jar");
160:                noTldJars.add("ldapsec.jar");
161:                noTldJars.add("localedata.jar");
162:                noTldJars.add("dnsns.jar");
163:            }
164:
165:            public TldLocationsCache(ServletContext ctxt) {
166:                this (ctxt, true);
167:            }
168:
169:            /** Constructor. 
170:             *
171:             * @param ctxt the servlet context of the web application in which Jasper 
172:             * is running
173:             * @param redeployMode if true, then the compiler will allow redeploying 
174:             * a tag library from the same jar, at the expense of slowing down the
175:             * server a bit. Note that this may only work on JDK 1.3.1_01a and later,
176:             * because of JDK bug 4211817 fixed in this release.
177:             * If redeployMode is false, a faster but less capable mode will be used.
178:             */
179:            public TldLocationsCache(ServletContext ctxt, boolean redeployMode) {
180:                this .ctxt = ctxt;
181:                this .redeployMode = redeployMode;
182:                mappings = new Hashtable();
183:                initialized = false;
184:            }
185:
186:            /**
187:             * Sets the list of JARs that are known not to contain any TLDs.
188:             *
189:             * @param jarNames List of comma-separated names of JAR files that are 
190:             * known not to contain any TLDs 
191:             */
192:            public static void setNoTldJars(String jarNames) {
193:                if (jarNames != null) {
194:                    noTldJars.clear();
195:                    StringTokenizer tokenizer = new StringTokenizer(jarNames,
196:                            ",");
197:                    while (tokenizer.hasMoreElements()) {
198:                        noTldJars.add(tokenizer.nextToken());
199:                    }
200:                }
201:            }
202:
203:            /**
204:             * Gets the 'location' of the TLD associated with the given taglib 'uri'.
205:             *
206:             * Returns null if the uri is not associated with any tag library 'exposed'
207:             * in the web application. A tag library is 'exposed' either explicitly in
208:             * web.xml or implicitly via the uri tag in the TLD of a taglib deployed
209:             * in a jar file (WEB-INF/lib).
210:             * 
211:             * @param uri The taglib uri
212:             *
213:             * @return An array of two Strings: The first element denotes the real
214:             * path to the TLD. If the path to the TLD points to a jar file, then the
215:             * second element denotes the name of the TLD entry in the jar file.
216:             * Returns null if the uri is not associated with any tag library 'exposed'
217:             * in the web application.
218:             */
219:            public String[] getLocation(String uri) throws JasperException {
220:                if (!initialized) {
221:                    init();
222:                }
223:                return (String[]) mappings.get(uri);
224:            }
225:
226:            /** 
227:             * Returns the type of a URI:
228:             *     ABS_URI
229:             *     ROOT_REL_URI
230:             *     NOROOT_REL_URI
231:             */
232:            public static int uriType(String uri) {
233:                if (uri.indexOf(':') != -1) {
234:                    return ABS_URI;
235:                } else if (uri.startsWith("/")) {
236:                    return ROOT_REL_URI;
237:                } else {
238:                    return NOROOT_REL_URI;
239:                }
240:            }
241:
242:            private void init() throws JasperException {
243:                if (initialized)
244:                    return;
245:                try {
246:                    processWebDotXml();
247:                    scanJars();
248:                    processTldsInFileSystem("/WEB-INF/");
249:                    initialized = true;
250:                } catch (Exception ex) {
251:                    throw new JasperException(Localizer.getMessage(
252:                            "jsp.error.internal.tldinit", ex.getMessage()));
253:                }
254:            }
255:
256:            /*
257:             * Populates taglib map described in web.xml.
258:             */
259:            private void processWebDotXml() throws Exception {
260:
261:                InputStream is = null;
262:
263:                try {
264:                    // Acquire input stream to web application deployment descriptor
265:                    is = ctxt.getResourceAsStream(WEB_XML);
266:                    if (is == null) {
267:                        if (log.isWarnEnabled()) {
268:                            log
269:                                    .warn(Localizer.getMessage(
270:                                            "jsp.error.internal.filenotfound",
271:                                            WEB_XML));
272:                        }
273:                        return;
274:                    }
275:
276:                    // Parse the web application deployment descriptor
277:                    TreeNode webtld = new ParserUtils().parseXMLDocument(
278:                            WEB_XML, is);
279:
280:                    // Allow taglib to be an element of the root or jsp-config (JSP2.0)
281:                    TreeNode jspConfig = webtld.findChild("jsp-config");
282:                    if (jspConfig != null) {
283:                        webtld = jspConfig;
284:                    }
285:                    Iterator taglibs = webtld.findChildren("taglib");
286:                    while (taglibs.hasNext()) {
287:
288:                        // Parse the next <taglib> element
289:                        TreeNode taglib = (TreeNode) taglibs.next();
290:                        String tagUri = null;
291:                        String tagLoc = null;
292:                        TreeNode child = taglib.findChild("taglib-uri");
293:                        if (child != null)
294:                            tagUri = child.getBody();
295:                        child = taglib.findChild("taglib-location");
296:                        if (child != null)
297:                            tagLoc = child.getBody();
298:
299:                        // Save this location if appropriate
300:                        if (tagLoc == null)
301:                            continue;
302:                        if (uriType(tagLoc) == NOROOT_REL_URI)
303:                            tagLoc = "/WEB-INF/" + tagLoc;
304:                        String tagLoc2 = null;
305:                        if (tagLoc.endsWith(JAR_FILE_SUFFIX)) {
306:                            tagLoc = ctxt.getResource(tagLoc).toString();
307:                            tagLoc2 = "META-INF/taglib.tld";
308:                        }
309:                        mappings.put(tagUri, new String[] { tagLoc, tagLoc2 });
310:                    }
311:                } finally {
312:                    if (is != null) {
313:                        try {
314:                            is.close();
315:                        } catch (Throwable t) {
316:                        }
317:                    }
318:                }
319:            }
320:
321:            /**
322:             * Scans the given JarURLConnection for TLD files located in META-INF
323:             * (or a subdirectory of it), adding an implicit map entry to the taglib
324:             * map for any TLD that has a <uri> element.
325:             *
326:             * @param conn The JarURLConnection to the JAR file to scan
327:             * @param ignore true if any exceptions raised when processing the given
328:             * JAR should be ignored, false otherwise
329:             */
330:            private void scanJar(JarURLConnection conn, boolean ignore)
331:                    throws JasperException {
332:
333:                JarFile jarFile = null;
334:                String resourcePath = conn.getJarFileURL().toString();
335:                try {
336:                    if (redeployMode) {
337:                        conn.setUseCaches(false);
338:                    }
339:                    jarFile = conn.getJarFile();
340:                    Enumeration entries = jarFile.entries();
341:                    while (entries.hasMoreElements()) {
342:                        JarEntry entry = (JarEntry) entries.nextElement();
343:                        String name = entry.getName();
344:                        if (!name.startsWith("META-INF/"))
345:                            continue;
346:                        if (!name.endsWith(".tld"))
347:                            continue;
348:                        InputStream stream = jarFile.getInputStream(entry);
349:                        try {
350:                            String uri = getUriFromTld(resourcePath, stream);
351:                            // Add implicit map entry only if its uri is not already
352:                            // present in the map
353:                            if (uri != null && mappings.get(uri) == null) {
354:                                mappings.put(uri, new String[] { resourcePath,
355:                                        name });
356:                            }
357:                        } finally {
358:                            if (stream != null) {
359:                                try {
360:                                    stream.close();
361:                                } catch (Throwable t) {
362:                                    // do nothing
363:                                }
364:                            }
365:                        }
366:                    }
367:                } catch (Exception ex) {
368:                    if (!redeployMode) {
369:                        // if not in redeploy mode, close the jar in case of an error
370:                        if (jarFile != null) {
371:                            try {
372:                                jarFile.close();
373:                            } catch (Throwable t) {
374:                                // ignore
375:                            }
376:                        }
377:                    }
378:                    if (!ignore) {
379:                        throw new JasperException(ex);
380:                    }
381:                } finally {
382:                    if (redeployMode) {
383:                        // if in redeploy mode, always close the jar
384:                        if (jarFile != null) {
385:                            try {
386:                                jarFile.close();
387:                            } catch (Throwable t) {
388:                                // ignore
389:                            }
390:                        }
391:                    }
392:                }
393:            }
394:
395:            /*
396:             * Searches the filesystem under /WEB-INF for any TLD files, and adds
397:             * an implicit map entry to the taglib map for any TLD that has a <uri>
398:             * element.
399:             */
400:            private void processTldsInFileSystem(String startPath)
401:                    throws Exception {
402:
403:                Set dirList = ctxt.getResourcePaths(startPath);
404:                if (dirList != null) {
405:                    Iterator it = dirList.iterator();
406:                    while (it.hasNext()) {
407:                        String path = (String) it.next();
408:                        if (path.endsWith("/")) {
409:                            processTldsInFileSystem(path);
410:                        }
411:                        if (!path.endsWith(".tld")) {
412:                            continue;
413:                        }
414:                        InputStream stream = ctxt.getResourceAsStream(path);
415:                        String uri = null;
416:                        try {
417:                            uri = getUriFromTld(path, stream);
418:                        } finally {
419:                            if (stream != null) {
420:                                try {
421:                                    stream.close();
422:                                } catch (Throwable t) {
423:                                    // do nothing
424:                                }
425:                            }
426:                        }
427:                        // Add implicit map entry only if its uri is not already
428:                        // present in the map
429:                        if (uri != null && mappings.get(uri) == null) {
430:                            mappings.put(uri, new String[] { path, null });
431:                        }
432:                    }
433:                }
434:            }
435:
436:            /*
437:             * Returns the value of the uri element of the given TLD, or null if the
438:             * given TLD does not contain any such element.
439:             */
440:            private String getUriFromTld(String resourcePath, InputStream in)
441:                    throws JasperException {
442:                // Parse the tag library descriptor at the specified resource path
443:                TreeNode tld = new ParserUtils().parseXMLDocument(resourcePath,
444:                        in);
445:                TreeNode uri = tld.findChild("uri");
446:                if (uri != null) {
447:                    String body = uri.getBody();
448:                    if (body != null)
449:                        return body;
450:                }
451:
452:                return null;
453:            }
454:
455:            /*
456:             * Scans all JARs accessible to the webapp's classloader and its
457:             * parent classloaders for TLDs.
458:             * 
459:             * The list of JARs always includes the JARs under WEB-INF/lib, as well as
460:             * all shared JARs in the classloader delegation chain of the webapp's
461:             * classloader.
462:             *
463:             * Considering JARs in the classloader delegation chain constitutes a
464:             * Tomcat-specific extension to the TLD search
465:             * order defined in the JSP spec. It allows tag libraries packaged as JAR
466:             * files to be shared by web applications by simply dropping them in a 
467:             * location that all web applications have access to (e.g.,
468:             * <CATALINA_HOME>/common/lib).
469:             *
470:             * The set of shared JARs to be scanned for TLDs is narrowed down by
471:             * the <tt>noTldJars</tt> class variable, which contains the names of JARs
472:             * that are known not to contain any TLDs.
473:             */
474:            private void scanJars() throws Exception {
475:
476:                ClassLoader webappLoader = Thread.currentThread()
477:                        .getContextClassLoader();
478:                ClassLoader loader = webappLoader;
479:
480:                while (loader != null) {
481:                    if (loader instanceof  URLClassLoader) {
482:                        URL[] urls = ((URLClassLoader) loader).getURLs();
483:                        for (int i = 0; i < urls.length; i++) {
484:                            URLConnection conn = urls[i].openConnection();
485:                            if (conn instanceof  JarURLConnection) {
486:                                if (needScanJar(loader, webappLoader,
487:                                        ((JarURLConnection) conn).getJarFile()
488:                                                .getName())) {
489:                                    scanJar((JarURLConnection) conn, true);
490:                                }
491:                            } else {
492:                                String urlStr = urls[i].toString();
493:                                if (urlStr.startsWith(FILE_PROTOCOL)
494:                                        && urlStr.endsWith(JAR_FILE_SUFFIX)
495:                                        && needScanJar(loader, webappLoader,
496:                                                urlStr)) {
497:                                    URL jarURL = new URL("jar:" + urlStr + "!/");
498:                                    scanJar((JarURLConnection) jarURL
499:                                            .openConnection(), true);
500:                                }
501:                            }
502:                        }
503:                    }
504:
505:                    loader = loader.getParent();
506:                }
507:            }
508:
509:            /*
510:             * Determines if the JAR file with the given <tt>jarPath</tt> needs to be
511:             * scanned for TLDs.
512:             *
513:             * @param loader The current classloader in the parent chain
514:             * @param webappLoader The webapp classloader
515:             * @param jarPath The JAR file path
516:             *
517:             * @return TRUE if the JAR file identified by <tt>jarPath</tt> needs to be
518:             * scanned for TLDs, FALSE otherwise
519:             */
520:            private boolean needScanJar(ClassLoader loader,
521:                    ClassLoader webappLoader, String jarPath) {
522:                if (loader == webappLoader) {
523:                    // JARs under WEB-INF/lib must be scanned unconditionally according
524:                    // to the spec.
525:                    return true;
526:                } else {
527:                    String jarName = jarPath;
528:                    int slash = jarPath.lastIndexOf('/');
529:                    if (slash >= 0) {
530:                        jarName = jarPath.substring(slash + 1);
531:                    }
532:                    return (!noTldJars.contains(jarName));
533:                }
534:            }
535:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.