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