1 9 package com.roblisa.classfinder; 10 11 import java.io.*; 12 import java.util.*; 13 import java.util.zip.*; 14 import java.net.URL; 15 16 public class Library implements Runnable 17 { 18 File deploy; 19 Map packages=new HashMap(); 20 Set classes=new TreeSet(); 21 List favorites=new LinkedList(); 22 Map lookup=new HashMap(); 23 String decompiler=null; 24 Set files=new HashSet(); 25 Thread updateTimer; 26 long SLEEP_TIME=20000; 27 String root=null; 28 String rootURL=null; 29 long lastModified=0; 30 int libID=0; 31 List javadocRoots=new ArrayList(); 32 List javadocTitles=new ArrayList(); 33 boolean favoritesChanged=false; 34 String favFile="favorites.txt"; 35 String blockFile="block.txt"; 36 37 Mappings mappings; 38 Set blocked=new HashSet(); 39 40 public long getLastModified() 41 { 42 return lastModified; 43 } 44 45 public List getJavadocRoots() 46 { 47 return javadocRoots; 48 } 49 50 public List getJavadocTitles() 51 { 52 return javadocTitles; 53 } 54 55 public int getID(String root) 56 { 57 return javadocRoots.indexOf(root); 58 } 59 60 public Mappings getMappings() 61 { 62 return mappings; 63 } 64 65 66 public Library(String dir,String mapDir) 67 { 68 this.deploy=new File(dir); 69 mappings=new Mappings(mapDir); 70 loadBlocks(); 71 } 72 73 public void setInterval(int interval) 74 { 75 SLEEP_TIME=interval*1000; 76 } 77 78 public void watchDirectory(boolean start) 79 { 80 if (start) 81 { 82 if (updateTimer==null) 83 { 84 updateTimer=new Thread(this); 85 updateTimer.start(); 86 } 87 } 88 else 89 { 90 if (updateTimer!=null) 91 { 92 updateTimer.interrupt(); 93 updateTimer=null; 94 } 95 } 96 } 97 98 public Set getClassSet() 99 { 100 return classes; 101 } 102 103 104 105 public InputStream decompile(InputStream is,File file) throws IOException 106 { 107 if (decompiler==null||is==null) 108 return null; 109 FileOutputStream fos=new FileOutputStream(file); 110 byte[] b=new byte[4096]; 111 int read=-1; 112 while((read=is.read(b))!=-1) 113 { 114 fos.write(b,0,read); 115 } 116 fos.close(); 117 is.close(); 118 Process p=Runtime.getRuntime().exec(decompiler+" -p \""+file+"\""); 119 is=p.getInputStream(); 120 return is; 121 } 122 123 public LibClass[] getClasses(String match,int resource) 124 { 125 if (match==null||match.length()==0) 126 return getClasses(null,false,resource); 127 128 int dot=match.indexOf('.'); 129 boolean full=dot!=-1; 130 if (!full) 131 match=match.toLowerCase(); 132 LibClass[] ret=getClasses(match,full,resource); 133 if (full&&ret.length==0&&match.indexOf('/',dot+1)==-1) 134 { 135 ret=getClasses(match,false,resource); 136 } 137 return ret; 138 } 139 140 141 public LibClass[] getClasses(String match,boolean full,int resource) 142 { 143 int equalMatches=0; 144 if (match!=null&&match.length()==0) 145 match=null; 146 147 int type=LibClass.START; 148 if (match!=null) 149 { 150 if (match.charAt(0)=='*') 151 { 152 type=LibClass.END; 153 match=match.substring(1); 154 } 155 if (match.charAt(match.length()-1)==';') 156 { 157 if (type==LibClass.START); 158 type=LibClass.EQUAL; 159 match=match.substring(0,match.length()-1); 160 } 161 else 162 if (match.charAt(match.length()-1)=='*') 163 { 164 if (type==LibClass.END) 165 type=LibClass.CONTAINS; 166 match=match.substring(0,match.length()-1); 167 } 168 } 169 170 List list=new ArrayList(); 171 if (match!=null) 172 { 173 for(Iterator it=favorites.iterator();it.hasNext();) 174 { 175 LibClass cla=(LibClass)it.next(); 176 if ((resource<=0||cla.hasResource(resource))&&cla.checkMatch(match,type,full)) 177 { 178 if (type!=LibClass.EQUAL&&cla.checkMatch(match,LibClass.EQUAL,full)) 179 list.add(equalMatches++,cla); 180 else 181 list.add(cla); 182 } 183 } 184 } 185 for(Iterator it=classes.iterator();it.hasNext();) 186 { 187 LibClass cla=(LibClass)it.next(); 188 if (resource<=0||cla.hasResource(resource)) 189 { 190 if (match==null) 191 list.add(cla); 192 else 193 if (cla.checkMatch(match,type,full)&&!list.contains(cla)) 194 { 195 if (type!=LibClass.EQUAL&&cla.checkMatch(match,LibClass.EQUAL,full)) 196 list.add(equalMatches++,cla); 197 else 198 list.add(cla); 199 } 200 } 201 } 202 LibClass[] ret=new LibClass[list.size()]; 203 list.toArray(ret); 204 return ret; 205 } 206 207 public File[] getDeployFiles() 208 { 209 return deploy.listFiles(); 210 } 211 212 public boolean isBlocked(File file) 213 { 214 return blocked.contains(file); 215 } 216 217 public void block(File file,boolean block) 218 { 219 if (block) 220 { 221 if (blocked.remove(file)) 222 saveBlocks(); 223 } 224 else 225 { 226 if (blocked.add(file)) 227 saveBlocks(); 228 } 229 } 230 231 public boolean process() 232 { 233 root=null; 234 rootURL=null; 235 boolean newFiles=false; 237 if (!newFiles) 238 { 239 Set check=new HashSet(files); 240 newFiles=process(deploy,check); 241 if (check.size()>0) 242 { 243 System.out.println("removed items - reloading all"); 244 files.clear(); 245 classes.clear(); 246 packages.clear(); 247 lookup.clear(); 248 javadocRoots.clear(); 249 javadocTitles.clear(); 250 newFiles=true; 251 } 252 else 253 if (newFiles) 254 System.out.println("new items - updating"); 255 } 258 if (newFiles) 259 { 260 process(deploy,null); 261 if (favorites==null) 262 loadFavorites(); 263 System.out.println("processing complete!"); 264 } 265 return newFiles; 266 } 267 268 public void run() 269 { 270 while(Thread.currentThread()==updateTimer) 271 { 272 try 273 { 274 reload(); 275 276 Thread.sleep(SLEEP_TIME); 277 } 278 catch(InterruptedException e) 279 { 280 } 281 } 282 } 283 284 public void reload() 285 { 286 if (favoritesChanged) 287 saveFavorites(); 288 289 if (process()||mappings.process()) 290 { 291 lastModified=System.currentTimeMillis()/1000*1000; 292 loadFavorites(); 293 } 294 } 295 296 public boolean process(File file,Set check) 297 { 298 if (blocked.contains(file)) 299 return false; 300 301 try 302 { 303 if (file.getName().endsWith(".lnk")) 304 { 305 file=FileParser.parseLink(file); 306 if (file==null) 307 return false; 308 } 309 if (file.isDirectory()) 310 { 311 boolean ret=false; 312 File[] files=file.listFiles(); 313 for(int i=0;i<files.length;i++) 314 ret=ret||process(files[i],check); 315 return ret; 316 } 317 else 318 { 319 String name=file.getName(); 320 String path=file.getPath(); 321 int dot=name.lastIndexOf('.'); 322 String ext=(dot==-1)?"":name.substring(dot+1).toLowerCase(); 323 if (ext.equals("zip")||ext.equals("jar")) 324 { 325 String id=path+"!"+file.lastModified(); 326 if (check!=null) 327 { 328 if (!check.remove(id)) 329 return true; 330 } 331 else 332 if (!files.contains(id)) 333 { 334 files.add(id); 335 System.out.println("ZIP: "+name); 336 processZip(file); 337 } 338 } 339 else 340 if (name.equals("allclasses-frame.html")) 341 { 342 String id=path+"!"+file.lastModified(); 343 if (check!=null) 344 { 345 if (!check.remove(id)) 346 return true; 347 } 348 else 349 if (!files.contains(id)) 350 { 351 files.add(id); 352 try 353 { 354 processJavadoc(new FileInputStream(file),file.getParentFile().toURI().toURL().toString()); 355 } 356 catch(IOException e) 357 { 358 System.out.println("Problem processing "+file); 359 } 360 } 361 } 362 else 363 if (ext.equals("url")) 364 { 365 String id=path+"!"+file.lastModified(); 366 if (check!=null) 367 { 368 if (!check.remove(id)) 369 return true; 370 } 371 else 372 if (!files.contains(id)) 373 { 374 files.add(id); 375 try 376 { 377 List urls=FileParser.getURLs(file); 378 for(Iterator it=urls.iterator();it.hasNext();) 379 { 380 String root=(String)it.next(); 381 System.out.println("URL: "+root); 382 URL url=new URL(root+"allclasses-frame.html"); 383 InputStream is=url.openStream(); 384 processJavadoc(is,root); 385 } 386 } 387 catch(IOException e) 388 { 389 e.printStackTrace(); 390 } 391 } 392 } 393 else 394 if (ext.equals("class")||ext.equals("java")) 395 { 396 if (check!=null) 397 { 398 if (!check.remove(path)) 399 return true; 400 } 401 else 402 if (!files.contains(path)) 403 { 404 files.add(path); 405 boolean java=ext.equals("java"); 406 if (root==null||!path.startsWith(root)) 407 { 408 root=null; 409 try 410 { 411 InputStream is=new FileInputStream(file); 412 String pack=java?FileParser.getJavaPackage(is):FileParser.getClassPackage(is); 413 if (pack!=null) 414 { 415 String pckpath=pack.replace('.',File.separatorChar); 416 String dir=file.getParent(); 417 if (dir.endsWith(pckpath)) 418 { 419 if (pckpath.length()==0) 420 root=path.substring(0,dir.length())+File.separatorChar; 421 else 422 root=path.substring(0,dir.length()-pckpath.length()); 423 rootURL=new File(root).toURI().toURL().toString(); 424 System.out.println("Source: "+root); 425 } 426 } 427 } 428 catch(IOException e) 429 { 430 e.printStackTrace(); 431 } 432 } 433 if (root!=null) 434 { 435 String dir=path.substring(root.length(),path.length()-(java?5:6)); 436 if (File.separatorChar!='/') 437 dir=dir.replace(File.separatorChar,'/'); 438 439 if (dir.indexOf('/')!=-1&&dir.indexOf('$')==-1) 440 { 441 LibPackage pack=getPackage(dir); 442 if (java) 443 pack.setJavaRoot(rootURL); 444 else 445 pack.setClassRoot(rootURL); 446 447 addClass(dir).setResource(java?LibClass.SRC:LibClass.CLA); 448 449 } 450 } 451 } 452 } 453 else 454 if (name.startsWith("jad")&&(ext.equals("")||ext.equals("exe"))) 455 { 456 if (decompiler==null||!decompiler.equals(path)) 457 { 458 decompiler=path; 459 System.out.println("Decompiler: "+decompiler); 460 } 461 } 462 return false; 463 } 464 } 465 catch(Throwable th) 466 { 467 System.out.println("************************************************"); 468 th.printStackTrace(); 469 return false; 470 } 471 } 472 473 public boolean processJavadoc(InputStream is,String root) throws IOException 474 { 475 BufferedReader br=new BufferedReader(new InputStreamReader(is)); 476 String line=null; 477 boolean valid=false; 478 String title="Unknown"; 479 boolean added=false; 480 while((line=br.readLine())!=null) 481 { 482 if (!valid&&line.startsWith("<!-- Generated by javadoc")) 483 valid=true; 484 else 485 if (valid) 486 { 487 if (line.startsWith("All Classes")) 488 { 489 title=line.length()>13?line.substring(13,line.length()-1):null; 490 if (title==null) 491 { 492 try 493 { 494 URL url=new URL(root+"index.html"); 495 InputStream is2=url.openStream(); 496 BufferedReader br2=new BufferedReader(new InputStreamReader(is2)); 497 while((line=br2.readLine())!=null) 498 { 499 if (line.equals("<TITLE>")) 500 { 501 title=br2.readLine(); 502 break; 503 } 504 } 505 br2.close(); 506 } 507 catch(IOException e) 508 { 509 System.out.println(e); 510 } 511 } 512 513 } 514 else 515 if (line.startsWith("<A HREF=\"")) 516 { 517 int endQuote=line.indexOf('"',9); 518 if (endQuote!=-1) 519 { 520 String dir=line.substring(9,endQuote-5); 521 if (dir.indexOf('/')!=-1) 522 { 523 LibPackage pack=getPackage(dir); 524 pack.setDocRoot(root); 525 addClass(dir).setResource(LibClass.DOC); 526 added=true; 527 } 528 } 529 } 530 } 531 } 532 br.close(); 533 if (added) 534 { 535 javadocRoots.add(root); 536 javadocTitles.add(title); 537 } 538 return valid; 539 } 540 541 public void processZip(File file) 542 { 543 try 544 { 545 String canon=file.getCanonicalPath().replace('\\','/'); 546 Map claroot=null; 547 Map srcroot=null; 548 Set skip=new HashSet(); 549 ZipFile zf=new ZipFile(file); 550 for(Enumeration e=zf.entries();e.hasMoreElements();) 551 { 552 ZipEntry entry=(ZipEntry)e.nextElement(); 553 String name=entry.getName(); 554 if (name.endsWith("allclasses-frame.html")) 555 { 556 int slash=name.lastIndexOf('/'); 557 if (slash!=-1) 558 name=name.substring(0,slash+1); 559 else 560 name=""; 561 InputStream is=zf.getInputStream(entry); 562 processJavadoc(is,"jar:file:"+canon+"!/"+name); 563 } 564 else 565 if (name.endsWith(".java")||name.endsWith(".class")) 566 { 567 String path=split(name,'/',true); 568 if (skip.contains(path)) 569 continue; 570 571 boolean java=name.endsWith(".java"); 572 String root=findRoot(name,java?srcroot:claroot); 573 if (root==null) 574 { 575 InputStream is=zf.getInputStream(entry); 576 String pack=java?FileParser.getJavaPackage(is):FileParser.getClassPackage(is); 577 if (pack!=null) 578 { 579 if (pack.length()==0) 580 { 581 skip.add(path); 582 continue; 583 } 584 String pckpath=pack.replace('.','/'); 585 if (path.endsWith(pckpath)) 586 { 587 root=path.substring(0,path.length()-pckpath.length()); 588 String rootURL="jar:file:"+canon+"!/"+root; 589 if (java) 590 { 591 if (srcroot==null) 592 srcroot=new HashMap(); 593 srcroot.put(root,rootURL); 594 } 595 else 596 { 597 if (claroot==null) 598 claroot=new HashMap(); 599 claroot.put(root,rootURL); 600 } 601 } 602 else 603 { 604 skip.add(path); 605 continue; 606 } 607 608 } 609 } 610 if (root!=null) 611 { 612 String dir=name.substring(root.length(),name.length()-(java?5:6)); 613 614 if (dir.indexOf('/')!=-1&&dir.indexOf('$')==-1) 615 { 616 LibPackage pack=getPackage(dir); 617 if (java) 618 pack.setJavaRoot((String)srcroot.get(root)); 619 else 620 pack.setClassRoot((String)claroot.get(root)); 621 622 addClass(dir).setResource(java?LibClass.SRC:LibClass.CLA); 623 624 } 625 } 626 627 } 628 } 629 } 630 catch(IOException e) 631 { 632 System.out.println("Error reading zip! - io"); 633 } 634 catch(InternalError e) 635 { 636 System.out.println("Error reading zip! - internal"); 637 } 638 catch(Throwable e) 639 { 640 System.out.println("FUCK! :"+file); 641 e.printStackTrace(); 642 } 643 } 644 645 public LibClass addClass(String dir) 646 { 647 if (dir.charAt(0)=='/') 648 { 649 (new Throwable()).printStackTrace(); 650 System.exit(1); 651 } 652 String cla=dir.replace('/','.'); 653 LibClass c=(LibClass)lookup.get(cla); 654 if (c==null) 655 { 656 c=new LibClass(dir); 657 classes.add(c); 658 String end=c.getName(); 659 Object o=lookup.get(end); 660 if (o==null) 661 { 662 lookup.put(end,c); 663 } 664 else 665 if (o instanceof LibClass) 666 { 667 List l=new ArrayList(); 668 l.add(o); 669 l.add(c); 670 lookup.put(end,l); 671 } 672 else 673 if (o instanceof List) 674 { 675 ((List)o).add(c); 676 } 677 else 678 { 679 System.out.println("WTF! - "+o+":"+o.getClass()); 680 } 681 lookup.put(cla,c); 682 } 683 return c; 684 } 685 686 public String getPackageForRoot(String root) 687 { 688 for(Iterator it=packages.keySet().iterator();it.hasNext();) 689 { 690 String pack=(String)it.next(); 691 LibPackage pck=(LibPackage)packages.get(pack); 692 if (root.equals(pck.getDocRoot())) 693 { 694 return pack; 695 } 696 } 697 return null; 698 } 699 700 public String[] getDocPackages() 701 { 702 List list=new ArrayList(); 703 for(Iterator it=packages.keySet().iterator();it.hasNext();) 704 { 705 String pack=(String)it.next(); 706 LibPackage pck=(LibPackage)packages.get(pack); 707 if (pck.getDocRoot()!=null) 708 { 709 list.add(pack); 710 } 711 } 712 String[] ret=new String[list.size()]; 713 list.toArray(ret); 714 Arrays.sort(ret); 715 return ret; 716 } 717 718 public Object lookupClass(String match) 719 { 720 return lookup.get(match); 721 } 722 723 public LibClass lookupFullClass(String className) 724 { 725 Object o=lookupClass(className); 726 if (o instanceof LibClass) 727 return (LibClass)o; 728 return null; 729 } 730 731 public boolean containsPackage(String pck) 732 { 733 return packages.containsKey(pck); 734 } 735 736 public LibPackage getPackage(String cla) 737 { 738 String pck=split(cla,'/',true); 739 int dot=pck.lastIndexOf('/'); 740 String last=pck.substring(dot+1); 741 if (last.equals("doc-files")||last.equals("class-use")) 742 pck=pck.substring(0,dot); 743 pck=pck.replace('/','.'); 744 LibPackage lp=(LibPackage)packages.get(pck); 745 if (lp==null) 746 { 747 packages.put(pck,lp=new LibPackage()); 748 } 749 return lp; 750 } 751 752 public String split(String name,char sep,boolean path) 753 { 754 int ind=name.lastIndexOf(sep); 755 if (ind==-1) 756 return path?"":name; 757 else 758 return path?name.substring(0,ind):name.substring(ind+1); 759 } 760 761 public String findRoot(String name,Map roots) 762 { 763 if (roots==null) return null; 764 for(Iterator it=roots.keySet().iterator();it.hasNext();) 765 { 766 String root=(String)it.next(); 767 if (name.startsWith(root)) 768 { 769 return root; 770 } 771 } 772 return null; 773 } 774 775 776 public void loaded(LibClass cla) 777 { 778 favorites.remove(cla); 779 favorites.remove(cla.getClassName()); 780 favorites.add(0,cla); 781 if (favorites.size()>100) 782 favorites.remove(favorites.size()-1); 783 favoritesChanged=true; 784 } 785 786 public void loadBlocks() 787 { 788 blocked.clear(); 789 try 790 { 791 BufferedReader br = new BufferedReader(new FileReader(blockFile)); 792 String line; 793 794 while ((line = br.readLine()) != null) 795 { 796 File f=new File(line); 797 if (f.exists()) 798 blocked.add(new File(line)); 799 } 800 801 br.close(); 802 } 803 catch (FileNotFoundException e) 804 { 805 System.out.println("No block file found."); 806 } 807 catch(IOException e) 808 { 809 e.printStackTrace(); 810 } 811 } 812 813 public void saveBlocks() 814 { 815 try 816 { 817 PrintWriter pw = new PrintWriter(new FileWriter(blockFile)); 818 for(Iterator it=blocked.iterator();it.hasNext();) 819 { 820 pw.println(it.next()); 821 } 822 pw.close(); 823 } 824 catch (FileNotFoundException e) 825 { 826 System.out.println( 827 "Can't write to block file "+favFile+". Probably read only"); 828 } 829 catch (IOException e) 830 { 831 e.printStackTrace(); 832 } 833 } 834 835 public void loadFavorites() 836 { 837 try 838 { 839 if (favorites==null) 840 favorites=new LinkedList(); 841 else 842 favorites.clear(); 843 844 BufferedReader br = new BufferedReader(new FileReader(favFile)); 845 String line; 846 847 while ((line = br.readLine()) != null) 848 { 849 LibClass lc=lookupFullClass(line.trim()); 850 if (lc!=null) 851 favorites.add(lc); 852 } 853 854 br.close(); 855 } 856 catch (FileNotFoundException e) 857 { 858 System.out.println("No favorites file found."); 859 } 860 catch (IOException e) 861 { 862 e.printStackTrace(); 863 } 864 favoritesChanged=false; 865 } 866 867 public void saveFavorites() 868 { 869 try 870 { 871 PrintWriter pw = new PrintWriter(new FileWriter(favFile)); 872 for(Iterator it=favorites.iterator();it.hasNext();) 873 { 874 pw.println(((LibClass)it.next()).getClassName()); 875 } 876 pw.close(); 877 } 878 catch (FileNotFoundException e) 879 { 880 System.out.println( 881 "Can't write to cache file "+favFile+". Probably read only"); 882 } 883 catch (IOException e) 884 { 885 e.printStackTrace(); 886 } 887 favoritesChanged=false; 888 } 889 } 890 | Popular Tags |