1 19 20 package org.netbeans.modules.web.jspparser_ext; 21 22 import java.beans.PropertyChangeListener ; 23 import java.io.File ; 24 import java.io.FileFilter ; 25 import java.io.IOException ; 26 import java.lang.reflect.Field ; 27 import java.net.MalformedURLException ; 28 import java.net.URL ; 29 import java.net.URLClassLoader ; 30 import java.security.CodeSource ; 31 import java.security.PermissionCollection ; 32 import java.util.ArrayList ; 33 import java.util.Date ; 34 import java.util.Enumeration ; 35 import java.util.HashMap ; 36 import java.util.HashSet ; 37 import java.util.Hashtable ; 38 import java.util.Iterator ; 39 import java.util.Map ; 40 import java.util.Set ; 41 import java.util.regex.Matcher ; 42 import java.util.regex.Pattern ; 43 import javax.servlet.ServletContext ; 44 import org.openide.filesystems.FileObject; 45 import org.openide.filesystems.FileUtil; 46 import org.openide.filesystems.FileStateInvalidException; 47 import org.openide.ErrorManager; 48 import org.openide.util.NbBundle; 49 50 import org.netbeans.modules.web.jsps.parserapi.JspParserAPI; 51 import org.netbeans.modules.web.jsps.parserapi.Node; 52 import org.netbeans.modules.web.jsps.parserapi.PageInfo; 53 import org.netbeans.modules.web.jspparser.*; 54 55 import org.apache.jasper.Options; 56 import org.apache.jasper.JspCompilationContext; 57 import org.apache.jasper.JasperException; 58 import org.apache.jasper.compiler.ExtractPageData; 59 import org.apache.jasper.compiler.GetParseData; 60 import org.apache.jasper.compiler.JspRuntimeContext; 61 import org.apache.jasper.compiler.TldLocationsCache; 62 import org.netbeans.api.java.classpath.ClassPath; 63 import org.netbeans.modules.web.jspparser_ext.OptionsImpl; 64 import org.openide.filesystems.URLMapper; 65 66 77 public class WebAppParseSupport implements WebAppParseProxy, PropertyChangeListener { 78 79 private FileObject wmRoot; 80 81 private OptionsImpl editorOptions; 82 private OptionsImpl diskOptions; 83 private ServletContext editorContext; 84 private ServletContext diskContext; 85 private JspRuntimeContext rctxt; 86 private URLClassLoader waClassLoader; 87 private URLClassLoader waContextClassLoader; 88 90 private HashMap clRootsTimeStamps; 91 private JspParserAPI.WebModule wm; 92 93 95 private static Field mappingsF; 96 97 99 private Map mappings; 100 101 105 private boolean isClassPathCurrent; 106 107 110 private HashMap mappingFiles; 111 112 116 117 private int lastCheckedClasspath; 118 119 122 private Set parserSystemJars = null; 123 124 125 126 130 131 private static int parserDebugLevel = Integer.getInteger("org.netbeans.modules.jspparser.debug", 0).intValue(); 133 134 public WebAppParseSupport(JspParserAPI.WebModule wm) { 135 this.wm = wm; 136 this.wmRoot = wm.getDocumentBase(); 137 wm.addPropertyChangeListener(this); 138 clRootsTimeStamps = new HashMap (); 139 reinitOptions(); 140 mappings = null; 141 mappingFiles = null; 142 } 143 144 public JspParserAPI.JspOpenInfo getJspOpenInfo(FileObject jspFile, boolean useEditor) { 145 JspCompilationContext ctxt = createCompilationContext(jspFile, useEditor); 147 ExtractPageData epd = new ExtractPageData(ctxt); 148 try { 149 return new JspParserAPI.JspOpenInfo(epd.isXMLSyntax(), epd.getEncoding()); 150 } catch (Exception e) { 151 if (parserDebugLevel > 0) { 152 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 153 } 154 return getDefaultJspOpenInfo(wmRoot, jspFile); 155 } 156 } 157 158 159 private JspParserAPI.JspOpenInfo getDefaultJspOpenInfo(FileObject wmRoot, FileObject jspFile) { 160 return new JspParserAPI.JspOpenInfo(false, "8859_1"); } 163 164 synchronized void reinitOptions() { 165 if (parserDebugLevel > 0) { 166 System.out.println("[" + new Date () + "] " + "JSP parser reinitialized for WM " + FileUtil.toFile(wmRoot)); ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, "[" + new Date () + "] " + "JSP parser reinitialized for WM " + FileUtil.toFile(wmRoot)); } 171 editorContext = new ParserServletContext(wmRoot, wm, true); 172 diskContext = new ParserServletContext(wmRoot, wm, false); 173 editorOptions = new OptionsImpl(editorContext); 174 diskOptions = new OptionsImpl(diskContext); 175 rctxt = null; 176 isClassPathCurrent = true; 179 createClassLoaders(); 180 181 } 182 183 private static Pattern rePatternMyFaces = Pattern.compile(".*myfaces-impl.*\\.jar.*"); private static Pattern rePatternCommonsLogging = Pattern.compile(".*commons-logging.*\\.jar.*"); 188 private boolean isParserSystemJar(URL path){ 189 String name = path.getFile(); 190 if (name.endsWith("!/")) name = name.substring(0, name.length()-2); 191 int index = name.lastIndexOf('/')+1; 192 193 if (index > 0) 194 name = name.substring(index).trim(); 195 Matcher m = rePatternMyFaces.matcher(path.getFile()); 197 return (m.matches() || getParserSystemJar().contains(name)); 198 } 199 200 private boolean isUnexpectedLibrary(URL url){ 201 Matcher m = rePatternCommonsLogging.matcher(url.getFile()); 202 return m.matches(); 203 } 204 205 private void createClassLoaders() { 206 clRootsTimeStamps.clear(); 207 208 FileObject webxml = ContextUtil.findRelativeFileObject(wmRoot, "WEB-INF/web.xml"); if (webxml !=null ){ 211 registerTimeStamp(webxml, false); 212 } 213 214 216 220 Hashtable tomcatTable = new Hashtable (); 221 Hashtable loadingTable = new Hashtable (); 222 HashSet systemJars = new HashSet (); 223 FileObject libDir = ContextUtil.findRelativeFileObject(wmRoot, "WEB-INF/lib"); URL helpurl; 225 boolean isSystemJar; 226 227 if (libDir != null) { 228 Enumeration libDirKids = libDir.getChildren(false); 229 while (libDirKids.hasMoreElements()) { 230 FileObject elem = (FileObject)libDirKids.nextElement(); 231 if (elem.getExt().equals("jar")) { helpurl = findInternalURL(elem); 233 isSystemJar = isParserSystemJar(helpurl); 234 if (!isUnexpectedLibrary(helpurl) ){ 235 tomcatTable.put(helpurl, helpurl); 236 loadingTable.put(helpurl, helpurl); 237 registerTimeStamp(elem, false); 238 } 239 if (isSystemJar) systemJars.add(helpurl); 240 } 241 } 242 } 243 244 245 246 247 ClassPath cp = ClassPath.getClassPath(wmRoot, ClassPath.COMPILE); 250 if (cp != null){ 251 FileObject[] roots = cp.getRoots(); 252 for (int i = 0; i < roots.length; i++){ 253 helpurl = findInternalURL(roots[i]); 254 isSystemJar = isParserSystemJar(helpurl); 255 if (loadingTable.get(helpurl) == null && !isUnexpectedLibrary(helpurl) ){ 256 loadingTable.put(helpurl, helpurl); 257 tomcatTable.put(helpurl, findExternalURL(roots[i])); 258 registerTimeStamp(roots[i], false); 259 } 260 if (isSystemJar && !systemJars.contains(helpurl)) systemJars.add(helpurl); 261 } 262 } 263 cp = ClassPath.getClassPath(wmRoot, ClassPath.EXECUTE); 265 lastCheckedClasspath = cp.hashCode(); 267 268 if (cp != null){ 269 FileObject [] roots = cp.getRoots(); 270 for (int i = 0; i < roots.length; i++){ 271 helpurl = findInternalURL(roots[i]); 272 isSystemJar = isParserSystemJar(helpurl); 273 if (loadingTable.get(helpurl) == null && !isUnexpectedLibrary(helpurl) ){ 274 loadingTable.put(helpurl, helpurl); 275 tomcatTable.put(helpurl, findExternalURL(roots[i])); 276 registerTimeStamp(roots[i], false); 277 } 278 if (isSystemJar && !systemJars.contains(helpurl)) systemJars.add(helpurl); 279 } 280 } 281 FileObject classesDir = ContextUtil.findRelativeFileObject(wmRoot, "WEB-INF/classes"); if (classesDir != null && loadingTable.get(helpurl = findInternalURL(classesDir)) == null){ 283 loadingTable.put(helpurl, helpurl); 284 tomcatTable.put(helpurl, helpurl); 285 registerTimeStamp(classesDir, false); 286 } 287 288 Iterator iter = loadingTable.values().iterator(); 289 URL loadingURLs[] = new URL [loadingTable.size()]; 290 int index = 0; 291 while (iter.hasNext()) 292 loadingURLs[index++] = (URL )iter.next(); 293 294 URL tomcatURLs[] = new URL [tomcatTable.size()]; 295 iter = tomcatTable.values().iterator(); 296 index = 0; 297 while (iter.hasNext()) 298 tomcatURLs[index++] = (URL )iter.next(); 299 300 301 File [] files = wm.getExtraClasspathEntries(); 303 if (files == null) 304 files = new File [0]; 305 306 URL urls[] = new URL [files.length + systemJars.size()]; 307 try { 308 for (int i = 0; i < files.length; i++) { 309 urls[i] = files[i].toURI().toURL(); 310 } 311 iter = systemJars.iterator(); 312 for (int i = files.length; i < urls.length; i++) 313 urls[i] = (URL )iter.next(); 314 } catch (MalformedURLException ex) { 315 ErrorManager.getDefault().notify(ErrorManager.EXCEPTION, ex); 316 } 317 318 waClassLoader = new ParserClassLoader(loadingURLs, tomcatURLs, getClass().getClassLoader()); 319 waContextClassLoader = new ParserClassLoader(loadingURLs, tomcatURLs, new JasperSystemClassLoader(urls, Thread.currentThread().getContextClassLoader())); 320 if (parserDebugLevel > 3) { 321 String clString; 322 clString = "wa class loader : " + waClassLoader; System.out.println(clString); 325 ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, clString); clString = "ctxt class loader : " + waContextClassLoader; System.out.println(clString); 329 ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, clString); } 331 } 332 333 private URL findInternalURL(FileObject fo) { 334 URL url = URLMapper.findURL(fo, URLMapper.INTERNAL); 335 return url; 336 } 337 338 private URL findExternalURL(FileObject fo) { 339 File f = FileUtil.toFile(fo); 341 if ((f != null)) { 342 try { 343 return f.toURI().toURL(); 344 } 345 catch (MalformedURLException e) { 346 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 347 } 348 } 349 return URLMapper.findURL(fo, URLMapper.EXTERNAL); 351 } 352 353 private void registerTimeStamp(FileObject fo, boolean recursive) { 354 try { 355 if (fo.getURL().getProtocol().equals("jar")) fo = FileUtil.getArchiveFile(fo); 357 } 358 catch (FileStateInvalidException e){ } 360 361 if (fo != null){ 362 File f = FileUtil.toFile(fo); 363 if (f != null) { 364 registerTimeStamp(f, recursive); 365 } 366 } 367 } 368 369 private void registerTimeStamp(Map where, File f, boolean recursive) { 370 where.put(f, new Long (f.lastModified())); 371 if (recursive && f.isDirectory()) { 372 File kids[] = f.listFiles( 373 new FileFilter () { 374 public boolean accept(File pathname) { 375 return pathname.isDirectory(); 376 } 377 } 378 ); 379 for (int i = 0; i < kids.length; i++) { 380 registerTimeStamp(where, kids[i], recursive); 381 } 382 } 383 } 384 385 private void registerTimeStamp(File f, boolean recursive) { 386 clRootsTimeStamps.put(f, new Long (f.lastModified())); 387 if (recursive && f.isDirectory()) { 388 File kids[] = f.listFiles( 389 new FileFilter () { 390 public boolean accept(File pathname) { 391 return pathname.isDirectory(); 392 } 393 } 394 ); 395 for (int i = 0; i < kids.length; i++) { 396 registerTimeStamp(kids[i], recursive); 397 } 398 } 399 } 400 401 private synchronized JspCompilationContext createCompilationContext(FileObject jspFile, boolean useEditor) { 402 boolean isTagFile = determineIsTagFile(jspFile); 403 String jspUri = getJSPUri(jspFile); 404 Options options = useEditor ? editorOptions : diskOptions; 405 ServletContext context = useEditor ? editorContext : diskContext; 406 JspCompilationContext clctxt = null; 407 try { 408 if (isTagFile) { 409 clctxt = new JspCompilationContext 410 (jspUri, null, options, context, null, rctxt, null ); 411 412 } else { 413 clctxt = new JspCompilationContext 414 (jspUri, false, options, context, null, rctxt ); 415 } 416 } catch (JasperException ex) { 417 ErrorManager.getDefault().annotate(ex, "JSP Parser"); 418 } 419 clctxt.setClassLoader(getWAClassLoader()); 420 return clctxt; 421 } 422 423 private boolean determineIsTagFile(FileObject fo) { 424 if (fo.getExt().startsWith("tag")) { return true; 426 } 427 if (JspParserAPI.TAG_MIME_TYPE.equals(fo.getMIMEType())) { 428 return true; 429 } 430 return false; 431 } 432 433 private String getJSPUri(FileObject jsp) { 434 return ContextUtil.findRelativeContextPath(wmRoot, jsp); 435 } 436 437 public JspParserAPI.ParseResult analyzePage(FileObject jspFile, 439 int errorReportingMode) { 440 JspCompilationContext ctxt = createCompilationContext(jspFile, true); 442 443 450 451 return callTomcatParser(jspFile, ctxt, waContextClassLoader, errorReportingMode); 452 } 453 454 461 public synchronized Map getTaglibMap(boolean useEditor) throws IOException { 462 Options options = useEditor ? editorOptions : diskOptions; 463 TldLocationsCache lc = options.getTldLocationsCache(); 464 Map mappings = new HashMap (); 465 mappings.putAll(getMappingsByReflection(lc)); 466 mappings.putAll(getImplicitLocation()); 467 return mappings; 468 } 469 470 472 private Map getImplicitLocation(){ 473 Map returnMap = new HashMap (); 474 FileObject webInf = ContextUtil.findRelativeFileObject(wmRoot, "WEB-INF"); 476 FileObject fo; 477 File file; 478 if (webInf != null && webInf.isFolder()){ 479 Enumeration en = webInf.getChildren(true); 480 while (en.hasMoreElements()){ 481 fo = (FileObject)en.nextElement(); 482 if (fo.getExt().equals("tld")){ 483 file = FileUtil.toFile(fo); 484 String path = "/" + ContextUtil.findRelativePath(wmRoot, fo); 485 returnMap.put(path, new String [] { path, null }); 486 } 487 } 488 } 489 return returnMap; 490 } 491 492 496 private synchronized boolean checkMappingsAreCurrent(){ 497 if (mappingFiles == null) { 498 return false; 499 } 500 501 HashMap checkedFiles = new HashMap (); 502 FileObject[] roots = ClassPath.getClassPath(wm.getDocumentBase(), ClassPath.EXECUTE).getRoots(); 504 FileObject fo; 505 File file; 506 try{ 507 for (int i = 0; i < roots.length; i++){ 508 if (roots[i].getURL().getProtocol().equals("jar")) { fo = FileUtil.getArchiveFile(roots[i]); 510 if (fo != null){ 511 file = FileUtil.toFile(fo); 512 checkedFiles.put(file, new Long (file.lastModified())); 513 } 514 } 515 } 516 } 517 catch(org.openide.filesystems.FileStateInvalidException e){ 518 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 519 } 520 521 FileObject webInf = ContextUtil.findRelativeFileObject(wmRoot, "WEB-INF"); if (webInf != null && webInf.isFolder()){ 524 Enumeration en = webInf.getChildren(true); 525 while (en.hasMoreElements()){ 526 fo = (FileObject)en.nextElement(); 527 if (fo.getExt().equals("tld")){ file = FileUtil.toFile(fo); 529 checkedFiles.put (file, new Long (file.lastModified())); 530 } 531 } 532 } 533 534 fo = ContextUtil.findRelativeFileObject(wmRoot, "WEB-INF"); if (fo != null){ 537 file = FileUtil.toFile(fo); 538 registerTimeStamp(checkedFiles, file, true); 539 } 540 if (!checkedFiles.equals(mappingFiles)){ 542 return false; 543 } 544 return true; 545 } 546 547 551 private Set getParserSystemJar(){ 552 if (parserSystemJars == null){ 553 TldLocationsCache lc = diskOptions.getTldLocationsCache(); 554 try { 555 Field systemsJar = TldLocationsCache.class.getDeclaredField("systemJars"); systemsJar.setAccessible(true); 557 parserSystemJars = (HashSet )systemsJar.get(lc); 558 } catch (IllegalArgumentException e) { 559 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 560 } catch (SecurityException e) { 561 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 562 } catch (NoSuchFieldException e) { 563 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 564 } catch (IllegalAccessException e) { 565 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 566 } 567 } 568 return parserSystemJars; 569 } 570 571 private Map getMappingsByReflection(TldLocationsCache lc) throws IOException { 572 try { 573 if (!isClassPathCurrent || !checkMappingsAreCurrent()) { 574 if (!isClassPathCurrent) 576 reinitOptions(); 577 mappingsF = TldLocationsCache.class.getDeclaredField("mappings"); mappingsF.setAccessible(true); 579 ((Hashtable )mappingsF.get(lc)).clear(); 582 583 Thread compThread = new WebAppParseSupport.InitTldLocationCacheThread(lc); 584 compThread.setContextClassLoader(waContextClassLoader); 585 compThread.start(); 586 587 try { 588 compThread.join(); 589 } catch (java.lang.InterruptedException e){ 590 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 591 } 592 593 mappings = (Map )mappingsF.get(lc); 594 if (mappingFiles == null) 597 mappingFiles = new HashMap (); 598 else 599 mappingFiles.clear(); 601 602 HashMap usedFile = new HashMap (); 603 604 Iterator iter = mappings.values().iterator(); 607 while (iter.hasNext()){ 608 usedFile.put(((String [])iter.next())[0], null); 609 } 610 611 iter = usedFile.keySet().iterator(); 613 File file; 614 while (iter.hasNext()){ 615 String uri = (String )iter.next(); 616 if (!uri.startsWith("file:")){ FileObject fo = ContextUtil.findRelativeFileObject(wmRoot, uri); 619 if (fo != null) 620 file = FileUtil.toFile(fo); 621 else 622 file = null; 623 } else { 624 uri = uri.substring(5); file = new File (uri); 626 } 627 if (file != null) 628 mappingFiles.put(file, new Long (file.lastModified())); 629 } 630 631 FileObject[] roots = ClassPath.getClassPath(wm.getDocumentBase(), ClassPath.EXECUTE).getRoots(); 634 FileObject fo; 635 try{ 636 for (int i = 0; i < roots.length; i++){ 637 if (roots[i].getURL().getProtocol().equals("jar")) { fo = FileUtil.getArchiveFile(roots[i]); 639 if (fo != null){ 640 file = FileUtil.toFile(fo); 641 mappingFiles.put(file, new Long (file.lastModified())); 642 } 643 } 644 } 645 } catch(org.openide.filesystems.FileStateInvalidException e){ 646 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 647 } 648 649 fo = ContextUtil.findRelativeFileObject(wmRoot, "WEB-INF"); 651 if (fo != null){ 652 file = FileUtil.toFile(fo); 653 registerTimeStamp(mappingFiles, file, true); 654 } 655 } 657 return mappings; 658 } 659 660 catch (NoSuchFieldException e) { 661 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 662 IOException e2 = new IOException (); 663 e2.initCause(e); 664 throw e2; 665 } catch (IllegalAccessException e) { 666 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 667 IOException e2 = new IOException (); 668 e2.initCause(e); 669 throw e2; 670 } 671 } 672 673 674 678 public URLClassLoader getWAClassLoader() { 679 if (!checkClassesAreCurrent()) { 680 reinitOptions(); 681 } 682 return waClassLoader; 683 } 684 685 689 private boolean checkClassesAreCurrent() { 690 if (!isClassPathCurrent) 691 return false; 692 long timeStamp = 0; 693 if (parserDebugLevel > 0) { 694 System.out.println("[" + new Date () + "] " + "JSP parser classloader check started for WM " + FileUtil.toFile(wmRoot)); ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, "[" + new Date () + "] " + "JSP parser classloader check started for WM " + FileUtil.toFile(wmRoot)); timeStamp = System.currentTimeMillis(); 699 } 700 if (clRootsTimeStamps == null) { 701 return false; 702 } 703 Iterator it = clRootsTimeStamps.entrySet().iterator(); 704 while (it.hasNext()) { 705 Map.Entry e = (Map.Entry )it.next(); 706 File f = (File )e.getKey(); 707 if (parserDebugLevel > 9) { 708 System.out.println(" -> checking file " + f); ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, " -> checking file " + f); 710 } 711 if (!f.exists()) { 712 return false; 713 } 714 if (f.lastModified() != ((Long )e.getValue()).longValue()) { 715 return false; 716 } 717 } 718 ClassPath cp = ClassPath.getClassPath(wmRoot, ClassPath.EXECUTE); 719 if (lastCheckedClasspath != cp.hashCode()){ 721 return false; 722 } 723 FileObject[] roots = cp.getRoots(); 725 FileObject fo; 726 File file; 727 for (int i = 0 ; i < roots.length; i++){ 728 URL url = findInternalURL(roots[i]); 729 if (!isParserSystemJar(url) && !isUnexpectedLibrary(url)){ 730 fo = roots[i]; 731 file = null; 732 try { 733 if (roots[i].getURL().getProtocol().equals("jar")) 734 fo = FileUtil.getArchiveFile(roots[i]); 735 } catch (FileStateInvalidException ex) { 736 ErrorManager.getDefault().notify(ex); 737 } 738 if (fo != null) 739 file = FileUtil.toFile(fo); 740 if (!clRootsTimeStamps.containsKey(file)){ 741 return false; 742 } 743 } 744 } 745 if (parserDebugLevel > 0) { 746 long timeStamp2 = System.currentTimeMillis(); 747 System.out.println("[" + new Date () + "] " + "check completed with result 'true', time " + (timeStamp2 - timeStamp)); 749 } 750 return true; 751 } 752 753 public class RRef { 754 JspParserAPI.ParseResult result; 755 } 756 757 private JspParserAPI.ParseResult callTomcatParser(final FileObject jspFile, 758 final JspCompilationContext ctxt, final ClassLoader contextClassLoader, final int errorReportingMode) { 759 760 final RRef resultRef = new RRef(); 761 762 Thread compThread = new Thread ("JSP Parsing") { 766 private void setResult(GetParseData gpd){ 767 PageInfo nbPageInfo = gpd.getNbPageInfo(); 768 Node.Nodes nbNodes = gpd.getNbNodes(); 769 Throwable e = gpd.getParseException(); 770 if (e == null) { 771 resultRef.result = new JspParserAPI.ParseResult(nbPageInfo, nbNodes); 772 } else { 773 ErrorManager.getDefault().annotate(e, NbBundle.getMessage(WebAppParseSupport.class, "MSG_errorDuringJspParsing")); 778 if (parserDebugLevel > 0) { 779 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 780 } 781 JspParserAPI.ErrorDescriptor error = constructErrorDescriptor(e, wmRoot, jspFile); 782 resultRef.result = new JspParserAPI.ParseResult(nbPageInfo, nbNodes, new JspParserAPI.ErrorDescriptor[] {error}); 783 } 784 } 785 786 public void run() { 787 GetParseData gpd = null; 788 try { 789 gpd = new GetParseData(ctxt, errorReportingMode); 790 gpd.parse(); 791 setResult(gpd); 792 793 } catch (ThreadDeath td) { 794 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, td); 795 throw td; 796 } catch (Throwable t) { 797 if (gpd != null) { 798 setResult(gpd); 799 } 800 else { 801 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, t); 802 } 803 } 804 } 805 }; 806 compThread.setContextClassLoader(contextClassLoader); 807 compThread.start(); 808 try { 809 compThread.join(); 810 return resultRef.result; 811 } catch (InterruptedException e) { 812 JspParserAPI.ErrorDescriptor error = constructErrorDescriptor(e, wmRoot, jspFile); 813 return new JspParserAPI.ParseResult(new JspParserAPI.ErrorDescriptor[] {error}); 814 } 815 816 837 } 838 839 840 private static JspParserAPI.ErrorDescriptor constructErrorDescriptor(Throwable e, FileObject wmRoot, FileObject jspPage) { 841 JspParserAPI.ErrorDescriptor error = null; 842 try { 843 error = constructJakartaErrorDescriptor(wmRoot, jspPage, e); 844 } catch (FileStateInvalidException e2) { 845 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e2); 846 } catch (IOException e2) { 848 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e2); 849 } 851 if (error == null) { 852 error = new JspParserAPI.ErrorDescriptor(wmRoot, jspPage, -1, -1, 853 ContextUtil.getThrowableMessage(e, !(e instanceof JasperException)), ""); 854 } 855 return error; 856 } 857 858 860 private static JspParserAPI.ErrorDescriptor constructJakartaErrorDescriptor( 861 FileObject wmRoot, FileObject jspPage, Throwable ex) throws IOException { 862 863 StringBuffer allStack = new StringBuffer (); 865 Throwable last = ex; 866 allStack.append(ContextUtil.getThrowableMessage(ex, true)); 867 while (ex instanceof JasperException) { 868 last = ex; 869 ex = ((JasperException)ex).getRootCause(); 870 if (ex != null) { 871 ErrorManager.getDefault().annotate(last, ex); 872 allStack.append(ContextUtil.getThrowableMessage(ex, true)); 873 } 874 } 875 876 if (ex == null) 877 ex = last; 878 879 882 String m1 = ex.getMessage(); 884 if (m1 == null) return null; 885 int lpar = m1.indexOf('('); 886 if (lpar == -1) return null; 887 int comma = m1.indexOf(',', lpar); 888 if (comma == -1) return null; 889 int rpar = m1.indexOf(')', comma); 890 if (rpar == -1) return null; 891 String line = m1.substring(lpar + 1, comma).trim(); 892 String col = m1.substring(comma + 1, rpar).trim(); 893 String fileName = m1.substring(0, lpar); 894 895 File file = FileUtil.toFile(wmRoot); 897 FileObject errorFile = jspPage; 899 fileName = new File (fileName).getCanonicalPath(); 900 String wmFileName = file.getCanonicalPath(); 901 if (fileName.startsWith(wmFileName)) { 902 String errorRes = fileName.substring(wmFileName.length()); 903 errorRes = errorRes.replace(File.separatorChar, '/'); 904 if (errorRes.startsWith("/")) errorRes = errorRes.substring(1); 906 FileObject errorTemp = ContextUtil.findRelativeFileObject(wmRoot, errorRes); 907 if (errorTemp != null) 908 errorFile = errorTemp; 909 } 910 911 try { 913 String errContextPath = ContextUtil.findRelativeContextPath(wmRoot, errorFile); 914 String errorMessage = errContextPath + " [" + line + ";" + col + "] " + m1.substring(rpar + 1).trim(); 915 return new JspParserAPI.ErrorDescriptor( 916 wmRoot, errorFile, Integer.parseInt(line), Integer.parseInt(col), 917 errorMessage, ""); } catch (NumberFormatException e) { 920 return null; 921 } 922 } 923 924 926 929 public void propertyChange(java.beans.PropertyChangeEvent evt) { 930 String propName = evt.getPropertyName(); 931 if (JspParserAPI.WebModule.PROP_LIBRARIES.equals(propName) || 932 JspParserAPI.WebModule.PROP_PACKAGE_ROOTS.equals(propName)) { 933 isClassPathCurrent = false; 935 } 936 } 937 938 945 946 public static class JasperSystemClassLoader extends URLClassLoader { 947 private static final java.security.AllPermission ALL_PERM = new java.security.AllPermission (); 948 949 public JasperSystemClassLoader(URL [] urls, ClassLoader parent) { 950 super(urls, parent); 951 } 952 953 protected PermissionCollection getPermissions(CodeSource codesource) { 954 PermissionCollection perms = super.getPermissions(codesource); 955 perms.add(ALL_PERM); 956 return perms; 957 } 958 } 959 960 963 public static class ParserClassLoader extends URLClassLoader { 964 965 private static final java.security.AllPermission ALL_PERM = new java.security.AllPermission (); 966 967 private URL [] tomcatURLs; 968 969 976 public ParserClassLoader(URL [] classLoadingURLs, URL [] tomcatURLs, ClassLoader parent) { 977 super(classLoadingURLs, parent); 978 this.tomcatURLs = tomcatURLs; 979 } 980 981 983 public URL [] getURLs() { 984 return tomcatURLs; 985 } 986 987 protected PermissionCollection getPermissions(CodeSource codesource) { 988 PermissionCollection perms = super.getPermissions(codesource); 989 perms.add(ALL_PERM); 990 return perms; 991 } 992 993 public String toString() { 994 StringBuffer sb = new StringBuffer (); 995 sb.append(super.toString()); 996 sb.append(", parent : "); sb.append(getParent().toString()); 998 return sb.toString(); 999 } 1000 1001 } 1002 1003 private static class InitTldLocationCacheThread extends Thread { 1004 1005 private TldLocationsCache cache; 1006 1007 InitTldLocationCacheThread(TldLocationsCache lc){ 1008 super("Init TldLocationCache"); cache = lc; 1010 } 1011 1012 public void run() { 1013 try { 1014 Field initialized= TldLocationsCache.class.getDeclaredField("initialized"); initialized.setAccessible(true); 1016 initialized.setBoolean(cache, false); 1017 cache.getLocation(""); 1018 } catch (JasperException e) { 1019 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 1020 } catch (NoSuchFieldException e) { 1021 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 1022 } catch (IllegalAccessException e) { 1023 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 1024 } 1025 } 1026 1027 } 1028} 1029 | Popular Tags |