1 16 17 package com.icesoft.jasper.compiler; 18 19 import com.icesoft.jasper.JasperException; 20 import com.icesoft.jasper.xmlparser.ParserUtils; 21 import com.icesoft.jasper.xmlparser.TreeNode; 22 import org.apache.commons.logging.Log; 23 import org.apache.commons.logging.LogFactory; 24 25 import javax.faces.context.ExternalContext; 26 import java.io.IOException ; 27 import java.io.InputStream ; 28 import java.net.JarURLConnection ; 29 import java.net.URL ; 30 import java.net.URLClassLoader ; 31 import java.net.URLConnection ; 32 import java.util.Enumeration ; 33 import java.util.HashSet ; 34 import java.util.Hashtable ; 35 import java.util.Iterator ; 36 import java.util.Set ; 37 import java.util.StringTokenizer ; 38 import java.util.jar.JarEntry ; 39 import java.util.jar.JarFile ; 40 41 68 69 public class TldLocationsCache { 70 71 private static Log log = LogFactory.getLog(TldLocationsCache.class); 73 74 77 public static final int ABS_URI = 0; 78 public static final int ROOT_REL_URI = 1; 79 public static final int NOROOT_REL_URI = 2; 80 81 private static final String WEB_XML = "/WEB-INF/web.xml"; 82 private static final String FILE_PROTOCOL = "file:"; 83 private static final String JAR_FILE_SUFFIX = ".jar"; 84 85 private static HashSet noTldJars; 87 88 94 private Hashtable mappings; 95 96 private boolean initialized; 97 private ExternalContext ctxt; 98 private boolean redeployMode; 99 100 103 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 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 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 188 public static void setNoTldJars(String jarNames) { 189 if (jarNames != null) { 190 noTldJars.clear(); 191 StringTokenizer tokenizer = new StringTokenizer (jarNames, ","); 192 while (tokenizer.hasMoreElements()) { 193 noTldJars.add(tokenizer.nextToken()); 194 } 195 } 196 } 197 198 213 public String [] getLocation(String uri) throws JasperException { 214 if (!initialized) { 215 init(); 216 } 217 return (String []) mappings.get(uri); 218 } 219 220 223 public static int uriType(String uri) { 224 if (uri.indexOf(':') != -1) { 225 return ABS_URI; 226 } else if (uri.startsWith("/")) { 227 return ROOT_REL_URI; 228 } else { 229 return NOROOT_REL_URI; 230 } 231 } 232 233 private void init() throws JasperException { 234 if (initialized) return; 235 try { 236 if (log.isDebugEnabled()) { 237 log.debug("Initializing ICEfaces TldLocationsCache"); 238 } 239 processWebDotXml(); 240 scanJars(); 241 processTldsInFileSystem("/WEB-INF/"); 242 initialized = true; 243 } catch (Exception ex) { 244 throw new JasperException(Localizer.getMessage( 249 "jsp.error.internal.tldinit", ex.getMessage())); 250 } 251 } 252 253 256 private void processWebDotXml() throws Exception { 257 258 InputStream is = null; 259 260 try { 261 is = ctxt.getResourceAsStream(WEB_XML); 263 if (is == null) { 264 if (log.isWarnEnabled()) { 265 log.warn(Localizer.getMessage( 266 "jsp.error.internal.filenotfound", 267 WEB_XML)); 268 } 269 return; 270 } 271 272 TreeNode webtld = new ParserUtils().parseXMLDocument(WEB_XML, is); 274 275 TreeNode jspConfig = webtld.findChild("jsp-config"); 277 if (jspConfig != null) { 278 webtld = jspConfig; 279 } 280 Iterator taglibs = webtld.findChildren("taglib"); 281 while (taglibs.hasNext()) { 282 283 TreeNode taglib = (TreeNode) taglibs.next(); 285 String tagUri = null; 286 String tagLoc = null; 287 TreeNode child = taglib.findChild("taglib-uri"); 288 if (child != null) 289 tagUri = child.getBody(); 290 child = taglib.findChild("taglib-location"); 291 if (child != null) 292 tagLoc = child.getBody(); 293 294 if (tagLoc == null) 296 continue; 297 if (uriType(tagLoc) == NOROOT_REL_URI) 298 tagLoc = "/WEB-INF/" + tagLoc; 299 String tagLoc2 = null; 300 if (tagLoc.endsWith(JAR_FILE_SUFFIX)) { 301 tagLoc = ctxt.getResource(tagLoc).toString(); 302 tagLoc2 = "META-INF/taglib.tld"; 303 } 304 mappings.put(tagUri, new String []{tagLoc, tagLoc2}); 305 } 306 } finally { 307 if (is != null) { 308 try { 309 is.close(); 310 } catch (IOException e) { 311 if (log.isDebugEnabled()) { 312 log.debug(e.getLocalizedMessage(), e); 313 } 314 } 315 } 316 } 317 } 318 319 328 private void scanJar(JarURLConnection conn, boolean ignore) 329 throws JasperException { 330 331 JarFile jarFile = null; 332 String resourcePath = conn.getJarFileURL().toString(); 333 try { 334 if (redeployMode) { 335 conn.setUseCaches(false); 336 } 337 jarFile = conn.getJarFile(); 338 Enumeration entries = jarFile.entries(); 339 while (entries.hasMoreElements()) { 340 JarEntry entry = (JarEntry ) entries.nextElement(); 341 String name = entry.getName(); 342 if (!name.startsWith("META-INF/")) continue; 343 if (!name.endsWith(".tld")) continue; 344 InputStream stream = jarFile.getInputStream(entry); 345 try { 346 String uri = getUriFromTld(resourcePath, stream); 347 if (uri != null && mappings.get(uri) == null) { 350 mappings.put(uri, new String []{resourcePath, name}); 351 } 352 } finally { 353 if (stream != null) { 354 try { 355 stream.close(); 356 } catch (IOException e) { 357 if (log.isDebugEnabled()) { 358 log.debug(e.getLocalizedMessage(), e); 359 } 360 } 361 } 362 } 363 } 364 } catch (IOException ex) { 365 if (log.isDebugEnabled()) { 366 log.debug(ex.getMessage(), ex); 367 } 368 if (!redeployMode) { 369 if (jarFile != null) { 371 try { 372 jarFile.close(); 373 } catch (IOException e) { 374 if (log.isDebugEnabled()) { 375 log.debug(e.getLocalizedMessage(), e); 376 } 377 } 378 } 379 } 380 if (!ignore) { 381 throw new JasperException(ex); 382 } 383 } finally { 384 if (redeployMode) { 385 if (jarFile != null) { 387 try { 388 jarFile.close(); 389 } catch (IOException e) { 390 if (log.isDebugEnabled()) { 391 log.debug(e.getLocalizedMessage(), e); 392 } 393 } 394 } 395 } 396 } 397 } 398 399 404 private void processTldsInFileSystem(String startPath) 405 throws Exception { 406 407 Set dirList = ctxt.getResourcePaths(startPath); 408 if (dirList != null) { 409 Iterator it = dirList.iterator(); 410 while (it.hasNext()) { 411 String path = (String ) it.next(); 412 if (path.endsWith("/")) { 413 processTldsInFileSystem(path); 414 } 415 if (!path.endsWith(".tld")) { 416 continue; 417 } 418 InputStream stream = ctxt.getResourceAsStream(path); 419 String uri = null; 420 try { 421 uri = getUriFromTld(path, stream); 422 } finally { 423 if (stream != null) { 424 try { 425 stream.close(); 426 } catch (Throwable t) { 427 } 429 } 430 } 431 if (uri != null && mappings.get(uri) == null) { 434 mappings.put(uri, new String []{path, null}); 435 } 436 } 437 } 438 } 439 440 444 private String getUriFromTld(String resourcePath, InputStream in) 445 throws JasperException { 446 TreeNode tld = new ParserUtils().parseXMLDocument(resourcePath, in); 448 if( tld != null ){ 449 TreeNode uri = tld.findChild("uri"); 450 if (uri != null) { 451 String body = uri.getBody(); 452 if (body != null) 453 return body; 454 } 455 } 456 457 return null; 458 } 459 460 479 private void scanJars() throws Exception { 480 481 ClassLoader webappLoader 482 = Thread.currentThread().getContextClassLoader(); 483 ClassLoader loader = webappLoader; 484 485 while (loader != null) { 486 if (loader instanceof URLClassLoader ) { 487 URL [] urls = ((URLClassLoader ) loader).getURLs(); 488 if (null != urls) { 489 for (int i = 0; i < urls.length; i++) { 490 URLConnection conn = urls[i].openConnection(); 491 if (conn instanceof JarURLConnection ) { 492 if (needScanJar(loader, webappLoader, 493 ((JarURLConnection ) conn) 494 .getJarFile().getName())) { 495 scanJar((JarURLConnection ) conn, true); 496 } 497 } else { 498 String urlStr = urls[i].toString(); 499 if (urlStr.startsWith(FILE_PROTOCOL) 500 && urlStr.endsWith(JAR_FILE_SUFFIX) 501 && 502 needScanJar(loader, webappLoader, urlStr)) { 503 URL jarURL = new URL ("jar:" + urlStr + "!/"); 504 scanJar((JarURLConnection ) jarURL 505 .openConnection(), 506 true); 507 } 508 } 509 } 510 } 511 } 512 513 loader = loader.getParent(); 514 } 515 } 516 517 528 private boolean needScanJar(ClassLoader loader, ClassLoader webappLoader, 529 String jarPath) { 530 if (loader == webappLoader) { 531 return true; 534 } else { 535 String jarName = jarPath; 536 int slash = jarPath.lastIndexOf('/'); 537 if (slash >= 0) { 538 jarName = jarPath.substring(slash + 1); 539 } 540 return (!noTldJars.contains(jarName)); 541 } 542 } 543 } 544 | Popular Tags |