Source Code Cross Referenced for TldConfig.java in  » Sevlet-Container » apache-tomcat-6.0.14 » org » apache » catalina » startup » 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 » apache tomcat 6.0.14 » org.apache.catalina.startup 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         * 
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:
018:        package org.apache.catalina.startup;
019:
020:        import java.io.File;
021:        import java.io.FileInputStream;
022:        import java.io.FileOutputStream;
023:        import java.io.IOException;
024:        import java.io.InputStream;
025:        import java.io.ObjectInputStream;
026:        import java.io.ObjectOutputStream;
027:        import java.net.URISyntaxException;
028:        import java.net.URL;
029:        import java.net.URLClassLoader;
030:        import java.util.ArrayList;
031:        import java.util.Enumeration;
032:        import java.util.HashMap;
033:        import java.util.HashSet;
034:        import java.util.Iterator;
035:        import java.util.Map;
036:        import java.util.Set;
037:        import java.util.StringTokenizer;
038:        import java.util.jar.JarEntry;
039:        import java.util.jar.JarFile;
040:
041:        import javax.naming.NameClassPair;
042:        import javax.naming.NamingEnumeration;
043:        import javax.naming.NamingException;
044:        import javax.naming.directory.DirContext;
045:        import javax.servlet.ServletException;
046:
047:        import org.apache.catalina.Context;
048:        import org.apache.catalina.Globals;
049:        import org.apache.catalina.core.StandardContext;
050:        import org.apache.catalina.util.StringManager;
051:        import org.apache.tomcat.util.digester.Digester;
052:        import org.xml.sax.InputSource;
053:
054:        /**
055:         * Startup event listener for a <b>Context</b> that configures the properties
056:         * of that Context, and the associated defined servlets.
057:         *
058:         * @author Craig R. McClanahan
059:         * @author Jean-Francois Arcand
060:         * @author Costin Manolache
061:         */
062:        public final class TldConfig {
063:
064:            // Names of JARs that are known not to contain any TLDs
065:            private static HashSet<String> noTldJars;
066:
067:            private static org.apache.juli.logging.Log log = org.apache.juli.logging.LogFactory
068:                    .getLog(TldConfig.class);
069:
070:            /*
071:             * Initializes the set of JARs that are known not to contain any TLDs
072:             */
073:            static {
074:                noTldJars = new HashSet<String>();
075:                // Bootstrap JARs
076:                noTldJars.add("bootstrap.jar");
077:                noTldJars.add("commons-daemon.jar");
078:                noTldJars.add("tomcat-juli.jar");
079:                // Main JARs
080:                noTldJars.add("annotations-api.jar");
081:                noTldJars.add("catalina.jar");
082:                noTldJars.add("catalina-ant.jar");
083:                noTldJars.add("catalina-ha.jar");
084:                noTldJars.add("catalina-tribes.jar");
085:                noTldJars.add("el-api.jar");
086:                noTldJars.add("jasper.jar");
087:                noTldJars.add("jasper-el.jar");
088:                noTldJars.add("jasper-jdt.jar");
089:                noTldJars.add("jsp-api.jar");
090:                noTldJars.add("servlet-api.jar");
091:                noTldJars.add("tomcat-coyote.jar");
092:                noTldJars.add("tomcat-dbcp.jar");
093:                // i18n JARs
094:                noTldJars.add("tomcat-i18n-en.jar");
095:                noTldJars.add("tomcat-i18n-es.jar");
096:                noTldJars.add("tomcat-i18n-fr.jar");
097:                noTldJars.add("tomcat-i18n-ja.jar");
098:                // Misc JARs not included with Tomcat
099:                noTldJars.add("ant.jar");
100:                noTldJars.add("commons-dbcp.jar");
101:                noTldJars.add("commons-beanutils.jar");
102:                noTldJars.add("commons-fileupload-1.0.jar");
103:                noTldJars.add("commons-pool.jar");
104:                noTldJars.add("commons-digester.jar");
105:                noTldJars.add("commons-logging.jar");
106:                noTldJars.add("commons-collections.jar");
107:                noTldJars.add("jmx.jar");
108:                noTldJars.add("jmx-tools.jar");
109:                noTldJars.add("xercesImpl.jar");
110:                noTldJars.add("xmlParserAPIs.jar");
111:                noTldJars.add("xml-apis.jar");
112:                // JARs from J2SE runtime
113:                noTldJars.add("sunjce_provider.jar");
114:                noTldJars.add("ldapsec.jar");
115:                noTldJars.add("localedata.jar");
116:                noTldJars.add("dnsns.jar");
117:                noTldJars.add("tools.jar");
118:                noTldJars.add("sunpkcs11.jar");
119:            }
120:
121:            // ----------------------------------------------------- Instance Variables
122:
123:            /**
124:             * The Context we are associated with.
125:             */
126:            private Context context = null;
127:
128:            /**
129:             * The string resources for this package.
130:             */
131:            private static final StringManager sm = StringManager
132:                    .getManager(Constants.Package);
133:
134:            /**
135:             * The <code>Digester</code> we will use to process tag library
136:             * descriptor files.
137:             */
138:            private static Digester tldDigester = null;
139:
140:            /**
141:             * Attribute value used to turn on/off TLD validation
142:             */
143:            private static boolean tldValidation = false;
144:
145:            /**
146:             * Attribute value used to turn on/off TLD  namespace awarenes.
147:             */
148:            private static boolean tldNamespaceAware = false;
149:
150:            private boolean rescan = true;
151:
152:            private ArrayList<String> listeners = new ArrayList<String>();
153:
154:            // --------------------------------------------------------- Public Methods
155:
156:            /**
157:             * Sets the list of JARs that are known not to contain any TLDs.
158:             *
159:             * @param jarNames List of comma-separated names of JAR files that are 
160:             * known not to contain any TLDs 
161:             */
162:            public static void setNoTldJars(String jarNames) {
163:                if (jarNames != null) {
164:                    noTldJars.clear();
165:                    StringTokenizer tokenizer = new StringTokenizer(jarNames,
166:                            ",");
167:                    while (tokenizer.hasMoreElements()) {
168:                        noTldJars.add(tokenizer.nextToken());
169:                    }
170:                }
171:            }
172:
173:            /**
174:             * Set the validation feature of the XML parser used when
175:             * parsing xml instances.
176:             * @param tldValidation true to enable xml instance validation
177:             */
178:            public void setTldValidation(boolean tldValidation) {
179:                TldConfig.tldValidation = tldValidation;
180:            }
181:
182:            /**
183:             * Get the server.xml <host> attribute's xmlValidation.
184:             * @return true if validation is enabled.
185:             *
186:             */
187:            public boolean getTldValidation() {
188:                return tldValidation;
189:            }
190:
191:            /**
192:             * Get the server.xml <host> attribute's xmlNamespaceAware.
193:             * @return true if namespace awarenes is enabled.
194:             *
195:             */
196:            public boolean getTldNamespaceAware() {
197:                return tldNamespaceAware;
198:            }
199:
200:            /**
201:             * Set the namespace aware feature of the XML parser used when
202:             * parsing xml instances.
203:             * @param tldNamespaceAware true to enable namespace awareness
204:             */
205:            public void setTldNamespaceAware(boolean tldNamespaceAware) {
206:                TldConfig.tldNamespaceAware = tldNamespaceAware;
207:            }
208:
209:            public boolean isRescan() {
210:                return rescan;
211:            }
212:
213:            public void setRescan(boolean rescan) {
214:                this .rescan = rescan;
215:            }
216:
217:            public Context getContext() {
218:                return context;
219:            }
220:
221:            public void setContext(Context context) {
222:                this .context = context;
223:            }
224:
225:            public void addApplicationListener(String s) {
226:                //if(log.isDebugEnabled())
227:                log.debug("Add tld listener " + s);
228:                listeners.add(s);
229:            }
230:
231:            public String[] getTldListeners() {
232:                String result[] = new String[listeners.size()];
233:                listeners.toArray(result);
234:                return result;
235:            }
236:
237:            /**
238:             * Scan for and configure all tag library descriptors found in this
239:             * web application.
240:             *
241:             * @exception Exception if a fatal input/output or parsing error occurs
242:             */
243:            public void execute() throws Exception {
244:                long t1 = System.currentTimeMillis();
245:
246:                File tldCache = null;
247:
248:                if (context instanceof  StandardContext) {
249:                    File workDir = (File) ((StandardContext) context)
250:                            .getServletContext().getAttribute(
251:                                    Globals.WORK_DIR_ATTR);
252:                    //tldCache=new File( workDir, "tldCache.ser");
253:                }
254:
255:                // Option to not rescan
256:                if (!rescan) {
257:                    // find the cache
258:                    if (tldCache != null && tldCache.exists()) {
259:                        // just read it...
260:                        processCache(tldCache);
261:                        return;
262:                    }
263:                }
264:
265:                /*
266:                 * Acquire the list of TLD resource paths, possibly embedded in JAR
267:                 * files, to be processed
268:                 */
269:                Set resourcePaths = tldScanResourcePaths();
270:                Map jarPaths = getJarPaths();
271:
272:                // Check to see if we can use cached listeners
273:                if (tldCache != null && tldCache.exists()) {
274:                    long lastModified = getLastModified(resourcePaths, jarPaths);
275:                    if (lastModified < tldCache.lastModified()) {
276:                        processCache(tldCache);
277:                        return;
278:                    }
279:                }
280:
281:                // Scan each accumulated resource path for TLDs to be processed
282:                Iterator paths = resourcePaths.iterator();
283:                while (paths.hasNext()) {
284:                    String path = (String) paths.next();
285:                    if (path.endsWith(".jar")) {
286:                        tldScanJar(path);
287:                    } else {
288:                        tldScanTld(path);
289:                    }
290:                }
291:                if (jarPaths != null) {
292:                    paths = jarPaths.values().iterator();
293:                    while (paths.hasNext()) {
294:                        tldScanJar((File) paths.next());
295:                    }
296:                }
297:
298:                String list[] = getTldListeners();
299:
300:                if (tldCache != null) {
301:                    log.debug("Saving tld cache: " + tldCache + " "
302:                            + list.length);
303:                    try {
304:                        FileOutputStream out = new FileOutputStream(tldCache);
305:                        ObjectOutputStream oos = new ObjectOutputStream(out);
306:                        oos.writeObject(list);
307:                        oos.close();
308:                    } catch (IOException ex) {
309:                        ex.printStackTrace();
310:                    }
311:                }
312:
313:                if (log.isDebugEnabled())
314:                    log.debug("Adding tld listeners:" + list.length);
315:                for (int i = 0; list != null && i < list.length; i++) {
316:                    context.addApplicationListener(list[i]);
317:                }
318:
319:                long t2 = System.currentTimeMillis();
320:                if (context instanceof  StandardContext) {
321:                    ((StandardContext) context).setTldScanTime(t2 - t1);
322:                }
323:
324:            }
325:
326:            // -------------------------------------------------------- Private Methods
327:
328:            /*
329:             * Returns the last modification date of the given sets of resources.
330:             *
331:             * @param resourcePaths
332:             * @param jarPaths
333:             *
334:             * @return Last modification date
335:             */
336:            private long getLastModified(Set resourcePaths, Map jarPaths)
337:                    throws Exception {
338:
339:                long lastModified = 0;
340:
341:                Iterator paths = resourcePaths.iterator();
342:                while (paths.hasNext()) {
343:                    String path = (String) paths.next();
344:                    URL url = context.getServletContext().getResource(path);
345:                    if (url == null) {
346:                        log.debug("Null url " + path);
347:                        break;
348:                    }
349:                    long lastM = url.openConnection().getLastModified();
350:                    if (lastM > lastModified)
351:                        lastModified = lastM;
352:                    if (log.isDebugEnabled()) {
353:                        log.debug("Last modified " + path + " " + lastM);
354:                    }
355:                }
356:
357:                if (jarPaths != null) {
358:                    paths = jarPaths.values().iterator();
359:                    while (paths.hasNext()) {
360:                        File jarFile = (File) paths.next();
361:                        long lastM = jarFile.lastModified();
362:                        if (lastM > lastModified)
363:                            lastModified = lastM;
364:                        if (log.isDebugEnabled()) {
365:                            log.debug("Last modified "
366:                                    + jarFile.getAbsolutePath() + " " + lastM);
367:                        }
368:                    }
369:                }
370:
371:                return lastModified;
372:            }
373:
374:            private void processCache(File tldCache) throws IOException {
375:                // read the cache and return;
376:                try {
377:                    FileInputStream in = new FileInputStream(tldCache);
378:                    ObjectInputStream ois = new ObjectInputStream(in);
379:                    String list[] = (String[]) ois.readObject();
380:                    if (log.isDebugEnabled())
381:                        log.debug("Reusing tldCache " + tldCache + " "
382:                                + list.length);
383:                    for (int i = 0; list != null && i < list.length; i++) {
384:                        context.addApplicationListener(list[i]);
385:                    }
386:                    ois.close();
387:                } catch (ClassNotFoundException ex) {
388:                    ex.printStackTrace();
389:                }
390:            }
391:
392:            /**
393:             * Create (if necessary) and return a Digester configured to process a tag
394:             * library descriptor, looking for additional listener classes to be
395:             * registered.
396:             */
397:            private static Digester createTldDigester() {
398:
399:                return DigesterFactory.newDigester(tldValidation,
400:                        tldNamespaceAware, new TldRuleSet());
401:
402:            }
403:
404:            /**
405:             * Scan the JAR file at the specified resource path for TLDs in the
406:             * <code>META-INF</code> subdirectory, and scan each TLD for application
407:             * event listeners that need to be registered.
408:             *
409:             * @param resourcePath Resource path of the JAR file to scan
410:             *
411:             * @exception Exception if an exception occurs while scanning this JAR
412:             */
413:            private void tldScanJar(String resourcePath) throws Exception {
414:
415:                if (log.isDebugEnabled()) {
416:                    log.debug(" Scanning JAR at resource path '" + resourcePath
417:                            + "'");
418:                }
419:
420:                URL url = context.getServletContext().getResource(resourcePath);
421:                if (url == null) {
422:                    throw new IllegalArgumentException(sm.getString(
423:                            "contextConfig.tldResourcePath", resourcePath));
424:                }
425:
426:                File file = null;
427:                try {
428:                    file = new File(url.toURI());
429:                } catch (URISyntaxException e) {
430:                    // Ignore, probably an unencoded char
431:                    file = new File(url.getFile());
432:                }
433:                try {
434:                    file = file.getCanonicalFile();
435:                } catch (IOException e) {
436:                    // Ignore
437:                }
438:                tldScanJar(file);
439:
440:            }
441:
442:            /**
443:             * Scans all TLD entries in the given JAR for application listeners.
444:             *
445:             * @param file JAR file whose TLD entries are scanned for application
446:             * listeners
447:             */
448:            private void tldScanJar(File file) throws Exception {
449:
450:                JarFile jarFile = null;
451:                String name = null;
452:
453:                String jarPath = file.getAbsolutePath();
454:
455:                try {
456:                    jarFile = new JarFile(file);
457:                    Enumeration entries = jarFile.entries();
458:                    while (entries.hasMoreElements()) {
459:                        JarEntry entry = (JarEntry) entries.nextElement();
460:                        name = entry.getName();
461:                        if (!name.startsWith("META-INF/")) {
462:                            continue;
463:                        }
464:                        if (!name.endsWith(".tld")) {
465:                            continue;
466:                        }
467:                        if (log.isTraceEnabled()) {
468:                            log.trace("  Processing TLD at '" + name + "'");
469:                        }
470:                        try {
471:                            tldScanStream(new InputSource(jarFile
472:                                    .getInputStream(entry)));
473:                        } catch (Exception e) {
474:                            log.error(sm.getString(
475:                                    "contextConfig.tldEntryException", name,
476:                                    jarPath, context.getPath()), e);
477:                        }
478:                    }
479:                } catch (Exception e) {
480:                    log.error(sm.getString("contextConfig.tldJarException",
481:                            jarPath, context.getPath()), e);
482:                } finally {
483:                    if (jarFile != null) {
484:                        try {
485:                            jarFile.close();
486:                        } catch (Throwable t) {
487:                            // Ignore
488:                        }
489:                    }
490:                }
491:            }
492:
493:            /**
494:             * Scan the TLD contents in the specified input stream, and register
495:             * any application event listeners found there.  <b>NOTE</b> - It is
496:             * the responsibility of the caller to close the InputStream after this
497:             * method returns.
498:             *
499:             * @param resourceStream InputStream containing a tag library descriptor
500:             *
501:             * @exception Exception if an exception occurs while scanning this TLD
502:             */
503:            private void tldScanStream(InputSource resourceStream)
504:                    throws Exception {
505:
506:                if (tldDigester == null) {
507:                    tldDigester = createTldDigester();
508:                }
509:
510:                synchronized (tldDigester) {
511:                    try {
512:                        tldDigester.push(this );
513:                        tldDigester.parse(resourceStream);
514:                    } finally {
515:                        tldDigester.reset();
516:                    }
517:                }
518:
519:            }
520:
521:            /**
522:             * Scan the TLD contents at the specified resource path, and register
523:             * any application event listeners found there.
524:             *
525:             * @param resourcePath Resource path being scanned
526:             *
527:             * @exception Exception if an exception occurs while scanning this TLD
528:             */
529:            private void tldScanTld(String resourcePath) throws Exception {
530:
531:                if (log.isDebugEnabled()) {
532:                    log.debug(" Scanning TLD at resource path '" + resourcePath
533:                            + "'");
534:                }
535:
536:                InputSource inputSource = null;
537:                try {
538:                    InputStream stream = context.getServletContext()
539:                            .getResourceAsStream(resourcePath);
540:                    if (stream == null) {
541:                        throw new IllegalArgumentException(sm.getString(
542:                                "contextConfig.tldResourcePath", resourcePath));
543:                    }
544:                    inputSource = new InputSource(stream);
545:                    if (inputSource == null) {
546:                        throw new IllegalArgumentException(sm.getString(
547:                                "contextConfig.tldResourcePath", resourcePath));
548:                    }
549:                    tldScanStream(inputSource);
550:                } catch (Exception e) {
551:                    throw new ServletException(sm.getString(
552:                            "contextConfig.tldFileException", resourcePath,
553:                            context.getPath()), e);
554:                }
555:
556:            }
557:
558:            /**
559:             * Accumulate and return a Set of resource paths to be analyzed for
560:             * tag library descriptors.  Each element of the returned set will be
561:             * the context-relative path to either a tag library descriptor file,
562:             * or to a JAR file that may contain tag library descriptors in its
563:             * <code>META-INF</code> subdirectory.
564:             *
565:             * @exception IOException if an input/output error occurs while
566:             *  accumulating the list of resource paths
567:             */
568:            private Set tldScanResourcePaths() throws IOException {
569:                if (log.isDebugEnabled()) {
570:                    log.debug(" Accumulating TLD resource paths");
571:                }
572:                Set resourcePaths = new HashSet();
573:
574:                // Accumulate resource paths explicitly listed in the web application
575:                // deployment descriptor
576:                if (log.isTraceEnabled()) {
577:                    log.trace("  Scanning <taglib> elements in web.xml");
578:                }
579:                String taglibs[] = context.findTaglibs();
580:                for (int i = 0; i < taglibs.length; i++) {
581:                    String resourcePath = context.findTaglib(taglibs[i]);
582:                    // FIXME - Servlet 2.4 DTD implies that the location MUST be
583:                    // a context-relative path starting with '/'?
584:                    if (!resourcePath.startsWith("/")) {
585:                        resourcePath = "/WEB-INF/" + resourcePath;
586:                    }
587:                    if (log.isTraceEnabled()) {
588:                        log.trace("   Adding path '" + resourcePath
589:                                + "' for URI '" + taglibs[i] + "'");
590:                    }
591:                    resourcePaths.add(resourcePath);
592:                }
593:
594:                DirContext resources = context.getResources();
595:                if (resources != null) {
596:                    tldScanResourcePathsWebInf(resources, "/WEB-INF",
597:                            resourcePaths);
598:                }
599:
600:                // Return the completed set
601:                return (resourcePaths);
602:
603:            }
604:
605:            /*
606:             * Scans the web application's subdirectory identified by rootPath,
607:             * along with its subdirectories, for TLDs.
608:             *
609:             * Initially, rootPath equals /WEB-INF. The /WEB-INF/classes and
610:             * /WEB-INF/lib subdirectories are excluded from the search, as per the
611:             * JSP 2.0 spec.
612:             *
613:             * @param resources The web application's resources
614:             * @param rootPath The path whose subdirectories are to be searched for
615:             * TLDs
616:             * @param tldPaths The set of TLD resource paths to add to
617:             */
618:            private void tldScanResourcePathsWebInf(DirContext resources,
619:                    String rootPath, Set tldPaths) throws IOException {
620:
621:                if (log.isTraceEnabled()) {
622:                    log.trace("  Scanning TLDs in " + rootPath
623:                            + " subdirectory");
624:                }
625:
626:                try {
627:                    NamingEnumeration items = resources.list(rootPath);
628:                    while (items.hasMoreElements()) {
629:                        NameClassPair item = (NameClassPair) items
630:                                .nextElement();
631:                        String resourcePath = rootPath + "/" + item.getName();
632:                        if (!resourcePath.endsWith(".tld")
633:                                && (resourcePath.startsWith("/WEB-INF/classes") || resourcePath
634:                                        .startsWith("/WEB-INF/lib"))) {
635:                            continue;
636:                        }
637:                        if (resourcePath.endsWith(".tld")) {
638:                            if (log.isTraceEnabled()) {
639:                                log.trace("   Adding path '" + resourcePath
640:                                        + "'");
641:                            }
642:                            tldPaths.add(resourcePath);
643:                        } else {
644:                            tldScanResourcePathsWebInf(resources, resourcePath,
645:                                    tldPaths);
646:                        }
647:                    }
648:                } catch (NamingException e) {
649:                    ; // Silent catch: it's valid that no /WEB-INF directory exists
650:                }
651:            }
652:
653:            /**
654:             * Returns a map of the paths to all JAR files that are accessible to the
655:             * webapp and will be scanned for TLDs.
656:             *
657:             * The map always includes all the JARs under WEB-INF/lib, as well as
658:             * shared JARs in the classloader delegation chain of the webapp's
659:             * classloader.
660:             *
661:             * The latter constitutes a Tomcat-specific extension to the TLD search
662:             * order defined in the JSP spec. It allows tag libraries packaged as JAR
663:             * files to be shared by web applications by simply dropping them in a 
664:             * location that all web applications have access to (e.g.,
665:             * <CATALINA_HOME>/common/lib).
666:             *
667:             * The set of shared JARs to be scanned for TLDs is narrowed down by
668:             * the <tt>noTldJars</tt> class variable, which contains the names of JARs
669:             * that are known not to contain any TLDs.
670:             *
671:             * @return Map of JAR file paths
672:             */
673:            private Map getJarPaths() {
674:
675:                HashMap jarPathMap = null;
676:
677:                ClassLoader webappLoader = Thread.currentThread()
678:                        .getContextClassLoader();
679:                ClassLoader loader = webappLoader;
680:                while (loader != null) {
681:                    if (loader instanceof  URLClassLoader) {
682:                        URL[] urls = ((URLClassLoader) loader).getURLs();
683:                        for (int i = 0; i < urls.length; i++) {
684:                            // Expect file URLs, these are %xx encoded or not depending on
685:                            // the class loader
686:                            // This is definitely not as clean as using JAR URLs either
687:                            // over file or the custom jndi handler, but a lot less
688:                            // buggy overall
689:                            File file = null;
690:                            try {
691:                                file = new File(urls[i].toURI());
692:                            } catch (URISyntaxException e) {
693:                                // Ignore, probably an unencoded char
694:                                file = new File(urls[i].getFile());
695:                            }
696:                            try {
697:                                file = file.getCanonicalFile();
698:                            } catch (IOException e) {
699:                                // Ignore
700:                            }
701:                            if (!file.exists()) {
702:                                continue;
703:                            }
704:                            String path = file.getAbsolutePath();
705:                            if (!path.endsWith(".jar")) {
706:                                continue;
707:                            }
708:                            /*
709:                             * Scan all JARs from WEB-INF/lib, plus any shared JARs
710:                             * that are not known not to contain any TLDs
711:                             */
712:                            if (loader == webappLoader || noTldJars == null
713:                                    || !noTldJars.contains(file.getName())) {
714:                                if (jarPathMap == null) {
715:                                    jarPathMap = new HashMap();
716:                                    jarPathMap.put(path, file);
717:                                } else if (!jarPathMap.containsKey(path)) {
718:                                    jarPathMap.put(path, file);
719:                                }
720:                            }
721:                        }
722:                    }
723:                    loader = loader.getParent();
724:                }
725:
726:                return jarPathMap;
727:            }
728:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.