📄 javacfilemanager.java
字号:
/* * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */package com.sun.tools.javac.util;import com.sun.tools.javac.main.JavacOption;import com.sun.tools.javac.main.OptionName;import com.sun.tools.javac.main.RecognizedOptions;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.Writer;import java.lang.ref.SoftReference;import java.net.MalformedURLException;import java.net.URI;import java.net.URISyntaxException;import java.net.URL;import java.net.URLClassLoader;import java.nio.ByteBuffer;import java.nio.CharBuffer;import java.nio.channels.FileChannel;import java.nio.charset.Charset;import java.nio.charset.CharsetDecoder;import java.nio.charset.CoderResult;import java.nio.charset.CodingErrorAction;import java.nio.charset.IllegalCharsetNameException;import java.nio.charset.UnsupportedCharsetException;import java.util.ArrayList;import java.util.Arrays;import java.util.Collection;import java.util.Collections;import java.util.EnumSet;import java.util.Enumeration;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Set;import java.util.zip.ZipEntry;import java.util.zip.ZipFile;import javax.lang.model.SourceVersion;import javax.tools.FileObject;import javax.tools.JavaFileManager;import javax.tools.JavaFileObject;import com.sun.tools.javac.code.Source;import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;import java.util.concurrent.ConcurrentHashMap;import javax.tools.StandardJavaFileManager;import com.sun.tools.javac.zip.*;import java.io.ByteArrayInputStream;import static com.sun.tools.javac.main.OptionName.*;import static javax.tools.StandardLocation.*;/** * This class provides access to the source, class and other files * used by the compiler and related tools. */public class JavacFileManager implements StandardJavaFileManager { private static final String[] symbolFileLocation = { "lib", "ct.sym" }; private static final String symbolFilePrefix = "META-INF/sym/rt.jar/"; boolean useZipFileIndex; private static int symbolFilePrefixLength = 0; static { try { symbolFilePrefixLength = symbolFilePrefix.getBytes("UTF-8").length; } catch (java.io.UnsupportedEncodingException uee) { // Can't happen...UTF-8 is always supported. } } private static boolean CHECK_ZIP_TIMESTAMP = false; private static Map<File, Boolean> isDirectory = new ConcurrentHashMap<File, Boolean>(); public static char[] toArray(CharBuffer buffer) { if (buffer.hasArray()) return ((CharBuffer)buffer.compact().flip()).array(); else return buffer.toString().toCharArray(); } /** * The log to be used for error reporting. */ protected Log log; /** Encapsulates knowledge of paths */ private Paths paths; private Options options; private final File uninited = new File("U N I N I T E D"); private final Set<JavaFileObject.Kind> sourceOrClass = EnumSet.of(JavaFileObject.Kind.SOURCE, JavaFileObject.Kind.CLASS); /** The standard output directory, primarily used for classes. * Initialized by the "-d" option. * If classOutDir = null, files are written into same directory as the sources * they were generated from. */ private File classOutDir = uninited; /** The output directory, used when generating sources while processing annotations. * Initialized by the "-s" option. */ private File sourceOutDir = uninited; protected boolean mmappedIO; protected boolean ignoreSymbolFile; /** * User provided charset (through javax.tools). */ protected Charset charset; /** * Register a Context.Factory to create a JavacFileManager. */ public static void preRegister(final Context context) { context.put(JavaFileManager.class, new Context.Factory<JavaFileManager>() { public JavaFileManager make() { return new JavacFileManager(context, true, null); } }); } /** * Create a JavacFileManager using a given context, optionally registering * it as the JavaFileManager for that context. */ public JavacFileManager(Context context, boolean register, Charset charset) { if (register) context.put(JavaFileManager.class, this); byteBufferCache = new ByteBufferCache(); this.charset = charset; setContext(context); } /** * Set the context for JavacFileManager. */ public void setContext(Context context) { log = Log.instance(context); if (paths == null) { paths = Paths.instance(context); } else { // Reuse the Paths object as it stores the locations that // have been set with setLocation, etc. paths.setContext(context); } options = Options.instance(context); useZipFileIndex = System.getProperty("useJavaUtilZip") == null;// TODO: options.get("useJavaUtilZip") == null; CHECK_ZIP_TIMESTAMP = System.getProperty("checkZipIndexTimestamp") != null;// TODO: options.get("checkZipIndexTimestamp") != null; mmappedIO = options.get("mmappedIO") != null; ignoreSymbolFile = options.get("ignore.symbol.file") != null; } public JavaFileObject getFileForInput(String name) { return getRegularFile(new File(name)); } public JavaFileObject getRegularFile(File file) { return new RegularFileObject(file); } public JavaFileObject getFileForOutput(String classname, JavaFileObject.Kind kind, JavaFileObject sibling) throws IOException { return getJavaFileForOutput(CLASS_OUTPUT, classname, kind, sibling); } public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) { ListBuffer<File> files = new ListBuffer<File>(); for (String name : names) files.append(new File(nullCheck(name))); return getJavaFileObjectsFromFiles(files.toList()); } public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) { return getJavaFileObjectsFromStrings(Arrays.asList(nullCheck(names))); } protected JavaFileObject.Kind getKind(String extension) { if (extension.equals(JavaFileObject.Kind.CLASS.extension)) return JavaFileObject.Kind.CLASS; else if (extension.equals(JavaFileObject.Kind.SOURCE.extension)) return JavaFileObject.Kind.SOURCE; else if (extension.equals(JavaFileObject.Kind.HTML.extension)) return JavaFileObject.Kind.HTML; else return JavaFileObject.Kind.OTHER; } private static boolean isValidName(String name) { // Arguably, isValidName should reject keywords (such as in SourceVersion.isName() ), // but the set of keywords depends on the source level, and we don't want // impls of JavaFileManager to have to be dependent on the source level. // Therefore we simply check that the argument is a sequence of identifiers // separated by ".". for (String s : name.split("\\.", -1)) { if (!SourceVersion.isIdentifier(s)) return false; } return true; } private static void validateClassName(String className) { if (!isValidName(className)) throw new IllegalArgumentException("Invalid class name: " + className); } private static void validatePackageName(String packageName) { if (packageName.length() > 0 && !isValidName(packageName)) throw new IllegalArgumentException("Invalid packageName name: " + packageName); } public static void testName(String name, boolean isValidPackageName, boolean isValidClassName) { try { validatePackageName(name); if (!isValidPackageName) throw new AssertionError("Invalid package name accepted: " + name); printAscii("Valid package name: \"%s\"", name); } catch (IllegalArgumentException e) { if (isValidPackageName) throw new AssertionError("Valid package name rejected: " + name); printAscii("Invalid package name: \"%s\"", name); } try { validateClassName(name); if (!isValidClassName) throw new AssertionError("Invalid class name accepted: " + name); printAscii("Valid class name: \"%s\"", name); } catch (IllegalArgumentException e) { if (isValidClassName) throw new AssertionError("Valid class name rejected: " + name); printAscii("Invalid class name: \"%s\"", name); } } private static void printAscii(String format, Object... args) { String message; try { final String ascii = "US-ASCII"; message = new String(String.format(null, format, args).getBytes(ascii), ascii); } catch (java.io.UnsupportedEncodingException ex) { throw new AssertionError(ex); } System.out.println(message); } /** Return external representation of name, * converting '.' to File.separatorChar. */ private static String externalizeFileName(CharSequence name) { return name.toString().replace('.', File.separatorChar); } private static String externalizeFileName(CharSequence n, JavaFileObject.Kind kind) { return externalizeFileName(n) + kind.extension; } private static String baseName(String fileName) { return fileName.substring(fileName.lastIndexOf(File.separatorChar) + 1); } /** * Insert all files in subdirectory `subdirectory' of `directory' which end * in one of the extensions in `extensions' into packageSym. */ private void listDirectory(File directory, String subdirectory, Set<JavaFileObject.Kind> fileKinds, boolean recurse, ListBuffer<JavaFileObject> l) { Archive archive = archives.get(directory); boolean isFile = false; if (CHECK_ZIP_TIMESTAMP) { Boolean isf = isDirectory.get(directory); if (isf == null) { isFile = directory.isFile(); isDirectory.put(directory, isFile); } else { isFile = directory.isFile(); } } else { isFile = directory.isFile(); } if (archive != null || isFile) { if (archive == null) { try { archive = openArchive(directory); } catch (IOException ex) { log.error("error.reading.file", directory, ex.getLocalizedMessage()); return; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -