public PathDocFileFactory(Configuration configuration) { super(configuration); fileManager = (PathFileManager) configuration.getFileManager(); if (!configuration.destDirName.isEmpty() || !fileManager.hasLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT)) { try { String dirName = configuration.destDirName.isEmpty() ? "." : configuration.destDirName; Path dir = fileManager.getDefaultFileSystem().getPath(dirName); fileManager.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(dir)); } catch (IOException e) { throw new DocletAbortException(e); } } destDir = fileManager.getLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT).iterator().next(); }
private File getDestDir() { if (destDir == null) { if (!configuration.destDirName.isEmpty() || !fileManager.hasLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT)) { try { String dirName = configuration.destDirName.isEmpty() ? "." : configuration.destDirName; File dir = new File(dirName); fileManager.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(dir)); } catch (IOException e) { throw new DocletAbortException(e); } } destDir = fileManager.getLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT).iterator().next(); } return destDir; }
void test(boolean hasLocation, File siblingFile, String relName, String expectedPath) throws Exception { System.err.format("test: hasLocation:%s, siblingFile:%s, relName:%s, expectedPath:%s%n", hasLocation, siblingFile, relName, expectedPath); try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { if (hasLocation) { for (Location location : StandardLocation.values()) { System.err.format(" location:%s, moduleLocn:%b%n", location, location.isModuleOrientedLocation()); if (!location.isOutputLocation()) { continue; } fm.setLocation(location, Arrays.asList(new File("."))); test(fm, location, siblingFile, relName, expectedPath); } } else { test(fm, CLASS_OUTPUT, siblingFile, relName, expectedPath); } } }
@Override public javax.tools.FileObject getFileForInput(Location l, String pkgName, String relativeName) { final String[] names = FileObjects.getFolderAndBaseName( FileObjects.resolveRelativePath(pkgName, relativeName), FileObjects.NBFS_SEPARATOR_CHAR); javax.tools.FileObject fo = tx.readFileObject(l, names[0], names[1]); if (fo != null) { return fo; } if (!ModuleLocation.isInstance(l)) { //File in output return super.getFileForInput(l, pkgName, relativeName); } else { //File in module return getFileForInputImpl( ModuleLocation.WithExcludes.cast(l).getModuleEntries(), pkgName, relativeName); } }
private File getClassFolderForApt( final Location l, final String baseName) { String[] parentName = splitParentName(baseName); final Collection<? extends URL> roots = getLocationRoots(l); for (ClassPath.Entry entry : this.apt.entries()) { FileObject root = entry.getRoot(); if (root != null) { FileObject parentFile = root.getFileObject(parentName[0]); if (parentFile != null) { if (parentFile.getFileObject(parentName[1], FileObjects.JAVA) != null) { final URL classFolder = AptCacheForSourceQuery.getClassFolder(entry.getURL()); if (classFolder != null && roots.contains(classFolder)) { try { return BaseUtilities.toFile(classFolder.toURI()); } catch (URISyntaxException ex) { Exceptions.printStackTrace(ex); } } } } } } return null; }
@Override public JavaFileObject getJavaFileForInput (Location l, final String className, JavaFileObject.Kind kind) { String[] namePair = FileObjects.getParentRelativePathAndName (className); String ext = kind == JavaFileObject.Kind.CLASS ? FileObjects.SIG : kind.extension.substring(1); //tzezula: Clearly wrong in compile on save, but "class" is also wrong for (ClassPath.Entry entry : this.sourceRoots.entries()) { FileObject root = entry.getRoot(); if (root != null) { FileObject parent = root.getFileObject(namePair[0]); if (parent != null) { FileObject[] children = parent.getChildren(); for (FileObject child : children) { if (namePair[1].equals(child.getName()) && ext.equalsIgnoreCase(child.getExt()) && (ignoreExcludes || entry.includes(child))) { return FileObjects.sourceFileObject(child, root); } } } } } return null; }
@Override Iterable<Set<Location>> listLocationsForModules() throws IOException { if (!listed && outputDir != null) { try (DirectoryStream<Path> stream = Files.newDirectoryStream(outputDir)) { for (Path p : stream) { getLocationForModule(p.getFileName().toString()); } } listed = true; } if (moduleTable == null || moduleTable.isEmpty()) return Collections.emptySet(); return Collections.singleton(moduleTable.locations()); }
private Location getLocation(String packageName) throws IOException { if (location == StandardLocation.MODULE_SOURCE_PATH) { // TODO: handle invalid results Name pack = names.fromString(packageName); for (ModuleSymbol msym : modules.allModules()) { PackageSymbol p = syms.getPackage(msym, pack); if (p != null && !p.members().isEmpty()) { return fm.getLocationForModule(location, msym.name.toString()); } } return null; } else { return location; } }
@Test public void testBasic(Path base) throws IOException { try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { Location[] locns = { StandardLocation.SOURCE_PATH, StandardLocation.CLASS_PATH, StandardLocation.PLATFORM_CLASS_PATH, }; // set a value Path out = Files.createDirectories(base.resolve("out")); for (Location locn : locns) { checkException("unsupported for location", IllegalArgumentException.class, "location is not an output location or a module-oriented location: " + locn, () -> fm.setLocationForModule(locn, "m", List.of(out))); } } }
void test(StandardJavaFileManager fm, Location location, File siblingFile, String relName, String expectedPath) throws Exception { JavaFileObject sibling = siblingFile == null ? null : fm.getJavaFileObjectsFromFiles(Arrays.asList(siblingFile)).iterator().next(); FileObject fileObject = fm.getFileForOutput(location, "java.lang", relName, sibling); File expectedFile = new File(expectedPath).getCanonicalFile(); File fileObjectFile = new File(fileObject.toUri()).getCanonicalFile(); if (!fileObjectFile.equals(expectedFile)) throw new AssertionError("Expected " + expectedFile + ", got " + fileObjectFile); System.err.format("OK: (%s, %s) => %s%n", siblingFile, relName, fileObjectFile); }
@Test public void testSystemModules(Path base) throws IOException { try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { Location locn = StandardLocation.SYSTEM_MODULES; Location javaCompiler = fm.getLocationForModule(locn, "java.compiler"); // cannot easily verify default setting: could be jrt: or exploded image Path override1 = Files.createDirectories(base.resolve("override1")); fm.setLocationForModule(locn, "java.compiler", List.of(override1)); checkEqual("override setting 1", fm.getLocationAsPaths(javaCompiler), override1); Path override2 = Files.createDirectories(base.resolve("override2")); fm.setLocationFromPaths(javaCompiler, List.of(override2)); checkEqual("override setting 2", fm.getLocationAsPaths(javaCompiler), override2); } }
private void fillIn(PackageSymbol p, Location location, Iterable<JavaFileObject> files) { currentLoc = location; for (JavaFileObject fo : files) { switch (fo.getKind()) { case CLASS: case SOURCE: { // TODO pass binaryName to includeClassFile String binaryName = fileManager.inferBinaryName(currentLoc, fo); String simpleName = binaryName.substring(binaryName.lastIndexOf(".") + 1); if (SourceVersion.isIdentifier(simpleName) || simpleName.equals("package-info")) includeClassFile(p, fo); break; } default: extraFileActions(p, fo); } } }
@SuppressWarnings("unchecked") private void computeSubpackages() throws ToolException { ((List<String>) opts.computeIfAbsent(ToolOption.EXCLUDE, v -> Collections.EMPTY_LIST)) .stream() .map(ModulePackage::new) .forEachOrdered((mpkg) -> excludePackages.add(mpkg)); excludePackages.forEach((p) -> { getEntry(p).excluded = true; }); for (ModulePackage modpkg : subPackages) { List<Location> locs = getLocation(modpkg); for (Location loc : locs) { addPackagesFromLocations(loc, modpkg); } } }
void setPathForLocation(Location location, Iterable<? extends File> path) { // TODO? if (inited) throw new IllegalStateException // TODO: otherwise reset sourceSearchPath, classSearchPath as needed Path p; if (path == null) { if (location == CLASS_PATH) p = computeUserClassPath(); else if (location == PLATFORM_CLASS_PATH) p = computeBootClassPath(); else if (location == ANNOTATION_PROCESSOR_PATH) p = computeAnnotationProcessorPath(); else if (location == SOURCE_PATH) p = computeSourcePath(); else // no defaults for other paths p = null; } else { p = new Path(); for (File f : path) p.addFile(f, warn); // TODO: is use of warn appropriate? } pathsForLocation.put(location, p); }
void initHandlers() { handlersForLocation = new HashMap<Location, LocationHandler>(); handlersForOption = new EnumMap<Option, LocationHandler>(Option.class); LocationHandler[] handlers = { new BootClassPathLocationHandler(), new ClassPathLocationHandler(), new SimpleLocationHandler(StandardLocation.SOURCE_PATH, Option.SOURCEPATH), new SimpleLocationHandler(StandardLocation.ANNOTATION_PROCESSOR_PATH, Option.PROCESSORPATH), new OutputLocationHandler((StandardLocation.CLASS_OUTPUT), Option.D), new OutputLocationHandler((StandardLocation.SOURCE_OUTPUT), Option.S), new OutputLocationHandler((StandardLocation.NATIVE_HEADER_OUTPUT), Option.H) }; for (LocationHandler h: handlers) { handlersForLocation.put(h.location, h); for (Option o: h.options) handlersForOption.put(o, h); } }
private void addPackagesFromLocations(Location packageLocn, ModulePackage modpkg) throws ToolException { for (JavaFileObject fo : fmList(packageLocn, modpkg.packageName, sourceKinds, true)) { String binaryName = fm.inferBinaryName(packageLocn, fo); String pn = getPackageName(binaryName); String simpleName = getSimpleName(binaryName); Entry e = getEntry(pn); if (!e.isExcluded() && isValidClassName(simpleName)) { ModuleSymbol msym = (modpkg.hasModule()) ? syms.getModule(names.fromString(modpkg.moduleName)) : findModuleOfPackageName(modpkg.packageName); if (msym != null && !msym.isUnnamed()) { syms.enterPackage(msym, names.fromString(pn)); ModulePackage npkg = new ModulePackage(msym.toString(), pn); cmdLinePackages.add(npkg); } else { cmdLinePackages.add(e.modpkg); } e.files = (e.files == null ? com.sun.tools.javac.util.List.of(fo) : e.files.prepend(fo)); } } }
private Location getModuleLocation(Location location, String msymName) throws ToolException { try { return fm.getLocationForModule(location, msymName); } catch (IOException ioe) { String text = messager.getText("main.doclet_could_not_get_location", msymName); throw new ToolException(ERROR, text, ioe); } }
@Override public Location getLocationForModule(Location location, String moduleName) throws IOException { return StreamSupport.stream( listLocationsForModules(location).spliterator(), false) .flatMap((c) -> c.stream()) .filter((l) -> moduleName.equals(ModuleLocation.cast(l).getModuleName())) .findAny() .orElse(null); }
private File getClassFolderForSource ( final Location l, final javax.tools.FileObject sibling, final String baseName) throws IOException { return sibling == null ? getClassFolderForSourceImpl(l, baseName) : getClassFolderForSourceImpl(sibling.toUri().toURL()); }
@Override Iterable<Set<Location>> listLocationsForModules() { if (moduleTable == null) return Collections.emptySet(); return Collections.singleton(moduleTable.locations()); }
private File getClassFolderForApt( final Location l, final javax.tools.FileObject sibling, final String baseName) throws IOException { return sibling == null ? getClassFolderForApt(l, baseName) : getClassFolderForApt(sibling.toUri().toURL()); }
private void assertValidRoot( final File activeRoot, final Location l) throws IOException { final Collection<? extends URL> roots = getLocationRoots(l); if (!roots.contains(BaseUtilities.toURI(activeRoot).toURL())) { throw new IOException(String.format( "Wrong cache folder: %s, allowed: %s, location: %s", //NOI18N activeRoot, roots, l)); } }
@Override public Iterable<JavaFileObject> list(final Location l, final String packageName, final Set<JavaFileObject.Kind> kinds, final boolean recursive) { //Todo: Caching of results, needs listening on FS List<JavaFileObject> result = new ArrayList<JavaFileObject> (); String _name = packageName.replace('.','/'); //NOI18N if (_name.length() != 0) { _name+='/'; //NOI18N } for (ClassPath.Entry entry : this.sourceRoots.entries()) { if (ignoreExcludes || entry.includes(_name)) { FileObject root = entry.getRoot(); if (root != null) { FileObject tmpFile = root.getFileObject(_name); if (tmpFile != null && tmpFile.isFolder()) { Enumeration<? extends FileObject> files = tmpFile.getChildren (recursive); while (files.hasMoreElements()) { FileObject file = files.nextElement(); if (ignoreExcludes || entry.includes(file)) { final JavaFileObject.Kind kind = FileObjects.getKind(file.getExt()); if (kinds.contains(kind)) { result.add (FileObjects.sourceFileObject(file, root)); } } } } } } } return result; }
private JavaFileObject createSourceOrClassFile(ModuleSymbol mod, boolean isSourceFile, String name) throws IOException { Assert.checkNonNull(mod); if (lint) { int periodIndex = name.lastIndexOf("."); if (periodIndex != -1) { String base = name.substring(periodIndex); String extn = (isSourceFile ? ".java" : ".class"); if (base.equals(extn)) log.warning(Warnings.ProcSuspiciousClassName(name, extn)); } } checkNameAndExistence(mod, name, isSourceFile); Location loc = (isSourceFile ? SOURCE_OUTPUT : CLASS_OUTPUT); if (modules.multiModuleMode) { loc = this.fileManager.getLocationForModule(loc, mod.name.toString()); } JavaFileObject.Kind kind = (isSourceFile ? JavaFileObject.Kind.SOURCE : JavaFileObject.Kind.CLASS); JavaFileObject fileObject = fileManager.getJavaFileForOutput(loc, name, kind, null); checkFileReopening(fileObject, true); if (lastRound) log.warning(Warnings.ProcFileCreateLastRound(name)); if (isSourceFile) aggregateGeneratedSourceNames.add(Pair.of(mod, name)); else aggregateGeneratedClassNames.add(Pair.of(mod, name)); openTypeNames.add(name); return new FilerOutputJavaFileObject(mod, name, fileObject); }
/** * Creates the table to manage included and excluded elements. * * @param context the context to locate commonly used objects * @param location the location used to locate source files */ ElementsTable(Context context, Map<ToolOption, Object> opts) { this.toolEnv = ToolEnvironment.instance(context); this.syms = Symtab.instance(context); this.names = Names.instance(context); this.fm = toolEnv.fileManager; this.modules = Modules.instance(context); this.opts = opts; this.messager = Messager.instance0(context); this.compiler = JavaCompiler.instance(context); Source source = Source.instance(context); List<Location> locs = new ArrayList<>(); if (modules.multiModuleMode) { locs.add(StandardLocation.MODULE_SOURCE_PATH); } else { if (toolEnv.fileManager.hasLocation(StandardLocation.SOURCE_PATH)) locs.add(StandardLocation.SOURCE_PATH); else locs.add(StandardLocation.CLASS_PATH); } if (source.allowModules() && toolEnv.fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH)) locs.add(StandardLocation.PATCH_MODULE_PATH); this.locations = Collections.unmodifiableList(locs); getEntry("").excluded = false; accessFilter = new ModifierFilter(opts); xclasses = (boolean)opts.getOrDefault(ToolOption.XCLASSES, false); expandRequires = (AccessKind)opts.get(ToolOption.EXPAND_REQUIRES); }
@Test public void testModuleSourcePath(Path base) throws IOException { try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { Location locn = StandardLocation.MODULE_SOURCE_PATH; Path src1 = Files.createDirectories(base.resolve("src1")); Path src1_m = src1.resolve("m"); tb.writeJavaFiles(src1_m, "module m { }"); // fm.setLocationFromPaths(locn, List.of(src1)); fm.handleOption("--module-source-path", List.of(src1.toString()).iterator()); Location m = fm.getLocationForModule(locn, "m"); checkEqual("default setting", fm.getLocationAsPaths(m), src1.resolve("m")); Path override1 = Files.createDirectories(base.resolve("override1")); tb.writeJavaFiles(override1, "module m { }"); fm.setLocationForModule(locn, "m", List.of(override1)); checkEqual("override setting 1", fm.getLocationAsPaths(m), override1); Path override2 = Files.createDirectories(base.resolve("override2")); tb.writeJavaFiles(override2, "module m { }"); fm.setLocationFromPaths(m, List.of(override2)); checkEqual("override setting 2", fm.getLocationAsPaths(m), override2); Path src2 = Files.createDirectories(base.resolve("src2")); Path src2_m = src2.resolve("m"); tb.writeJavaFiles(src2_m, "module m { }"); // fm.setLocationFromPaths(locn, List.of(src2)); fm.handleOption("--module-source-path", List.of(src2.toString()).iterator()); checkEqual("updated setting", fm.getLocationAsPaths(m), src2.resolve("m")); } }
void setLocationForModule(Location location, String moduleName, Iterable<? extends Path> files) throws IOException { LocationHandler h = getHandler(location); if (h == null) { if (location.isOutputLocation()) { h = new OutputLocationHandler(location); } else { h = new ModulePathLocationHandler(location); } handlersForLocation.put(location, h); } h.setPathsForModule(moduleName, files); }
static void test(Iterable<? extends File> path, File file, Location location) { Iterator<? extends File> it = path.iterator(); if (!it.next().equals(file)) throw new AssertionError(file + " not in " + location); if (it.hasNext()) throw new AssertionError("Unexpected element in " + location + " : " + it.next()); System.err.format((Locale)null, "OK: %s: %s%n", location, path); }
@Override @NonNull Iterable<JavaFileObject> filter( @NonNull final Location location, @NonNull final String packageName, @NonNull final Iterable<JavaFileObject> files) { return files; }
@SafeVarargs private void assertLocations(Iterable<Set<Location>> locations, Set<String>... expected) { List<Set<String>> actual = StreamSupport.stream(locations.spliterator(), true) .map(locs -> locs.stream() .map(l -> toString(l)) .collect(Collectors.toSet())) .collect(Collectors.toList()); if (!Objects.equals(actual, Arrays.asList(expected))) { throw new AssertionError("Unexpected output: " + actual); } }
/** * Open an output stream for the file. * The file must have been created with a location of * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path. * * @throws DocFileIOException if there is a problem while opening stream */ @Override public OutputStream openOutputStream() throws DocFileIOException { if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT) throw new IllegalStateException(); try { OutputStream out = getFileObjectForOutput(path).openOutputStream(); return new BufferedOutputStream(out); } catch (IOException e) { throw new DocFileIOException(this, DocFileIOException.Mode.WRITE, e); } }
@NonNull static ModuleLocation cast(@NonNull final Location l) { if (!isInstance(l)) { throw new IllegalArgumentException (String.valueOf(l)); } return (ModuleLocation) l; }
@NonNull static WithExcludes cast(@NonNull final Location l) { if (!isInstance(l)) { throw new IllegalArgumentException (String.valueOf(l)); } return (WithExcludes) l; }
@NonNull static WithExcludes createExcludes( @NonNull final Location base, @NonNull final Collection<? extends ClassPath.Entry> moduleEntries, @NonNull final String moduleName) { return new WithExcludes( base, moduleName, moduleEntries); }
@NonNull private Collection<File> listDir( @NonNull final Location location, @NonNull final String dir) { final Map<String, Map<File, CachedFileObject>> cache = getCacheLine(location, true); Map<File, CachedFileObject> content = cache.get(dir); return content == null ? Collections.<File>emptyList() : content.keySet(); }
private void appendPaths(MemoryFileManager fm, Location loc, Collection<Path> paths) { Iterable<? extends Path> locationPaths = fm.getLocationAsPaths(loc); if (locationPaths == null) return ; for (Path path : locationPaths) { if (".".equals(path.toString())) { //skip CWD continue; } paths.add(path); } }
private void addFile( @NonNull final Location location, @NonNull final String packageName, @NonNull final CachedFileObject fo) { LOG.log(Level.FINE, "File added to cache:{0}:{1}", new Object[] { fo.getFile(), root }); // check whether the softref has been freed: final Map<String, Map<File, CachedFileObject>> cache = getCacheLine(location, false); Map<File, CachedFileObject> dirContent = cache.get(packageName); if (dirContent == null) { dirContent = new HashMap<File, CachedFileObject>(); cache.put(packageName, dirContent); } dirContent.put(toFile(fo), fo); }
@Test public void testOutput(Path base) throws IOException { try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { Location locn = StandardLocation.CLASS_OUTPUT; Path out1 = Files.createDirectories(base.resolve("out1")); fm.setLocationFromPaths(locn, List.of(out1)); Location m = fm.getLocationForModule(locn, "m"); checkEqual("default setting", fm.getLocationAsPaths(m), out1.resolve("m")); Path override1 = Files.createDirectories(base.resolve("override1")); fm.setLocationForModule(locn, "m", List.of(override1)); checkEqual("override setting 1", fm.getLocationAsPaths(m), override1); Path override2 = Files.createDirectories(base.resolve("override2")); fm.setLocationFromPaths(m, List.of(override2)); checkEqual("override setting 2", fm.getLocationAsPaths(m), override2); Path out2 = Files.createDirectories(base.resolve("out2")); fm.setLocationFromPaths(locn, List.of(out2)); checkEqual("updated setting", fm.getLocationAsPaths(m), out2.resolve("m")); } }
private void locationCheck(Location location) { if (location instanceof StandardLocation) { StandardLocation stdLoc = (StandardLocation) location; if (!stdLoc.isOutputLocation()) throw new IllegalArgumentException("Resource creation not supported in location " + stdLoc); } }