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