KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icesoft > faces > webapp > parser > JspPageToDocument


1 /*
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * "The contents of this file are subject to the Mozilla Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
11  * License for the specific language governing rights and limitations under
12  * the License.
13  *
14  * The Original Code is ICEfaces 1.5 open source software code, released
15  * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
16  * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
17  * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
18  *
19  * Contributor(s): _____________________.
20  *
21  * Alternatively, the contents of this file may be used under the terms of
22  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
23  * License), in which case the provisions of the LGPL License are
24  * applicable instead of those above. If you wish to allow use of your
25  * version of this file only under the terms of the LGPL License and not to
26  * allow others to use your version of this file under the MPL, indicate
27  * your decision by deleting the provisions above and replace them with
28  * the notice and other provisions required by the LGPL License. If you do
29  * not delete the provisions above, a recipient may use your version of
30  * this file under either the MPL or the LGPL License."
31  *
32  */

33
34 package com.icesoft.faces.webapp.parser;
35
36 import com.icesoft.jasper.JasperException;
37 import com.icesoft.jasper.compiler.TldLocationsCache;
38 import com.icesoft.jasper.xmlparser.ParserUtils;
39 import com.icesoft.jasper.xmlparser.TreeNode;
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42
43 import javax.faces.context.ExternalContext;
44 import javax.faces.context.FacesContext;
45 import java.io.File JavaDoc;
46 import java.io.FileReader JavaDoc;
47 import java.io.IOException JavaDoc;
48 import java.io.InputStream JavaDoc;
49 import java.io.InputStreamReader JavaDoc;
50 import java.io.Reader JavaDoc;
51 import java.io.StringBufferInputStream JavaDoc;
52 import java.io.StringReader JavaDoc;
53 import java.io.StringWriter JavaDoc;
54 import java.net.JarURLConnection JavaDoc;
55 import java.net.URL JavaDoc;
56 import java.net.URLConnection JavaDoc;
57 import java.util.Arrays JavaDoc;
58 import java.util.Enumeration JavaDoc;
59 import java.util.Hashtable JavaDoc;
60 import java.util.Iterator JavaDoc;
61 import java.util.jar.JarEntry JavaDoc;
62 import java.util.jar.JarFile JavaDoc;
63 import java.util.regex.Matcher JavaDoc;
64 import java.util.regex.Pattern JavaDoc;
65 import java.util.zip.ZipEntry JavaDoc;
66
67 public class JspPageToDocument {
68     static String JavaDoc JSP_TAGLIB_PATTERN = "<%@\\s*taglib\\s+(.*?)%>";
69     static String JavaDoc URI_PATTERN = "uri=\"(.*?)\"";
70     static String JavaDoc PREFIX_PATTERN = "prefix=\"(.*?)\"";
71     static String JavaDoc JSP_DECL_PATTERN = "<%.*?%>";
72     static String JavaDoc STATIC_INCLUDE_PATTERN =
73             "<%@\\s*include\\s+file=\"([^\"]*)\".*?%>";
74     static String JavaDoc STATIC_INCLUDE_DIRECTIVE_PATTERN =
75             "<\\s*jsp:directive.include\\s+file=\"([^\"]*)\".*?/>";
76     static String JavaDoc OPEN_TAG_PATTERN = "<\\s*(\\w*\\:*\\w+)([^>]*)>";
77     static String JavaDoc GENERIC_TAG_PATTERN = "(<\\s*)(/*)(\\w+)([^:])";
78     static String JavaDoc ATTRIBUTE_PATTERN = "\\s*([^=]*)\\s*=\\s*\"([^\"]*)\"";
79     static String JavaDoc HTML_TAG_PATTERN = "<\\s*html";
80     static String JavaDoc P_TAG_PATTERN = "<\\s*/*(p)([^>]*?)/*>";
81     static String JavaDoc IMG_TAG_PATTERN = "<\\s*(img)([^>]*?)/*>";
82     static String JavaDoc JSP_INCLUDE_PATTERN = "<\\s*jsp:include([^>]*?)/>";
83     static String JavaDoc BR_TAG_PATTERN = "<\\s*br\\s*>";
84     static String JavaDoc HR_TAG_PATTERN = "<\\s*hr\\s*>";
85     static String JavaDoc LINK_TAG_PATTERN = "<\\s*(link)([^>]*?)/*>";
86     static String JavaDoc META_TAG_PATTERN = "<\\s*(meta)([^>]*?)/*>";
87     static String JavaDoc INPUT_TAG_PATTERN = "<\\s*(input)([^>]*?)/*>";
88     static String JavaDoc NBSP_ENTITY_PATTERN = "&nbsp";
89     static String JavaDoc COPY_ENTITY_PATTERN = "&copy;";
90     static String JavaDoc DOC_DECL_PATTERN = "<!DOCTYPE [^>]*>";
91     static String JavaDoc XML_DECL_PATTERN = "<\\?xml [^>]*\\?>";
92
93     static String JavaDoc MYFACES_TAG_CLASS =
94             "org/apache/myfaces/taglib/core/ViewTag.class";
95     static String JavaDoc SUN_TAG_CLASS = "com/sun/faces/taglib/jsf_core/ViewTag.class";
96
97     private static final Log log = LogFactory.getLog(JspPageToDocument.class);
98
99     public static void main(String JavaDoc[] args) {
100         try {
101             getInputAsString(transform(new FileReader JavaDoc(args[0])));
102         } catch (Exception JavaDoc e) {
103             e.printStackTrace();
104         }
105
106     }
107
108     /**
109      * @param input
110      * @return String
111      */

112     public static String JavaDoc transform(String JavaDoc input) {
113         String JavaDoc result = input;
114
115         Pattern JavaDoc jspDeclarationPattern =
116                 Pattern.compile(JSP_DECL_PATTERN, Pattern.DOTALL);
117         Matcher JavaDoc jspDeclarationMatcher = jspDeclarationPattern.matcher(result);
118         if (!jspDeclarationMatcher.find()) {
119             //no JSP declarations, must be a JSP Document, not a page
120
return (preprocessJspDocument(result));
121         }
122
123         result = performStaticInclude(STATIC_INCLUDE_PATTERN, input);
124
125         result = toLowerHTML(result);
126
127         Pattern JavaDoc jspTaglibPattern =
128                 Pattern.compile(JSP_TAGLIB_PATTERN, Pattern.DOTALL);
129         Pattern JavaDoc openTagPattern =
130                 Pattern.compile(OPEN_TAG_PATTERN, Pattern.DOTALL);
131         Pattern JavaDoc attributePattern =
132                 Pattern.compile(ATTRIBUTE_PATTERN, Pattern.DOTALL);
133         Pattern JavaDoc prefixPattern = Pattern.compile(PREFIX_PATTERN, Pattern.DOTALL);
134         Pattern JavaDoc uriPattern = Pattern.compile(URI_PATTERN, Pattern.DOTALL);
135
136         Hashtable JavaDoc declarationsTable = new Hashtable JavaDoc();
137         Matcher JavaDoc jspTaglibMatcher = jspTaglibPattern.matcher(result);
138         declarationsTable.put("xmlns:jsp", "jsp");
139         declarationsTable
140                 .put("xmlns:icefaces", "http://www.icesoft.com/icefaces");
141
142         while (jspTaglibMatcher.find()) {
143             String JavaDoc attributes = jspTaglibMatcher.group(1);
144             Matcher JavaDoc prefixMatcher = prefixPattern.matcher(attributes);
145             Matcher JavaDoc uriMatcher = uriPattern.matcher(attributes);
146             prefixMatcher.find();
147             uriMatcher.find();
148             String JavaDoc prefix = prefixMatcher.group(1);
149             String JavaDoc url = uriMatcher.group(1);
150             declarationsTable.put("xmlns:" + prefix, url);
151         }
152
153         Matcher JavaDoc openTagMatcher = openTagPattern.matcher(result);
154         openTagMatcher.find();
155         String JavaDoc tag = openTagMatcher.group(1);
156         String JavaDoc attributes = openTagMatcher.group(2);
157
158         Matcher JavaDoc attributeMatcher = attributePattern.matcher(attributes);
159         while (attributeMatcher.find()) {
160             String JavaDoc name = attributeMatcher.group(1);
161             String JavaDoc value = attributeMatcher.group(2);
162             declarationsTable.put(name, value);
163         }
164
165         Enumeration JavaDoc declarations = declarationsTable.keys();
166         String JavaDoc namespaceDeclarations = "";
167         while (declarations.hasMoreElements()) {
168             String JavaDoc prefix = (String JavaDoc) declarations.nextElement();
169             String JavaDoc url = (String JavaDoc) declarationsTable.get(prefix);
170             namespaceDeclarations += prefix + "=\"" + url + "\" ";
171         }
172
173         jspDeclarationMatcher = jspDeclarationPattern.matcher(result);
174         result = jspDeclarationMatcher.replaceAll("");
175
176         //ensure single root tag for all JSPs as per bug 361
177
result = "<icefaces:root " + namespaceDeclarations + ">" +
178                  result +
179                  "</icefaces:root>";
180
181         Pattern JavaDoc jspIncludePattern = Pattern.compile(JSP_INCLUDE_PATTERN);
182         Matcher JavaDoc jspIncludeMatcher = jspIncludePattern.matcher(result);
183         StringBuffer JavaDoc jspIncludeBuf = new StringBuffer JavaDoc();
184         while (jspIncludeMatcher.find()) {
185             String JavaDoc args = jspIncludeMatcher.group(1);
186             jspIncludeMatcher.appendReplacement(jspIncludeBuf,
187                                                 "<icefaces:include" + args +
188                                                 " isDynamic=\"#{true}\" />");
189         }
190         jspIncludeMatcher.appendTail(jspIncludeBuf);
191         result = jspIncludeBuf.toString();
192
193         //Fix HTML
194
result = toSingletonTag(P_TAG_PATTERN, result);
195         result = toSingletonTag(LINK_TAG_PATTERN, result);
196         result = toSingletonTag(META_TAG_PATTERN, result);
197         result = toSingletonTag(IMG_TAG_PATTERN, result);
198         result = toSingletonTag(INPUT_TAG_PATTERN, result);
199
200         Pattern JavaDoc brTagPattern = Pattern.compile(BR_TAG_PATTERN);
201         Matcher JavaDoc brTagMatcher = brTagPattern.matcher(result);
202         result = brTagMatcher.replaceAll("<br/>");
203
204         Pattern JavaDoc hrTagPattern = Pattern.compile(HR_TAG_PATTERN);
205         Matcher JavaDoc hrTagMatcher = hrTagPattern.matcher(result);
206         result = hrTagMatcher.replaceAll("<hr/>");
207
208         Pattern JavaDoc nbspEntityPattern = Pattern.compile(NBSP_ENTITY_PATTERN);
209         Matcher JavaDoc nbspEntityMatcher = nbspEntityPattern.matcher(result);
210         // result = nbspEntityMatcher.replaceAll("&nbsp;");
211
result = nbspEntityMatcher.replaceAll("&amp;nbsp");
212
213         Pattern JavaDoc copyEntityPattern = Pattern.compile(COPY_ENTITY_PATTERN);
214         Matcher JavaDoc copyEntityMatcher = copyEntityPattern.matcher(result);
215         result = copyEntityMatcher.replaceAll("&#169;");
216
217         Pattern JavaDoc docDeclPattern = Pattern.compile(DOC_DECL_PATTERN);
218         Matcher JavaDoc docDeclMatcher = docDeclPattern.matcher(result);
219         result = docDeclMatcher.replaceAll("");
220
221         result = unescapeBackslash(result);
222
223         return result;
224     }
225
226     static String JavaDoc preprocessJspDocument(String JavaDoc input) {
227         String JavaDoc result = input;
228         result = performStaticInclude(STATIC_INCLUDE_DIRECTIVE_PATTERN, input);
229         return result;
230     }
231
232     /**
233      * @param input
234      * @return Reader
235      */

236     public static Reader JavaDoc preprocessJspDocument(Reader JavaDoc input) {
237         String JavaDoc inputString = getInputAsString(input);
238         String JavaDoc outputString = preprocessJspDocument(inputString);
239         return new StringReader JavaDoc(outputString);
240     }
241
242     static String JavaDoc performStaticInclude(String JavaDoc includePatternString,
243                                        String JavaDoc input) {
244         String JavaDoc result = input;
245         boolean matchFound = true;
246
247         Pattern JavaDoc staticIncludePattern = Pattern.compile(includePatternString);
248         StringBuffer JavaDoc staticIncludeBuf;
249
250         while (matchFound) {
251             matchFound = false;
252             staticIncludeBuf = new StringBuffer JavaDoc();
253             Matcher JavaDoc staticIncludeMatcher = staticIncludePattern.matcher(result);
254             while (staticIncludeMatcher.find()) {
255                 matchFound = true;
256                 String JavaDoc args = staticIncludeMatcher.group(1);
257                 try {
258                     if (!args.startsWith("/")) {
259                         String JavaDoc servletPath = FacesContext.getCurrentInstance()
260                                 .getExternalContext().getRequestServletPath();
261                         String JavaDoc workingDir = servletPath.substring( 0,
262                                 servletPath.lastIndexOf("/") );
263                         args = workingDir + "/" + args;
264                     }
265                     String JavaDoc includeString = getInputAsString(
266                             new InputStreamReader JavaDoc(
267                                     FacesContext.getCurrentInstance()
268                                             .getExternalContext()
269                                             .getResource(args)
270                                             .openConnection()
271                                             .getInputStream()));
272                     //Strip xml declarations from included files
273
Pattern JavaDoc xmlDeclPattern = Pattern.compile(XML_DECL_PATTERN);
274                     Matcher JavaDoc xmlDeclMatcher =
275                             xmlDeclPattern.matcher(includeString);
276                     includeString = xmlDeclMatcher.replaceAll("");
277
278                     staticIncludeMatcher.appendReplacement(staticIncludeBuf,
279                                                            escapeBackreference(
280                                                                    includeString));
281                 } catch (Exception JavaDoc e) {
282                     //an error occurred, just remove the include
283
staticIncludeMatcher.appendReplacement(
284                             staticIncludeBuf, "");
285                     if (log.isErrorEnabled()) {
286                         log.error("static include failed to include " + args,
287                                   e);
288                     }
289                 }
290             }
291             staticIncludeMatcher.appendTail(staticIncludeBuf);
292             result = staticIncludeBuf.toString();
293         }
294         return result;
295     }
296
297     static String JavaDoc toSingletonTag(String JavaDoc pattern, String JavaDoc input) {
298         Pattern JavaDoc tagPattern = Pattern.compile(pattern, Pattern.DOTALL);
299         Matcher JavaDoc tagMatcher = tagPattern.matcher(input);
300         StringBuffer JavaDoc tagBuf = new StringBuffer JavaDoc();
301         while (tagMatcher.find()) {
302             String JavaDoc tagName = tagMatcher.group(1);
303             String JavaDoc attributes = tagMatcher.group(2);
304             tagMatcher.appendReplacement(tagBuf,
305                                          escapeBackreference("<" + tagName +
306                                                              attributes +
307                                                              "/>"));
308         }
309         tagMatcher.appendTail(tagBuf);
310         return tagBuf.toString();
311     }
312
313     /**
314      * @param input
315      * @return String
316      */

317     public static String JavaDoc toLowerHTML(String JavaDoc input) {
318         Pattern JavaDoc genericPattern =
319                 Pattern.compile(GENERIC_TAG_PATTERN);
320         Matcher JavaDoc genericMatcher = genericPattern.matcher(input);
321         StringBuffer JavaDoc inputBuffer = new StringBuffer JavaDoc();
322
323         while (genericMatcher.find()) {
324             String JavaDoc openBracket = genericMatcher.group(1);
325             String JavaDoc slash = genericMatcher.group(2);
326             String JavaDoc tagName = genericMatcher.group(3);
327             String JavaDoc trailing = genericMatcher.group(4);
328             if (!"HTML".equals(tagName)) {
329                 tagName = tagName.toLowerCase();
330             }
331             genericMatcher.appendReplacement(inputBuffer,
332                                              escapeBackreference(openBracket +
333                                                                  slash + tagName
334                                                                  + trailing));
335         }
336         genericMatcher.appendTail(inputBuffer);
337
338         return inputBuffer.toString();
339     }
340
341     /**
342      * @param input
343      * @return String
344      */

345     public static String JavaDoc escapeBackreference(String JavaDoc input) {
346         String JavaDoc result = input;
347
348         Pattern JavaDoc slashPattern =
349                 Pattern.compile("\\\\");
350         Matcher JavaDoc slashMatcher = slashPattern.matcher(result);
351         result = slashMatcher.replaceAll("\\\\\\\\");
352
353         Pattern JavaDoc dollarPattern =
354                 Pattern.compile("\\$");
355         Matcher JavaDoc dollarMatcher = dollarPattern.matcher(result);
356         result = dollarMatcher.replaceAll("\\\\\\$");
357
358         return result;
359     }
360
361     /**
362      * @param input
363      * @return String
364      */

365     public static String JavaDoc unescapeBackslash(String JavaDoc input) {
366         String JavaDoc result = input;
367
368         Pattern JavaDoc slashPattern =
369                 Pattern.compile("\\\\\\\\");
370         Matcher JavaDoc slashMatcher = slashPattern.matcher(result);
371         result = slashMatcher.replaceAll("\\\\");
372
373         return result;
374
375     }
376
377     /**
378      * @param input
379      * @return String
380      */

381     public static Reader JavaDoc transform(Reader JavaDoc input) {
382         String JavaDoc inputString = getInputAsString(input);
383         String JavaDoc outputString = transform(inputString);
384
385         if (log.isTraceEnabled()) {
386             log.trace(outputString);
387         }
388
389         return new StringReader JavaDoc(outputString);
390     }
391
392     /**
393      * @param context
394      * @param namespaceURL
395      * @return InputStream
396      * @throws IOException
397      */

398     public static InputStream JavaDoc getTldInputStream(
399             ExternalContext context, String JavaDoc namespaceURL)
400             throws IOException JavaDoc {
401
402         // InputStream in = null;
403
JarFile JavaDoc jarFile = null;
404         String JavaDoc[] location = null;
405
406         namespaceURL = String.valueOf(namespaceURL);
407
408         // "jsp" is only a placeholder for standard JSP tags that are
409
// not supported, so just return null
410

411         if ("jsp".equals(namespaceURL)) {
412             return null;
413         }
414
415         if ("http://java.sun.com/JSP/Page".equals(namespaceURL)) {
416             return null;
417         }
418
419         // TldLocationsCache may fail esp. with SecurityException on SUN app server
420
TldLocationsCache tldCache = new TldLocationsCache(context);
421         try {
422             location = tldCache.getLocation(namespaceURL);
423         } catch (Exception JavaDoc e) {
424             if (log.isDebugEnabled()) {
425                 log.debug(e.getMessage(), e);
426             }
427         }
428
429         if (null == location) {
430             if ( namespaceURL.startsWith("/") &&
431                  namespaceURL.endsWith(".tld") ) {
432                 location = new String JavaDoc[] {namespaceURL};
433             }
434         }
435
436         if (null == location) {
437             location = scanJars(context, namespaceURL);
438         }
439
440         if (null == location) {
441             //look for myfaces-impl.jar
442
URL JavaDoc tagURL = JspPageToDocument.class.getClassLoader()
443                     .getResource(MYFACES_TAG_CLASS);
444             if (null != tagURL) {
445                 location = scanJar((JarURLConnection JavaDoc) tagURL.openConnection(),
446                                    namespaceURL);
447             }
448         }
449
450         if (null == location) {
451             //look for myfaces-impl.jar
452
URL JavaDoc tagURL = JspPageToDocument.class.getClassLoader()
453                     .getResource(SUN_TAG_CLASS);
454             if (null != tagURL) {
455
456                 // Bug 876
457
// Not all app servers (ie WebLogic 8.1) return
458
// an actual JarURLConnection.
459
URLConnection JavaDoc conn = tagURL.openConnection();
460                 if (conn instanceof JarURLConnection JavaDoc) {
461                     location = scanJar((JarURLConnection JavaDoc) conn, namespaceURL);
462                 }
463             }
464         }
465
466         if (null == location) {
467             try {
468                 // scan WebSphere dirs for JSF jars
469
String JavaDoc separator = System.getProperty("path.separator");
470                 String JavaDoc wsDirs = System.getProperty("ws.ext.dirs");
471
472                 String JavaDoc[] dirs = null;
473                 if (null != wsDirs) {
474                     dirs = wsDirs.split(separator);
475                 } else {
476                     dirs = new String JavaDoc[]{};
477                 }
478                 Iterator JavaDoc theDirs = Arrays.asList(dirs).iterator();
479                 while (theDirs.hasNext()) {
480                     String JavaDoc dir = (String JavaDoc) theDirs.next();
481                     try {
482                         location = scanJars(dir, namespaceURL);
483                     } catch (Exception JavaDoc e) {
484                         //catch all possible exceptions including runtime exception
485
//so that the rest of jars still can be scanned.
486
}
487                     if (null != location) {
488                         break;
489                     }
490                 }
491             } catch (Exception JavaDoc e) {
492                 if (log.isDebugEnabled()) {
493                     log.debug(e.getMessage(), e);
494                 }
495             }
496         }
497
498         if (null == location) {
499             String JavaDoc msg = "Can't find TLD for location [" + namespaceURL +
500                          "]. JAR containing the TLD may not be in the classpath";
501             log.error(msg);
502             return null;
503         } else {
504             if (log.isTraceEnabled()) {
505                 for (int i = 0; i < location.length; i++) {
506                     log.trace("Found TLD location for " + namespaceURL + " = " +
507                               location[i]);
508                 }
509             }
510         }
511
512         if (!location[0].endsWith("jar")) {
513             return context.getResourceAsStream(location[0]);
514         } else {
515             // Tag library is packaged in JAR file
516
URL JavaDoc jarFileUrl = new URL JavaDoc("jar:" + location[0] + "!/");
517             JarURLConnection JavaDoc conn = (JarURLConnection JavaDoc) jarFileUrl
518                     .openConnection();
519             conn.setUseCaches(false);
520             conn.connect();
521             jarFile = conn.getJarFile();
522             ZipEntry JavaDoc jarEntry = jarFile.getEntry(location[1]);
523             return jarFile.getInputStream(jarEntry);
524         }
525
526     }
527
528     /**
529      * @param source
530      * @return InputStream
531      */

532     public static InputStream JavaDoc stripDoctype(InputStream JavaDoc source) {
533         String JavaDoc result = getInputAsString(new InputStreamReader JavaDoc(source));
534
535         Pattern JavaDoc docDeclPattern = Pattern.compile(DOC_DECL_PATTERN);
536         Matcher JavaDoc docDeclMatcher = docDeclPattern.matcher(result);
537         result = docDeclMatcher.replaceAll("");
538
539         return new StringBufferInputStream JavaDoc(result);
540     }
541
542     static String JavaDoc getInputAsString(Reader JavaDoc in) {
543         char[] buf = new char[1024];
544         StringWriter JavaDoc out = new StringWriter JavaDoc();
545
546         try {
547             int l = 1;
548             while (l > 0) {
549                 l = in.read(buf);
550                 if (l > 0) {
551                     out.write(buf, 0, l);
552                 }
553             }
554         } catch (IOException JavaDoc e) {
555             if (log.isWarnEnabled()) {
556                 log.warn(e.getMessage(), e);
557             }
558         }
559         return out.toString();
560
561     }
562
563     /*
564      * Scan all jars under WEB-INF/lib/
565      */

566     static String JavaDoc[] scanJars(ExternalContext context, String JavaDoc namespaceURL) {
567         try {
568             String JavaDoc[] location = null;
569             Iterator JavaDoc paths =
570                     context.getResourcePaths("/WEB-INF/lib/").iterator();
571             while (paths.hasNext()) {
572                 String JavaDoc path = (String JavaDoc) paths.next();
573                 if (!path.endsWith(".jar")) {
574                     continue;
575                 }
576                 path = context.getResource(path).toString();
577
578                 JarURLConnection JavaDoc connection = (JarURLConnection JavaDoc)
579                         new URL JavaDoc("jar:" + path + "!/").openConnection();
580                 location = scanJar(connection, namespaceURL);
581                 if (null != location) {
582                     return location;
583                 }
584             }
585         } catch (Exception JavaDoc e) {
586             if (log.isWarnEnabled()) {
587                 log.warn("Jar scanning under /WEB_INF/lib failed "
588                          + e.getMessage(), e);
589             }
590         }
591
592         return null;
593     }
594
595     /*
596      * Scan all jars under the given path
597      */

598     static String JavaDoc[] scanJars(String JavaDoc dir, String JavaDoc namespaceURL)
599             throws IOException JavaDoc {
600         String JavaDoc[] location = null;
601         Iterator JavaDoc paths = Arrays.asList(new File JavaDoc(dir).listFiles()).iterator();
602         while (paths.hasNext()) {
603             String JavaDoc path = ((File JavaDoc) paths.next()).getCanonicalPath();
604             if (!path.endsWith(".jar")) {
605                 continue;
606             }
607
608             URL JavaDoc url = new URL JavaDoc("jar:file:" + path + "!/");
609             JarURLConnection JavaDoc connection =
610                     (JarURLConnection JavaDoc) url.openConnection();
611             location = scanJar(connection, namespaceURL);
612             if (null != location) {
613                 return location;
614             }
615         }
616
617         return null;
618     }
619
620     static String JavaDoc[] scanJar(JarURLConnection JavaDoc conn, String JavaDoc namespaceURL)
621             throws IOException JavaDoc {
622         JarFile JavaDoc jarFile = null;
623         String JavaDoc resourcePath = conn.getJarFileURL().toString();
624
625         if (log.isTraceEnabled()) {
626             log.trace("Fallback Scanning Jar " + resourcePath);
627         }
628
629         jarFile = conn.getJarFile();
630         Enumeration JavaDoc entries = jarFile.entries();
631         while (entries.hasMoreElements()) {
632             try {
633                 JarEntry JavaDoc entry = (JarEntry JavaDoc) entries.nextElement();
634                 String JavaDoc name = entry.getName();
635                 if (!name.startsWith("META-INF/")) {
636                     continue;
637                 }
638                 if (!name.endsWith(".tld")) {
639                     continue;
640                 }
641                 InputStream JavaDoc stream = jarFile.getInputStream(entry);
642                 try {
643                     String JavaDoc uri = getUriFromTld(resourcePath, stream);
644                     if ((uri != null) && (uri.equals(namespaceURL))) {
645                         return (new String JavaDoc[]{resourcePath, name});
646                     }
647                 } catch (JasperException jpe) {
648                     if (log.isDebugEnabled()) {
649                         log.debug(jpe.getMessage(), jpe);
650                     }
651                 } finally {
652                     if (stream != null) {
653                         stream.close();
654                     }
655                 }
656             } catch (Throwable JavaDoc t) {
657                 if (log.isDebugEnabled()) {
658                     log.debug(t.getMessage(), t);
659                 }
660             }
661         }
662
663         return null;
664     }
665
666
667     /*
668      * Returns the value of the uri element of the given TLD, or null if the
669      * given TLD does not contain any such element.
670      */

671     static String JavaDoc getUriFromTld(String JavaDoc resourcePath, InputStream JavaDoc in)
672             throws JasperException {
673
674         // Parse the tag library descriptor at the specified resource path
675
TreeNode tld = new ParserUtils().parseXMLDocument(resourcePath, in);
676         TreeNode uri = tld.findChild("uri");
677         if (uri != null) {
678             String JavaDoc body = uri.getBody();
679             if (body != null) {
680                 return body;
681             }
682         }
683
684         return null;
685     }
686
687 }
688
Popular Tags