提交 d64fda66 编写于 作者: T tbell

Merge

/*
* Copyright 2005-2008 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.file;
import java.io.File;
import java.io.IOException;
import java.util.List;
import com.sun.tools.javac.util.Context;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Caching implementation of FSInfo
*/
public class CacheFSInfo extends FSInfo {
/**
* Register a Context.Factory to create a singleton CacheFSInfo.
*/
public static void preRegister(final Context context) {
context.put(FSInfo.class, new Context.Factory<FSInfo>() {
public FSInfo make() {
if (singleton == null)
singleton = new CacheFSInfo();
context.put(FSInfo.class, singleton);
return singleton;
}
});
}
static CacheFSInfo singleton;
public void clearCache() {
cache.clear();
}
@Override
public File getCanonicalFile(File file) {
Entry e = getEntry(file);
return e.canonicalFile;
}
@Override
public boolean exists(File file) {
Entry e = getEntry(file);
return e.exists;
}
@Override
public boolean isDirectory(File file) {
Entry e = getEntry(file);
return e.isDirectory;
}
@Override
public boolean isFile(File file) {
Entry e = getEntry(file);
return e.isFile;
}
@Override
public List<File> getJarClassPath(File file) throws IOException {
// don't bother to lock the cache, because it is thread-safe, and
// because the worst that can happen would be to create two identical
// jar class paths together and have one overwrite the other.
Entry e = getEntry(file);
if (e.jarClassPath == null)
e.jarClassPath = super.getJarClassPath(file);
return e.jarClassPath;
}
private Entry getEntry(File file) {
// don't bother to lock the cache, because it is thread-safe, and
// because the worst that can happen would be to create two identical
// entries together and have one overwrite the other.
Entry e = cache.get(file);
if (e == null) {
e = new Entry();
e.canonicalFile = super.getCanonicalFile(file);
e.exists = super.exists(file);
e.isDirectory = super.isDirectory(file);
e.isFile = super.isFile(file);
cache.put(file, e);
}
return e;
}
// could also be a Map<File,SoftReference<Entry>> ?
private Map<File,Entry> cache = new ConcurrentHashMap<File,Entry>();
private static class Entry {
File canonicalFile;
boolean exists;
boolean isFile;
boolean isDirectory;
List<File> jarClassPath;
}
}
package com.sun.tools.javac.file;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import com.sun.tools.javac.util.Context;
/**
* Get meta-info about files. Default direct (non-caching) implementation.
* @see CacheFSInfo
*/
public class FSInfo {
/** Get the FSInfo instance for this context.
* @param context the context
* @return the Paths instance for this context
*/
public static FSInfo instance(Context context) {
FSInfo instance = context.get(FSInfo.class);
if (instance == null)
instance = new FSInfo();
return instance;
}
protected FSInfo() {
}
protected FSInfo(Context context) {
context.put(FSInfo.class, this);
}
public File getCanonicalFile(File file) {
try {
return file.getCanonicalFile();
} catch (IOException e) {
return file.getAbsoluteFile();
}
}
public boolean exists(File file) {
return file.exists();
}
public boolean isDirectory(File file) {
return file.isDirectory();
}
public boolean isFile(File file) {
return file.isFile();
}
public List<File> getJarClassPath(File file) throws IOException {
String parent = file.getParent();
JarFile jarFile = new JarFile(file);
try {
Manifest man = jarFile.getManifest();
if (man == null)
return Collections.emptyList();
Attributes attr = man.getMainAttributes();
if (attr == null)
return Collections.emptyList();
String path = attr.getValue(Attributes.Name.CLASS_PATH);
if (path == null)
return Collections.emptyList();
List<File> list = new ArrayList<File>();
for (StringTokenizer st = new StringTokenizer(path); st.hasMoreTokens(); ) {
String elt = st.nextToken();
File f = (parent == null ? new File(elt) : new File(parent, elt));
list.add(f);
}
return list;
} finally {
jarFile.close();
}
}
}
......@@ -55,7 +55,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.zip.ZipFile;
import javax.lang.model.SourceVersion;
......@@ -88,10 +87,6 @@ public class JavacFileManager implements StandardJavaFileManager {
boolean useZipFileIndex;
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();
......@@ -110,6 +105,8 @@ public class JavacFileManager implements StandardJavaFileManager {
private Options options;
private FSInfo fsInfo;
private final File uninited = new File("U N I N I T E D");
private final Set<JavaFileObject.Kind> sourceOrClass =
......@@ -172,9 +169,9 @@ public class JavacFileManager implements StandardJavaFileManager {
}
options = Options.instance(context);
fsInfo = FSInfo.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;
......@@ -289,20 +286,7 @@ public class JavacFileManager implements StandardJavaFileManager {
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();
}
boolean isFile = fsInfo.isFile(directory);
if (archive != null || isFile) {
if (archive == null) {
......
......@@ -31,19 +31,11 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.jar.Attributes;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.zip.ZipFile;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.tools.JavaFileManager.Location;
import com.sun.tools.javac.code.Lint;
......@@ -90,21 +82,8 @@ public class Paths {
/** Handler for -Xlint options */
private Lint lint;
private static boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this.
private static Map<File, PathEntry> pathExistanceCache = new ConcurrentHashMap<File, PathEntry>();
private static Map<File, java.util.List<File>> manifestEntries = new ConcurrentHashMap<File, java.util.List<File>>();
private static Map<File, Boolean> isDirectory = new ConcurrentHashMap<File, Boolean>();
private static Lock lock = new ReentrantLock();
public static void clearPathExistanceCache() {
pathExistanceCache.clear();
}
static class PathEntry {
boolean exists = false;
boolean isFile = false;
File cannonicalPath = null;
}
/** Access to (possibly cached) file info */
private FSInfo fsInfo;
protected Paths(Context context) {
context.put(pathsKey, this);
......@@ -116,6 +95,7 @@ public class Paths {
log = Log.instance(context);
options = Options.instance(context);
lint = Lint.instance(context);
fsInfo = FSInfo.instance(context);
}
/** Whether to warn about non-existent path elements */
......@@ -294,51 +274,17 @@ public class Paths {
}
public void addFile(File file, boolean warn) {
boolean foundInCache = false;
PathEntry pe = null;
if (!NON_BATCH_MODE) {
pe = pathExistanceCache.get(file);
if (pe != null) {
foundInCache = true;
}
else {
pe = new PathEntry();
}
}
else {
pe = new PathEntry();
}
File canonFile;
try {
if (!foundInCache) {
pe.cannonicalPath = file.getCanonicalFile();
}
else {
canonFile = pe.cannonicalPath;
}
} catch (IOException e) {
pe.cannonicalPath = canonFile = file;
}
if (contains(file) || canonicalValues.contains(pe.cannonicalPath)) {
File canonFile = fsInfo.getCanonicalFile(file);
if (contains(file) || canonicalValues.contains(canonFile)) {
/* Discard duplicates and avoid infinite recursion */
return;
}
if (!foundInCache) {
pe.exists = file.exists();
pe.isFile = file.isFile();
if (!NON_BATCH_MODE) {
pathExistanceCache.put(file, pe);
}
}
if (! pe.exists) {
if (! fsInfo.exists(file)) {
/* No such file or directory exists */
if (warn)
log.warning("path.element.not.found", file);
} else if (pe.isFile) {
} else if (fsInfo.isFile(file)) {
/* File is an ordinary file. */
if (!isArchive(file)) {
/* Not a recognized extension; open it to see if
......@@ -360,9 +306,9 @@ public class Paths {
/* Now what we have left is either a directory or a file name
confirming to archive naming convention */
super.add(file);
canonicalValues.add(pe.cannonicalPath);
canonicalValues.add(canonFile);
if (expandJarClassPaths && file.exists() && file.isFile())
if (expandJarClassPaths && fsInfo.exists(file) && fsInfo.isFile(file))
addJarClassPath(file, warn);
}
......@@ -372,58 +318,8 @@ public class Paths {
// filenames, but if we do, we should redo all path-related code.
private void addJarClassPath(File jarFile, boolean warn) {
try {
java.util.List<File> manifestsList = manifestEntries.get(jarFile);
if (!NON_BATCH_MODE) {
lock.lock();
try {
if (manifestsList != null) {
for (File entr : manifestsList) {
addFile(entr, warn);
}
return;
}
}
finally {
lock.unlock();
}
}
if (!NON_BATCH_MODE) {
manifestsList = new ArrayList<File>();
manifestEntries.put(jarFile, manifestsList);
}
String jarParent = jarFile.getParent();
JarFile jar = new JarFile(jarFile);
try {
Manifest man = jar.getManifest();
if (man == null) return;
Attributes attr = man.getMainAttributes();
if (attr == null) return;
String path = attr.getValue(Attributes.Name.CLASS_PATH);
if (path == null) return;
for (StringTokenizer st = new StringTokenizer(path);
st.hasMoreTokens();) {
String elt = st.nextToken();
File f = (jarParent == null ? new File(elt) : new File(jarParent, elt));
addFile(f, warn);
if (!NON_BATCH_MODE) {
lock.lock();
try {
manifestsList.add(f);
}
finally {
lock.unlock();
}
}
}
} finally {
jar.close();
for (File f: fsInfo.getJarClassPath(jarFile)) {
addFile(f, warn);
}
} catch (IOException e) {
log.error("error.reading.file", jarFile, e.getLocalizedMessage());
......@@ -554,24 +450,9 @@ public class Paths {
}
/** Is this the name of an archive file? */
private static boolean isArchive(File file) {
private boolean isArchive(File file) {
String n = file.getName().toLowerCase();
boolean isFile = false;
if (!NON_BATCH_MODE) {
Boolean isf = isDirectory.get(file);
if (isf == null) {
isFile = file.isFile();
isDirectory.put(file, isFile);
}
else {
isFile = isf;
}
}
else {
isFile = file.isFile();
}
return isFile
return fsInfo.isFile(file)
&& (n.endsWith(".jar") || n.endsWith(".zip"));
}
}
......@@ -31,6 +31,7 @@ import java.io.PrintWriter;
import java.util.MissingResourceException;
import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.file.CacheFSInfo;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.jvm.Target;
import com.sun.tools.javac.main.JavacOption.Option;
......@@ -368,6 +369,12 @@ public class Main {
context.put(Log.outKey, out);
// allow System property in following line as a Mustang legacy
boolean batchMode = (options.get("nonBatchMode") == null
&& System.getProperty("nonBatchMode") == null);
if (batchMode)
CacheFSInfo.preRegister(context);
fileManager = context.get(JavaFileManager.class);
comp = JavaCompiler.instance(context);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册