1 11 package org.eclipse.jdt.internal.compiler.tool; 12 13 import java.io.File ; 14 import java.io.IOException ; 15 import java.net.MalformedURLException ; 16 import java.net.URI ; 17 import java.net.URISyntaxException ; 18 import java.net.URL ; 19 import java.net.URLClassLoader ; 20 import java.nio.charset.Charset ; 21 import java.text.MessageFormat ; 22 import java.util.ArrayList ; 23 import java.util.Arrays ; 24 import java.util.HashMap ; 25 import java.util.Iterator ; 26 import java.util.Locale ; 27 import java.util.Map ; 28 import java.util.MissingResourceException ; 29 import java.util.ResourceBundle ; 30 import java.util.Set ; 31 import java.util.StringTokenizer ; 32 import java.util.zip.ZipException ; 33 34 import javax.tools.FileObject; 35 import javax.tools.JavaFileObject; 36 import javax.tools.StandardJavaFileManager; 37 import javax.tools.StandardLocation; 38 import javax.tools.JavaFileObject.Kind; 39 40 import org.eclipse.jdt.core.compiler.IProblem; 41 import org.eclipse.jdt.core.compiler.InvalidInputException; 42 import org.eclipse.jdt.internal.compiler.batch.FileSystem; 43 import org.eclipse.jdt.internal.compiler.batch.Main; 44 import org.eclipse.jdt.internal.compiler.batch.Main.ResourceBundleFactory; 45 import org.eclipse.jdt.internal.compiler.env.AccessRule; 46 import org.eclipse.jdt.internal.compiler.env.AccessRuleSet; 47 48 51 public class EclipseFileManager implements StandardJavaFileManager { 52 private static final String NO_EXTENSION = ""; static final int HAS_EXT_DIRS = 1; 54 static final int HAS_BOOTCLASSPATH = 2; 55 static final int HAS_ENDORSED_DIRS = 4; 56 static final int HAS_PROCESSORPATH = 8; 57 58 Map <File , Archive> archivesCache; 59 Charset charset; 60 Locale locale; 61 Map <String , Iterable <? extends File >> locations; 62 int flags; 63 public ResourceBundle bundle; 64 65 public EclipseFileManager(Locale locale, Charset charset) { 66 this.locale = locale == null ? Locale.getDefault() : locale; 67 this.charset = charset == null ? Charset.defaultCharset() : charset; 68 this.locations = new HashMap <String , Iterable <? extends File >>(); 69 this.archivesCache = new HashMap <File , Archive>(); 70 try { 71 this.setLocation(StandardLocation.PLATFORM_CLASS_PATH, getDefaultBootclasspath()); 72 Iterable <? extends File > defaultClasspath = getDefaultClasspath(); 73 this.setLocation(StandardLocation.CLASS_PATH, defaultClasspath); 74 this.setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, defaultClasspath); 75 } catch (IOException e) { 76 } 78 try { 79 this.bundle = ResourceBundleFactory.getBundle(this.locale); 80 } catch(MissingResourceException e) { 81 System.err.println("Missing resource : " + Main.bundleName.replace('.', '/') + ".properties for locale " + locale); throw e; 83 } 84 } 85 86 private void addFiles(File [][] jars, ArrayList <File > files) { 87 if (jars != null) { 88 for (File [] currentJars : jars) { 89 if (currentJars != null) { 90 for (File currentJar : currentJars) { 91 if (currentJar.exists()) { 92 files.add(currentJar); 93 } 94 } 95 } 96 } 97 } 98 } 99 100 101 private void addFilesFrom(File javaHome, String propertyName, String defaultPath, ArrayList <File > files) { 102 String extdirsStr = System.getProperty(propertyName); 103 File [] directoriesToCheck = null; 104 if (extdirsStr == null) { 105 if (javaHome != null) { 106 directoriesToCheck = new File [] { new File (javaHome, defaultPath) }; 107 } 108 } else { 109 StringTokenizer tokenizer = new StringTokenizer (extdirsStr, File.pathSeparator); 110 ArrayList <String > paths = new ArrayList <String >(); 111 while (tokenizer.hasMoreTokens()) { 112 paths.add(tokenizer.nextToken()); 113 } 114 if (paths.size() != 0) { 115 directoriesToCheck = new File [paths.size()]; 116 for (int i = 0; i < directoriesToCheck.length; i++) { 117 directoriesToCheck[i] = new File (paths.get(i)); 118 } 119 } 120 } 121 if (directoriesToCheck != null) { 122 addFiles(Main.getLibrariesFiles(directoriesToCheck), files); 123 } 124 125 } 126 127 130 public void close() throws IOException { 131 this.locations = null; 132 for (Archive archive : archivesCache.values()) { 133 archive.close(); 134 } 135 } 136 137 private void collectAllMatchingFiles(File file, String normalizedPackageName, Set <Kind> kinds, boolean recurse, ArrayList <JavaFileObject> collector) { 138 if (!isArchive(file)) { 139 File currentFile = new File (file, normalizedPackageName); 141 if (!currentFile.exists()) return; 142 String path; 143 try { 144 path = currentFile.getCanonicalPath(); 145 } catch (IOException e) { 146 return; 147 } 148 if (File.separatorChar == '/') { 149 if (!path.endsWith(normalizedPackageName)) return; 150 } else if (!path.endsWith(normalizedPackageName.replace('/', File.separatorChar))) return; 151 File [] files = currentFile.listFiles(); 152 if (files != null) { 153 for (File f : files) { 155 if (f.isDirectory() && recurse) { 156 collectAllMatchingFiles(file, normalizedPackageName + '/' + f.getName(), kinds, recurse, collector); 157 } else { 158 final Kind kind = getKind(f); 159 if (kinds.contains(kind)) { 160 collector.add(new EclipseFileObject(normalizedPackageName + currentFile.getName(), currentFile.toURI(), kind, this.charset)); 161 } 162 } 163 } 164 } 165 final Kind kind = getKind(file); 168 if (kinds.contains(kind)) { 169 collector.add(new EclipseFileObject(normalizedPackageName + currentFile.getName(), currentFile.toURI(), kind, this.charset)); 170 } 171 } else { 172 Archive archive = this.getArchive(file); 173 String key = normalizedPackageName; 174 if (!normalizedPackageName.endsWith("/")) { key += '/'; 176 } 177 if (recurse) { 179 for (String packageName : archive.allPackages()) { 180 if (packageName.startsWith(key)) { 181 ArrayList <String > types = archive.getTypes(packageName); 182 if (types != null) { 183 for (String typeName : types) { 184 final Kind kind = getKind(getExtension(typeName)); 185 if (kinds.contains(kind)) { 186 collector.add(archive.getArchiveFileObject(packageName + typeName, this.charset)); 187 } 188 } 189 } 190 } 191 } 192 } else { 193 ArrayList <String > types = archive.getTypes(key); 194 if (types != null) { 195 for (String typeName : types) { 196 final Kind kind = getKind(typeName); 197 if (kinds.contains(kind)) { 198 collector.add(archive.getArchiveFileObject(normalizedPackageName + typeName, this.charset)); 199 } 200 } 201 } 202 } 203 } 204 } 205 206 private Iterable <? extends File > concatFiles(Iterable <? extends File > iterable, Iterable <? extends File > iterable2) { 207 ArrayList <File > list = new ArrayList <File >(); 208 if (iterable2 == null) return iterable; 209 for (Iterator <? extends File > iterator = iterable.iterator(); iterator.hasNext(); ) { 210 list.add(iterator.next()); 211 } 212 for (Iterator <? extends File > iterator = iterable2.iterator(); iterator.hasNext(); ) { 213 list.add(iterator.next()); 214 } 215 return list; 216 } 217 218 221 public void flush() throws IOException { 222 for (Archive archive : archivesCache.values()) { 223 archive.flush(); 224 } 225 } 226 227 private Archive getArchive(File f) { 228 Archive archive = this.archivesCache.get(f); 230 if (archive == null) { 231 if (f.exists()) { 233 try { 234 archive = new Archive(f); 235 } catch (ZipException e) { 236 } catch (IOException e) { 238 } 240 if (archive != null) { 241 this.archivesCache.put(f, archive); 242 } else { 243 this.archivesCache.put(f, Archive.UNKNOWN_ARCHIVE); 244 } 245 } else { 246 this.archivesCache.put(f, Archive.UNKNOWN_ARCHIVE); 247 } 248 } 249 return archive; 250 } 251 252 255 public ClassLoader getClassLoader(Location location) { 256 Iterable <? extends File > files = getLocation(location); 257 if (files == null) { 258 return null; 260 } 261 ArrayList <URL > allURLs = new ArrayList <URL >(); 262 for (File f : files) { 263 try { 264 allURLs.add(f.toURI().toURL()); 265 } catch (MalformedURLException e) { 266 throw new RuntimeException (e); 268 } 269 } 270 URL [] result = new URL [allURLs.size()]; 271 return new URLClassLoader (allURLs.toArray(result), getClass().getClassLoader()); 272 } 273 274 private Iterable <? extends File > getPathsFrom(String path) { 275 ArrayList <FileSystem.Classpath> paths = new ArrayList <FileSystem.Classpath>(); 276 ArrayList <File > files = new ArrayList <File >(); 277 try { 278 this.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.toString(), false, false); 279 } catch (InvalidInputException e) { 280 return null; 281 } 282 for (FileSystem.Classpath classpath : paths) { 283 files.add(new File (classpath.getPath())); 284 } 285 return files; 286 } 287 288 Iterable <? extends File > getDefaultBootclasspath() { 289 ArrayList <File > files = new ArrayList <File >(); 290 String javaversion = System.getProperty("java.version"); if (javaversion != null && !javaversion.startsWith("1.6")) { return null; 294 } 295 296 299 String javaHome = System.getProperty("java.home"); File javaHomeFile = null; 301 if (javaHome != null) { 302 javaHomeFile = new File (javaHome); 303 if (!javaHomeFile.exists()) 304 javaHomeFile = null; 305 } 306 307 addFilesFrom(javaHomeFile, "java.endorsed.dirs", "/lib/endorsed", files); if (javaHomeFile != null) { 309 File [] directoriesToCheck = null; 310 if (System.getProperty("os.name").startsWith("Mac")) { directoriesToCheck = new File [] { new File (javaHomeFile, "../Classes"), }; 313 } else { 314 directoriesToCheck = new File [] { new File (javaHomeFile, "lib") }; 316 } 317 File [][] jars = Main.getLibrariesFiles(directoriesToCheck); 318 addFiles(jars, files); 319 } 320 addFilesFrom(javaHomeFile, "java.ext.dirs", "/lib/ext", files); return files; 322 } 323 324 Iterable <? extends File > getDefaultClasspath() { 325 ArrayList <File > files = new ArrayList <File >(); 327 String classProp = System.getProperty("java.class.path"); if ((classProp == null) || (classProp.length() == 0)) { 329 return null; 330 } else { 331 StringTokenizer tokenizer = new StringTokenizer (classProp, File.pathSeparator); 332 String token; 333 while (tokenizer.hasMoreTokens()) { 334 token = tokenizer.nextToken(); 335 File file = new File (token); 336 if (file.exists()) { 337 files.add(file); 338 } 339 } 340 } 341 return files; 342 } 343 344 private Iterable <? extends File > getEndorsedDirsFrom(String path) { 345 ArrayList <FileSystem.Classpath> paths = new ArrayList <FileSystem.Classpath>(); 346 ArrayList <File > files = new ArrayList <File >(); 347 try { 348 this.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.toString(), false, false); 349 } catch (InvalidInputException e) { 350 return null; 351 } 352 for (FileSystem.Classpath classpath : paths) { 353 files.add(new File (classpath.getPath())); 354 } 355 return files; 356 } 357 358 private Iterable <? extends File > getExtdirsFrom(String path) { 359 ArrayList <FileSystem.Classpath> paths = new ArrayList <FileSystem.Classpath>(); 360 ArrayList <File > files = new ArrayList <File >(); 361 try { 362 this.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.toString(), false, false); 363 } catch (InvalidInputException e) { 364 return null; 365 } 366 for (FileSystem.Classpath classpath : paths) { 367 files.add(new File (classpath.getPath())); 368 } 369 return files; 370 } 371 372 private String getExtension(File file) { 373 String name = file.getName(); 374 return getExtension(name); 375 } 376 private String getExtension(String name) { 377 int index = name.lastIndexOf('.'); 378 if (index == -1) { 379 return NO_EXTENSION; 380 } 381 return name.substring(index); 382 } 383 384 387 public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException { 388 Iterable <? extends File > files = getLocation(location); 389 if (files == null) { 390 throw new IllegalArgumentException ("Unknown location : " + location); } 392 String normalizedFileName = normalized(packageName) + '/' + relativeName.replace('\\', '/'); 393 for (File file : files) { 394 if (file.isDirectory()) { 395 File f = new File (file, normalizedFileName); 397 if (f.exists()) { 398 return new EclipseFileObject(packageName + File.separator + relativeName, f.toURI(), getKind(f), this.charset); 399 } else { 400 continue; } 402 } else if (isArchive(file)) { 403 Archive archive = getArchive(file); 405 if (archive != Archive.UNKNOWN_ARCHIVE) { 406 if (archive.contains(normalizedFileName)) { 407 return archive.getArchiveFileObject(normalizedFileName, this.charset); 408 } 409 } 410 } 411 } 412 return null; 413 } 414 415 418 public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) 419 throws IOException { 420 Iterable <? extends File > files = getLocation(location); 421 if (files == null) { 422 throw new IllegalArgumentException ("Unknown location : " + location); } 424 final Iterator <? extends File > iterator = files.iterator(); 425 if (iterator.hasNext()) { 426 File file = iterator.next(); 427 String normalizedFileName = normalized(packageName) + '/' + relativeName.replace('\\', '/'); 428 File f = new File (file, normalizedFileName); 429 return new EclipseFileObject(packageName + File.separator + relativeName, f.toURI(), getKind(f), this.charset); 430 } else { 431 throw new IllegalArgumentException ("location is empty : " + location); } 433 } 434 435 438 public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException { 439 if (kind != Kind.CLASS && kind != Kind.SOURCE) { 440 throw new IllegalArgumentException ("Invalid kind : " + kind); } 442 Iterable <? extends File > files = getLocation(location); 443 if (files == null) { 444 throw new IllegalArgumentException ("Unknown location : " + location); } 446 String normalizedFileName = normalized(className); 447 normalizedFileName += kind.extension; 448 for (File file : files) { 449 if (file.isDirectory()) { 450 File f = new File (file, normalizedFileName); 452 if (f.exists()) { 453 return new EclipseFileObject(className, f.toURI(), kind, this.charset); 454 } else { 455 continue; } 457 } else if (isArchive(file)) { 458 Archive archive = getArchive(file); 460 if (archive != Archive.UNKNOWN_ARCHIVE) { 461 if (archive.contains(normalizedFileName)) { 462 return archive.getArchiveFileObject(normalizedFileName, this.charset); 463 } 464 } 465 } 466 } 467 return null; 468 } 469 470 473 public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) 474 throws IOException { 475 if (kind != Kind.CLASS && kind != Kind.SOURCE) { 476 throw new IllegalArgumentException ("Invalid kind : " + kind); } 478 Iterable <? extends File > files = getLocation(location); 479 if (files == null) { 480 if (!location.equals(StandardLocation.CLASS_OUTPUT) 481 && !location.equals(StandardLocation.SOURCE_OUTPUT)) 482 throw new IllegalArgumentException ("Unknown location : " + location); if (sibling != null) { 485 String normalizedFileName = normalized(className); 486 int index = normalizedFileName.lastIndexOf('/'); 487 if (index != -1) { 488 normalizedFileName = normalizedFileName.substring(index + 1); 489 } 490 normalizedFileName += kind.extension; 491 URI uri = sibling.toUri(); 492 URI uri2 = null; 493 try { 494 String path = uri.getPath(); 495 index = path.lastIndexOf('/'); 496 if (index != -1) { 497 path = path.substring(0, index + 1); 498 path += normalizedFileName; 499 } 500 uri2 = new URI (uri.getScheme(), uri.getHost(), path, uri.getFragment()); 501 } catch (URISyntaxException e) { 502 throw new IllegalArgumentException ("invalid sibling"); } 504 return new EclipseFileObject(className, uri2, kind, this.charset); 505 } else { 506 String normalizedFileName = normalized(className); 507 int index = normalizedFileName.lastIndexOf('/'); 508 if (index != -1) { 509 normalizedFileName = normalizedFileName.substring(index + 1); 510 } 511 normalizedFileName += kind.extension; 512 File f = new File (System.getProperty("user.dir"), normalizedFileName); return new EclipseFileObject(className, f.toURI(), kind, this.charset); 514 } 515 } 516 final Iterator <? extends File > iterator = files.iterator(); 517 if (iterator.hasNext()) { 518 File file = iterator.next(); 519 String normalizedFileName = normalized(className); 520 normalizedFileName += kind.extension; 521 File f = new File (file, normalizedFileName); 522 return new EclipseFileObject(className, f.toURI(), kind, this.charset); 523 } else { 524 throw new IllegalArgumentException ("location is empty : " + location); } 526 } 527 528 531 public Iterable <? extends JavaFileObject> getJavaFileObjects(File ... files) { 532 return getJavaFileObjectsFromFiles(Arrays.asList(files)); 533 } 534 535 538 public Iterable <? extends JavaFileObject> getJavaFileObjects(String ... names) { 539 return getJavaFileObjectsFromStrings(Arrays.asList(names)); 540 } 541 542 545 public Iterable <? extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable <? extends File > files) { 546 ArrayList <JavaFileObject> javaFileArrayList = new ArrayList <JavaFileObject>(); 547 for (File f : files) { 548 javaFileArrayList.add(new EclipseFileObject(f.getAbsolutePath(), f.toURI(), getKind(f), this.charset)); 549 } 550 return javaFileArrayList; 551 } 552 553 556 public Iterable <? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable <String > names) { 557 ArrayList <File > files = new ArrayList <File >(); 558 for (String name : names) { 559 files.add(new File (name)); 560 } 561 return getJavaFileObjectsFromFiles(files); 562 } 563 564 public Kind getKind(File f) { 565 return getKind(getExtension(f)); 566 } 567 568 private Kind getKind(String extension) { 569 if (Kind.CLASS.extension.equals(extension)) { 570 return Kind.CLASS; 571 } else if (Kind.SOURCE.extension.equals(extension)) { 572 return Kind.SOURCE; 573 } else if (Kind.HTML.extension.equals(extension)) { 574 return Kind.HTML; 575 } 576 return Kind.OTHER; 577 } 578 579 582 public Iterable <? extends File > getLocation(Location location) { 583 if (this.locations == null) return null; 584 return this.locations.get(location.getName()); 585 } 586 587 private Iterable <? extends File > getOutputDir(String string) { 588 if ("none".equals(string)) { return null; 590 } 591 File file = new File (string); 592 if (file.exists() && !file.isDirectory()) { 593 throw new IllegalArgumentException ("file : " + file.getAbsolutePath() + " is not a directory"); } 595 ArrayList <File > list = new ArrayList <File >(1); 596 list.add(file); 597 return list; 598 } 599 600 603 public boolean handleOption(String current, Iterator <String > remaining) { 604 try { 605 if ("-bootclasspath".equals(current)) { remaining.remove(); if (remaining.hasNext()) { 608 final Iterable <? extends File > bootclasspaths = getPathsFrom(remaining.next()); 609 if (bootclasspaths != null) { 610 Iterable <? extends File > iterable = getLocation(StandardLocation.PLATFORM_CLASS_PATH); 611 if ((this.flags & HAS_ENDORSED_DIRS) == 0 612 && (this.flags & HAS_EXT_DIRS) == 0) { 613 setLocation(StandardLocation.PLATFORM_CLASS_PATH, bootclasspaths); 615 } else if ((this.flags & HAS_ENDORSED_DIRS) != 0) { 616 setLocation(StandardLocation.PLATFORM_CLASS_PATH, 618 concatFiles(iterable, bootclasspaths)); 619 } else { 620 setLocation(StandardLocation.PLATFORM_CLASS_PATH, 622 prependFiles(iterable, bootclasspaths)); 623 } 624 } 625 remaining.remove(); 626 this.flags |= HAS_BOOTCLASSPATH; 627 return true; 628 } else { 629 throw new IllegalArgumentException (); 630 } 631 } 632 if ("-classpath".equals(current) || "-cp".equals(current)) { remaining.remove(); if (remaining.hasNext()) { 635 final Iterable <? extends File > classpaths = getPathsFrom(remaining.next()); 636 if (classpaths != null) { 637 setLocation(StandardLocation.CLASS_PATH, classpaths); 638 if ((this.flags & HAS_PROCESSORPATH) == 0) { 639 setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, classpaths); 640 } 641 } 642 remaining.remove(); 643 return true; 644 } else { 645 throw new IllegalArgumentException (); 646 } 647 } 648 if ("-encoding".equals(current)) { remaining.remove(); if (remaining.hasNext()) { 651 this.charset = Charset.forName(remaining.next()); 652 remaining.remove(); 653 return true; 654 } else { 655 throw new IllegalArgumentException (); 656 } 657 } 658 if ("-sourcepath".equals(current)) { remaining.remove(); if (remaining.hasNext()) { 661 final Iterable <? extends File > sourcepaths = getPathsFrom(remaining.next()); 662 if (sourcepaths != null) setLocation(StandardLocation.SOURCE_PATH, sourcepaths); 663 remaining.remove(); 664 return true; 665 } else { 666 throw new IllegalArgumentException (); 667 } 668 } 669 if ("-extdirs".equals(current)) { remaining.remove(); if (remaining.hasNext()) { 672 Iterable <? extends File > iterable = getLocation(StandardLocation.PLATFORM_CLASS_PATH); 673 setLocation(StandardLocation.PLATFORM_CLASS_PATH, 674 concatFiles(iterable, getExtdirsFrom(remaining.next()))); 675 remaining.remove(); 676 this.flags |= HAS_EXT_DIRS; 677 return true; 678 } else { 679 throw new IllegalArgumentException (); 680 } 681 } 682 if ("-endorseddirs".equals(current)) { remaining.remove(); if (remaining.hasNext()) { 685 Iterable <? extends File > iterable = getLocation(StandardLocation.PLATFORM_CLASS_PATH); 686 setLocation(StandardLocation.PLATFORM_CLASS_PATH, 687 prependFiles(iterable, getEndorsedDirsFrom(remaining.next()))); 688 remaining.remove(); 689 this.flags |= HAS_ENDORSED_DIRS; 690 return true; 691 } else { 692 throw new IllegalArgumentException (); 693 } 694 } 695 if ("-d".equals(current)) { remaining.remove(); if (remaining.hasNext()) { 698 final Iterable <? extends File > outputDir = getOutputDir(remaining.next()); 699 if (outputDir != null) { 700 setLocation(StandardLocation.CLASS_OUTPUT, outputDir); 701 } 702 remaining.remove(); 703 return true; 704 } else { 705 throw new IllegalArgumentException (); 706 } 707 } 708 if ("-s".equals(current)) { remaining.remove(); if (remaining.hasNext()) { 711 final Iterable <? extends File > outputDir = getOutputDir(remaining.next()); 712 if (outputDir != null) { 713 setLocation(StandardLocation.SOURCE_OUTPUT, outputDir); 714 } 715 remaining.remove(); 716 return true; 717 } else { 718 throw new IllegalArgumentException (); 719 } 720 } 721 if ("-processorpath".equals(current)) { remaining.remove(); if (remaining.hasNext()) { 724 final Iterable <? extends File > processorpaths = getPathsFrom(remaining.next()); 725 if (processorpaths != null) { 726 setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, processorpaths); 727 } 728 remaining.remove(); 729 this.flags |= HAS_PROCESSORPATH; 730 return true; 731 } else { 732 throw new IllegalArgumentException (); 733 } 734 } 735 } catch (IOException e) { 736 } 738 return false; 739 } 740 741 744 public boolean hasLocation(Location location) { 745 return this.locations != null && this.locations.containsKey(location.getName()); 746 } 747 748 751 public String inferBinaryName(Location location, JavaFileObject file) { 752 String name = file.getName(); 753 JavaFileObject javaFileObject = null; 754 int index = name.lastIndexOf('.'); 755 if (index != -1) { 756 name = name.substring(0, index); 757 } 758 try { 759 javaFileObject = getJavaFileForInput(location, name, file.getKind()); 760 } catch (IOException e) { 761 } 763 if (javaFileObject == null) { 764 return null; 765 } 766 return normalized(name); 767 } 768 769 private boolean isArchive(File f) { 770 String extension = getExtension(f); 771 return extension.equalsIgnoreCase(".jar") || extension.equalsIgnoreCase(".zip"); } 773 774 777 public boolean isSameFile(FileObject fileObject1, FileObject fileObject2) { 778 if (!(fileObject1 instanceof EclipseFileObject)) throw new IllegalArgumentException ("Unsupported file object class : " + fileObject1.getClass()); if (!(fileObject2 instanceof EclipseFileObject)) throw new IllegalArgumentException ("Unsupported file object class : " + fileObject2.getClass()); return fileObject1.equals(fileObject2); 782 } 783 786 public int isSupportedOption(String option) { 787 return Options.processOptionsFileManager(option); 788 } 789 790 793 public Iterable <JavaFileObject> list(Location location, String packageName, Set <Kind> kinds, boolean recurse) 794 throws IOException { 795 796 Iterable <? extends File > allFilesInLocations = getLocation(location); 797 if (allFilesInLocations == null) { 798 throw new IllegalArgumentException ("Unknown location : " + location); } 800 801 ArrayList <JavaFileObject> collector = new ArrayList <JavaFileObject>(); 802 String normalizedPackageName = normalized(packageName); 803 for (File file : allFilesInLocations) { 804 collectAllMatchingFiles(file, normalizedPackageName, kinds, recurse, collector); 805 } 806 return collector; 807 } 808 809 private String normalized(String className) { 810 char[] classNameChars = className.toCharArray(); 811 for (int i = 0, max = classNameChars.length; i < max; i++) { 812 switch(classNameChars[i]) { 813 case '\\' : 814 classNameChars[i] = '/'; 815 break; 816 case '.' : 817 classNameChars[i] = '/'; 818 } 819 } 820 return new String (classNameChars); 821 } 822 823 private Iterable <? extends File > prependFiles(Iterable <? extends File > iterable, 824 Iterable <? extends File > iterable2) { 825 if (iterable2 == null) return iterable; 826 ArrayList <File > list = new ArrayList <File >(); 827 for (Iterator <? extends File > iterator = iterable2.iterator(); iterator.hasNext(); ) { 828 list.add(iterator.next()); 829 } 830 for (Iterator <? extends File > iterator = iterable.iterator(); iterator.hasNext(); ) { 831 list.add(iterator.next()); 832 } 833 return list; 834 } 835 836 839 public void setLocation(Location location, Iterable <? extends File > path) throws IOException { 840 if (path != null) { 841 if (location.isOutputLocation()) { 842 int count = 0; 844 for (Iterator <? extends File > iterator = path.iterator(); iterator.hasNext(); ) { 845 iterator.next(); 846 count++; 847 } 848 if (count != 1) { 849 throw new IllegalArgumentException ("output location can only have one path"); } 851 } 852 this.locations.put(location.getName(), path); 853 } 854 } 855 856 public void setLocale(Locale locale) { 857 this.locale = locale == null ? Locale.getDefault() : locale; 858 try { 859 this.bundle = ResourceBundleFactory.getBundle(this.locale); 860 } catch(MissingResourceException e) { 861 System.err.println("Missing resource : " + Main.bundleName.replace('.', '/') + ".properties for locale " + locale); throw e; 863 } 864 } 865 866 @SuppressWarnings ("unchecked") 867 public void processPathEntries(final int defaultSize, final ArrayList paths, 868 final String currentPath, String customEncoding, boolean isSourceOnly, 869 boolean rejectDestinationPathOnJars) 870 throws InvalidInputException { 871 String currentClasspathName = null; 872 String currentDestinationPath = null; 873 ArrayList currentRuleSpecs = new ArrayList (defaultSize); 874 StringTokenizer tokenizer = new StringTokenizer (currentPath, 875 File.pathSeparator + "[]", true); ArrayList tokens = new ArrayList (); 877 while (tokenizer.hasMoreTokens()) { 878 tokens.add(tokenizer.nextToken()); 879 } 880 final int start = 0; 882 final int readyToClose = 1; 883 final int readyToCloseEndingWithRules = 2; 885 final int readyToCloseOrOtherEntry = 3; 887 final int rulesNeedAnotherRule = 4; 889 final int rulesStart = 5; 891 final int rulesReadyToClose = 6; 893 final int destinationPathReadyToClose = 7; 895 final int readyToCloseEndingWithDestinationPath = 8; 897 final int destinationPathStart = 9; 899 final int bracketOpened = 10; 901 final int bracketClosed = 11; 903 905 final int error = 99; 906 int state = start; 907 String token = null; 908 int cursor = 0, tokensNb = tokens.size(), bracket = -1; 909 while (cursor < tokensNb && state != error) { 910 token = (String ) tokens.get(cursor++); 911 if (token.equals(File.pathSeparator)) { 912 switch (state) { 913 case start: 914 case readyToCloseOrOtherEntry: 915 case bracketOpened: 916 break; 917 case readyToClose: 918 case readyToCloseEndingWithRules: 919 case readyToCloseEndingWithDestinationPath: 920 state = readyToCloseOrOtherEntry; 921 addNewEntry(paths, currentClasspathName, currentRuleSpecs, 922 customEncoding, currentDestinationPath, isSourceOnly, 923 rejectDestinationPathOnJars); 924 currentRuleSpecs.clear(); 925 break; 926 case rulesReadyToClose: 927 state = rulesNeedAnotherRule; 928 break; 929 case destinationPathReadyToClose: 930 throw new InvalidInputException( 931 this.bind("configure.incorrectDestinationPathEntry", currentPath)); 933 case bracketClosed: 934 cursor = bracket + 1; 935 state = rulesStart; 936 break; 937 default: 938 state = error; 939 } 940 } else if (token.equals("[")) { switch (state) { 942 case start: 943 currentClasspathName = ""; case readyToClose: 945 bracket = cursor - 1; 946 case bracketClosed: 947 state = bracketOpened; 948 break; 949 case readyToCloseEndingWithRules: 950 state = destinationPathStart; 951 break; 952 case readyToCloseEndingWithDestinationPath: 953 state = rulesStart; 954 break; 955 case bracketOpened: 956 default: 957 state = error; 958 } 959 } else if (token.equals("]")) { switch (state) { 961 case rulesReadyToClose: 962 state = readyToCloseEndingWithRules; 963 break; 964 case destinationPathReadyToClose: 965 state = readyToCloseEndingWithDestinationPath; 966 break; 967 case bracketOpened: 968 state = bracketClosed; 969 break; 970 case bracketClosed: 971 default: 972 state = error; 973 } 974 } else { 975 switch (state) { 977 case start: 978 case readyToCloseOrOtherEntry: 979 state = readyToClose; 980 currentClasspathName = token; 981 break; 982 case rulesStart: 983 if (token.startsWith("-d ")) { if (currentDestinationPath != null) { 985 throw new InvalidInputException( 986 this.bind("configure.duplicateDestinationPathEntry", currentPath)); 988 } 989 currentDestinationPath = token.substring(3).trim(); 990 state = destinationPathReadyToClose; 991 break; 992 } case rulesNeedAnotherRule: 994 if (currentDestinationPath != null) { 995 throw new InvalidInputException( 996 this.bind("configure.accessRuleAfterDestinationPath", currentPath)); 998 } 999 state = rulesReadyToClose; 1000 currentRuleSpecs.add(token); 1001 break; 1002 case destinationPathStart: 1003 if (!token.startsWith("-d ")) { state = error; 1005 } else { 1006 currentDestinationPath = token.substring(3).trim(); 1007 state = destinationPathReadyToClose; 1008 } 1009 break; 1010 case bracketClosed: 1011 for (int i = bracket; i < cursor ; i++) { 1012 currentClasspathName += (String ) tokens.get(i); 1013 } 1014 state = readyToClose; 1015 break; 1016 case bracketOpened: 1017 break; 1018 default: 1019 state = error; 1020 } 1021 } 1022 if (state == bracketClosed && cursor == tokensNb) { 1023 cursor = bracket + 1; 1024 state = rulesStart; 1025 } 1026 } 1027 switch(state) { 1028 case readyToCloseOrOtherEntry: 1029 break; 1030 case readyToClose: 1031 case readyToCloseEndingWithRules: 1032 case readyToCloseEndingWithDestinationPath: 1033 addNewEntry(paths, currentClasspathName, currentRuleSpecs, 1034 customEncoding, currentDestinationPath, isSourceOnly, 1035 rejectDestinationPathOnJars); 1036 break; 1037 case bracketOpened: 1038 case bracketClosed: 1039 default : 1040 } 1042 } 1043 @SuppressWarnings ("unchecked") 1044 protected void addNewEntry(ArrayList paths, String currentClasspathName, 1045 ArrayList currentRuleSpecs, String customEncoding, 1046 String destPath, boolean isSourceOnly, 1047 boolean rejectDestinationPathOnJars) throws InvalidInputException { 1048 1049 int rulesSpecsSize = currentRuleSpecs.size(); 1050 AccessRuleSet accessRuleSet = null; 1051 if (rulesSpecsSize != 0) { 1052 AccessRule[] accessRules = new AccessRule[currentRuleSpecs.size()]; 1053 boolean rulesOK = true; 1054 Iterator i = currentRuleSpecs.iterator(); 1055 int j = 0; 1056 while (i.hasNext()) { 1057 String ruleSpec = (String ) i.next(); 1058 char key = ruleSpec.charAt(0); 1059 String pattern = ruleSpec.substring(1); 1060 if (pattern.length() > 0) { 1061 switch (key) { 1062 case '+': 1063 accessRules[j++] = new AccessRule(pattern 1064 .toCharArray(), 0); 1065 break; 1066 case '~': 1067 accessRules[j++] = new AccessRule(pattern 1068 .toCharArray(), 1069 IProblem.DiscouragedReference); 1070 break; 1071 case '-': 1072 accessRules[j++] = new AccessRule(pattern 1073 .toCharArray(), 1074 IProblem.ForbiddenReference); 1075 break; 1076 case '?': 1077 accessRules[j++] = new AccessRule(pattern 1078 .toCharArray(), 1079 IProblem.ForbiddenReference, true); 1080 break; 1081 default: 1082 rulesOK = false; 1083 } 1084 } else { 1085 rulesOK = false; 1086 } 1087 } 1088 if (rulesOK) { 1089 String templates[] = new String [AccessRuleSet.MESSAGE_TEMPLATES_LENGTH]; 1090 templates[0] = this.bind( 1091 "template.restrictedAccess.type", new String [] {"{0}", currentClasspathName}); templates[1] = this.bind( 1094 "template.restrictedAccess.constructor", new String [] {"{0}", currentClasspathName}); templates[2] = this.bind( 1097 "template.restrictedAccess.method", new String [] {"{0}", "{1}", currentClasspathName}); templates[3] = this.bind( 1100 "template.restrictedAccess.field", new String [] {"{0}", "{1}", currentClasspathName}); accessRuleSet = new AccessRuleSet(accessRules, templates); 1103 } else { 1104 return; 1105 } 1106 } 1107 if (Main.NONE.equals(destPath)) { 1108 destPath = Main.NONE; } 1110 if (rejectDestinationPathOnJars && destPath != null && 1111 (currentClasspathName.endsWith(".jar") || currentClasspathName.endsWith(".zip"))) { throw new InvalidInputException( 1114 this.bind("configure.unexpectedDestinationPathEntryFile", currentClasspathName)); 1116 } 1117 FileSystem.Classpath currentClasspath = FileSystem.getClasspath( 1118 currentClasspathName, 1119 customEncoding, 1120 isSourceOnly, 1121 accessRuleSet, 1122 destPath); 1123 if (currentClasspath != null) { 1124 paths.add(currentClasspath); 1125 } 1126 } 1127 1131 private String bind(String id, String binding) { 1132 return bind(id, new String [] { binding }); 1133 } 1134 1135 1139 private String bind(String id, String [] arguments) { 1140 if (id == null) 1141 return "No message available"; String message = null; 1143 try { 1144 message = this.bundle.getString(id); 1145 } catch (MissingResourceException e) { 1146 return "Missing message: " + id + " in: " + Main.bundleName; } 1150 return MessageFormat.format(message, (Object []) arguments); 1151 } 1152} 1153 | Popular Tags |