org.eclipse.jdt.internal.compiler.tool.EclipseFileManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ecj Show documentation
Show all versions of ecj Show documentation
This is Eclipse JDT Core Batch Compiler used by Scout SDK
The newest version!
/*******************************************************************************
* Copyright (c) 2006, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.tool;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.Charset;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.zip.ZipException;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.batch.FileSystem;
import org.eclipse.jdt.internal.compiler.batch.Main;
import org.eclipse.jdt.internal.compiler.batch.Main.ResourceBundleFactory;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
import org.eclipse.jdt.internal.compiler.env.AccessRule;
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
/**
* Implementation of the Standard Java File Manager
*/
public class EclipseFileManager implements StandardJavaFileManager {
private static final String NO_EXTENSION = "";//$NON-NLS-1$
static final int HAS_EXT_DIRS = 1;
static final int HAS_BOOTCLASSPATH = 2;
static final int HAS_ENDORSED_DIRS = 4;
static final int HAS_PROCESSORPATH = 8;
Map archivesCache;
Charset charset;
Locale locale;
Map> locations;
int flags;
public ResourceBundle bundle;
public EclipseFileManager(Locale locale, Charset charset) {
this.locale = locale == null ? Locale.getDefault() : locale;
this.charset = charset == null ? Charset.defaultCharset() : charset;
this.locations = new HashMap<>();
this.archivesCache = new HashMap<>();
try {
this.setLocation(StandardLocation.PLATFORM_CLASS_PATH, getDefaultBootclasspath());
Iterable extends File> defaultClasspath = getDefaultClasspath();
this.setLocation(StandardLocation.CLASS_PATH, defaultClasspath);
this.setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, defaultClasspath);
} catch (IOException e) {
// ignore
}
try {
this.bundle = ResourceBundleFactory.getBundle(this.locale);
} catch(MissingResourceException e) {
System.out.println("Missing resource : " + Main.bundleName.replace('.', '/') + ".properties for locale " + locale); //$NON-NLS-1$//$NON-NLS-2$
}
}
/* (non-Javadoc)
* @see javax.tools.JavaFileManager#close()
*/
@Override
public void close() throws IOException {
if (this.locations != null) this.locations.clear();
for (Archive archive : this.archivesCache.values()) {
archive.close();
}
this.archivesCache.clear();
}
private void collectAllMatchingFiles(File file, String normalizedPackageName, Set kinds, boolean recurse, ArrayList collector) {
if (!isArchive(file)) {
// we must have a directory
File currentFile = new File(file, normalizedPackageName);
if (!currentFile.exists()) return;
String path;
try {
path = currentFile.getCanonicalPath();
} catch (IOException e) {
return;
}
if (File.separatorChar == '/') {
if (!path.endsWith(normalizedPackageName)) return;
} else if (!path.endsWith(normalizedPackageName.replace('/', File.separatorChar))) return;
File[] files = currentFile.listFiles();
if (files != null) {
// this was a directory
for (File f : files) {
if (f.isDirectory() && recurse) {
collectAllMatchingFiles(file, normalizedPackageName + '/' + f.getName(), kinds, recurse, collector);
} else {
final Kind kind = getKind(f);
if (kinds.contains(kind)) {
collector.add(new EclipseFileObject(normalizedPackageName + f.getName(), f.toURI(), kind, this.charset));
}
}
}
}
} else {
Archive archive = this.getArchive(file);
if (archive == Archive.UNKNOWN_ARCHIVE) return;
String key = normalizedPackageName;
if (!normalizedPackageName.endsWith("/")) {//$NON-NLS-1$
key += '/';
}
// we have an archive file
if (recurse) {
for (String packageName : archive.allPackages()) {
if (packageName.startsWith(key)) {
List types = archive.getTypes(packageName);
if (types != null) {
for (String typeName : types) {
final Kind kind = getKind(getExtension(typeName));
if (kinds.contains(kind)) {
collector.add(archive.getArchiveFileObject(packageName + typeName, this.charset));
}
}
}
}
}
} else {
List types = archive.getTypes(key);
if (types != null) {
for (String typeName : types) {
final Kind kind = getKind(getExtension(typeName));
if (kinds.contains(kind)) {
collector.add(archive.getArchiveFileObject(key + typeName, this.charset));
}
}
}
}
}
}
private Iterable extends File> concatFiles(Iterable extends File> iterable, Iterable extends File> iterable2) {
ArrayList list = new ArrayList<>();
if (iterable2 == null) return iterable;
for (Iterator extends File> iterator = iterable.iterator(); iterator.hasNext(); ) {
list.add(iterator.next());
}
for (Iterator extends File> iterator = iterable2.iterator(); iterator.hasNext(); ) {
list.add(iterator.next());
}
return list;
}
/* (non-Javadoc)
* @see javax.tools.JavaFileManager#flush()
*/
@Override
public void flush() throws IOException {
for (Archive archive : this.archivesCache.values()) {
archive.flush();
}
}
private Archive getArchive(File f) {
// check the archive (jar/zip) cache
Archive archive = this.archivesCache.get(f);
if (archive == null) {
archive = Archive.UNKNOWN_ARCHIVE;
// create a new archive
if (f.exists()) {
try {
archive = new Archive(f);
} catch (ZipException e) {
// ignore
} catch (IOException e) {
// ignore
}
if (archive != null) {
this.archivesCache.put(f, archive);
}
}
this.archivesCache.put(f, archive);
}
return archive;
}
/* (non-Javadoc)
* @see javax.tools.JavaFileManager#getClassLoader(javax.tools.JavaFileManager.Location)
*/
@Override
public ClassLoader getClassLoader(Location location) {
Iterable extends File> files = getLocation(location);
if (files == null) {
// location is unknown
return null;
}
ArrayList allURLs = new ArrayList<>();
for (File f : files) {
try {
allURLs.add(f.toURI().toURL());
} catch (MalformedURLException e) {
// the url is malformed - this should not happen
throw new RuntimeException(e);
}
}
URL[] result = new URL[allURLs.size()];
return new URLClassLoader(allURLs.toArray(result), getClass().getClassLoader());
}
private Iterable extends File> getPathsFrom(String path) {
ArrayList paths = new ArrayList<>();
ArrayList files = new ArrayList<>();
try {
this.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.name(), false, false);
} catch (IllegalArgumentException e) {
return null;
}
for (FileSystem.Classpath classpath : paths) {
files.add(new File(classpath.getPath()));
}
return files;
}
Iterable extends File> getDefaultBootclasspath() {
List files = new ArrayList<>();
String javaversion = System.getProperty("java.version");//$NON-NLS-1$
if(javaversion.length() > 3)
javaversion = javaversion.substring(0, 3);
long jdkLevel = CompilerOptions.versionToJdkLevel(javaversion);
if (jdkLevel < ClassFileConstants.JDK1_6) {
// wrong jdk - 1.6 or above is required
return null;
}
for (String fileName : org.eclipse.jdt.internal.compiler.util.Util.collectFilesNames()) {
files.add(new File(fileName));
}
return files;
}
Iterable extends File> getDefaultClasspath() {
// default classpath
ArrayList files = new ArrayList<>();
String classProp = System.getProperty("java.class.path"); //$NON-NLS-1$
if ((classProp == null) || (classProp.length() == 0)) {
return null;
} else {
StringTokenizer tokenizer = new StringTokenizer(classProp, File.pathSeparator);
String token;
while (tokenizer.hasMoreTokens()) {
token = tokenizer.nextToken();
File file = new File(token);
if (file.exists()) {
files.add(file);
}
}
}
return files;
}
private Iterable extends File> getEndorsedDirsFrom(String path) {
ArrayList paths = new ArrayList<>();
ArrayList files = new ArrayList<>();
try {
this.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.name(), false, false);
} catch (IllegalArgumentException e) {
return null;
}
for (FileSystem.Classpath classpath : paths) {
files.add(new File(classpath.getPath()));
}
return files;
}
private Iterable extends File> getExtdirsFrom(String path) {
ArrayList paths = new ArrayList<>();
ArrayList files = new ArrayList<>();
try {
this.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.name(), false, false);
} catch (IllegalArgumentException e) {
return null;
}
for (FileSystem.Classpath classpath : paths) {
files.add(new File(classpath.getPath()));
}
return files;
}
private String getExtension(File file) {
String name = file.getName();
return getExtension(name);
}
private String getExtension(String name) {
int index = name.lastIndexOf('.');
if (index == -1) {
return EclipseFileManager.NO_EXTENSION;
}
return name.substring(index);
}
/* (non-Javadoc)
* @see javax.tools.JavaFileManager#getFileForInput(javax.tools.JavaFileManager.Location, java.lang.String, java.lang.String)
*/
@Override
public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
Iterable extends File> files = getLocation(location);
if (files == null) {
throw new IllegalArgumentException("Unknown location : " + location);//$NON-NLS-1$
}
String normalizedFileName = normalized(packageName) + '/' + relativeName.replace('\\', '/');
for (File file : files) {
if (file.isDirectory()) {
// handle directory
File f = new File(file, normalizedFileName);
if (f.exists()) {
return new EclipseFileObject(packageName + File.separator + relativeName, f.toURI(), getKind(f), this.charset);
} else {
continue; // go to next entry in the location
}
} else if (isArchive(file)) {
// handle archive file
Archive archive = getArchive(file);
if (archive != Archive.UNKNOWN_ARCHIVE) {
if (archive.contains(normalizedFileName)) {
return archive.getArchiveFileObject(normalizedFileName, this.charset);
}
}
}
}
return null;
}
/* (non-Javadoc)
* @see javax.tools.JavaFileManager#getFileForOutput(javax.tools.JavaFileManager.Location, java.lang.String, java.lang.String, javax.tools.FileObject)
*/
@Override
public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling)
throws IOException {
Iterable extends File> files = getLocation(location);
if (files == null) {
throw new IllegalArgumentException("Unknown location : " + location);//$NON-NLS-1$
}
final Iterator extends File> iterator = files.iterator();
if (iterator.hasNext()) {
File file = iterator.next();
String normalizedFileName = normalized(packageName) + '/' + relativeName.replace('\\', '/');
File f = new File(file, normalizedFileName);
return new EclipseFileObject(packageName + File.separator + relativeName, f.toURI(), getKind(f), this.charset);
} else {
throw new IllegalArgumentException("location is empty : " + location);//$NON-NLS-1$
}
}
/* (non-Javadoc)
* @see javax.tools.JavaFileManager#getJavaFileForInput(javax.tools.JavaFileManager.Location, java.lang.String, javax.tools.JavaFileObject.Kind)
*/
@Override
public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException {
if (kind != Kind.CLASS && kind != Kind.SOURCE) {
throw new IllegalArgumentException("Invalid kind : " + kind);//$NON-NLS-1$
}
Iterable extends File> files = getLocation(location);
if (files == null) {
throw new IllegalArgumentException("Unknown location : " + location);//$NON-NLS-1$
}
String normalizedFileName = normalized(className);
normalizedFileName += kind.extension;
for (File file : files) {
if (file.isDirectory()) {
// handle directory
File f = new File(file, normalizedFileName);
if (f.exists()) {
return new EclipseFileObject(className, f.toURI(), kind, this.charset);
} else {
continue; // go to next entry in the location
}
} else if (isArchive(file)) {
// handle archive file
Archive archive = getArchive(file);
if (archive != Archive.UNKNOWN_ARCHIVE) {
if (archive.contains(normalizedFileName)) {
return archive.getArchiveFileObject(normalizedFileName, this.charset);
}
}
}
}
return null;
}
/* (non-Javadoc)
* @see javax.tools.JavaFileManager#getJavaFileForOutput(javax.tools.JavaFileManager.Location, java.lang.String, javax.tools.JavaFileObject.Kind, javax.tools.FileObject)
*/
@Override
public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling)
throws IOException {
if (kind != Kind.CLASS && kind != Kind.SOURCE) {
throw new IllegalArgumentException("Invalid kind : " + kind);//$NON-NLS-1$
}
Iterable extends File> files = getLocation(location);
if (files == null) {
if (!location.equals(StandardLocation.CLASS_OUTPUT)
&& !location.equals(StandardLocation.SOURCE_OUTPUT))
throw new IllegalArgumentException("Unknown location : " + location);//$NON-NLS-1$
// we will use either the sibling or user.dir
if (sibling != null) {
String normalizedFileName = normalized(className);
int index = normalizedFileName.lastIndexOf('/');
if (index != -1) {
normalizedFileName = normalizedFileName.substring(index + 1);
}
normalizedFileName += kind.extension;
URI uri = sibling.toUri();
URI uri2 = null;
try {
String path = uri.getPath();
index = path.lastIndexOf('/');
if (index != -1) {
path = path.substring(0, index + 1);
path += normalizedFileName;
}
uri2 = new URI(uri.getScheme(), uri.getHost(), path, uri.getFragment());
} catch (URISyntaxException e) {
throw new IllegalArgumentException("invalid sibling");//$NON-NLS-1$
}
return new EclipseFileObject(className, uri2, kind, this.charset);
} else {
String normalizedFileName = normalized(className);
normalizedFileName += kind.extension;
File f = new File(System.getProperty("user.dir"), normalizedFileName);//$NON-NLS-1$
return new EclipseFileObject(className, f.toURI(), kind, this.charset);
}
}
final Iterator extends File> iterator = files.iterator();
if (iterator.hasNext()) {
File file = iterator.next();
String normalizedFileName = normalized(className);
normalizedFileName += kind.extension;
File f = new File(file, normalizedFileName);
return new EclipseFileObject(className, f.toURI(), kind, this.charset);
} else {
throw new IllegalArgumentException("location is empty : " + location);//$NON-NLS-1$
}
}
/* (non-Javadoc)
* @see javax.tools.StandardJavaFileManager#getJavaFileObjects(java.io.File[])
*/
@Override
public Iterable extends JavaFileObject> getJavaFileObjects(File... files) {
return getJavaFileObjectsFromFiles(Arrays.asList(files));
}
/* (non-Javadoc)
* @see javax.tools.StandardJavaFileManager#getJavaFileObjects(java.lang.String[])
*/
@Override
public Iterable extends JavaFileObject> getJavaFileObjects(String... names) {
return getJavaFileObjectsFromStrings(Arrays.asList(names));
}
/* (non-Javadoc)
* @see javax.tools.StandardJavaFileManager#getJavaFileObjectsFromFiles(java.lang.Iterable)
*/
@Override
public Iterable extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable extends File> files) {
ArrayList javaFileArrayList = new ArrayList<>();
for (File f : files) {
if (f.isDirectory()) {
throw new IllegalArgumentException("file : " + f.getAbsolutePath() + " is a directory"); //$NON-NLS-1$ //$NON-NLS-2$
}
javaFileArrayList.add(new EclipseFileObject(f.getAbsolutePath(), f.toURI(), getKind(f), this.charset));
}
return javaFileArrayList;
}
/* (non-Javadoc)
* @see javax.tools.StandardJavaFileManager#getJavaFileObjectsFromStrings(java.lang.Iterable)
*/
@Override
public Iterable extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable names) {
ArrayList files = new ArrayList<>();
for (String name : names) {
files.add(new File(name));
}
return getJavaFileObjectsFromFiles(files);
}
public Kind getKind(File f) {
return getKind(getExtension(f));
}
private Kind getKind(String extension) {
if (Kind.CLASS.extension.equals(extension)) {
return Kind.CLASS;
} else if (Kind.SOURCE.extension.equals(extension)) {
return Kind.SOURCE;
} else if (Kind.HTML.extension.equals(extension)) {
return Kind.HTML;
}
return Kind.OTHER;
}
/* (non-Javadoc)
* @see javax.tools.StandardJavaFileManager#getLocation(javax.tools.JavaFileManager.Location)
*/
@Override
public Iterable extends File> getLocation(Location location) {
if (this.locations == null) return null;
return this.locations.get(location.getName());
}
private Iterable extends File> getOutputDir(String string) {
if ("none".equals(string)) {//$NON-NLS-1$
return null;
}
File file = new File(string);
if (file.exists() && !file.isDirectory()) {
throw new IllegalArgumentException("file : " + file.getAbsolutePath() + " is not a directory");//$NON-NLS-1$//$NON-NLS-2$
}
ArrayList list = new ArrayList<>(1);
list.add(file);
return list;
}
/* (non-Javadoc)
* @see javax.tools.JavaFileManager#handleOption(java.lang.String, java.util.Iterator)
*/
@Override
public boolean handleOption(String current, Iterator remaining) {
try {
if ("-bootclasspath".equals(current)) {//$NON-NLS-1$
if (remaining.hasNext()) {
final Iterable extends File> bootclasspaths = getPathsFrom(remaining.next());
if (bootclasspaths != null) {
Iterable extends File> iterable = getLocation(StandardLocation.PLATFORM_CLASS_PATH);
if ((this.flags & EclipseFileManager.HAS_ENDORSED_DIRS) == 0
&& (this.flags & EclipseFileManager.HAS_EXT_DIRS) == 0) {
// override default bootclasspath
setLocation(StandardLocation.PLATFORM_CLASS_PATH, bootclasspaths);
} else if ((this.flags & EclipseFileManager.HAS_ENDORSED_DIRS) != 0) {
// endorseddirs have been processed first
setLocation(StandardLocation.PLATFORM_CLASS_PATH,
concatFiles(iterable, bootclasspaths));
} else {
// extdirs have been processed first
setLocation(StandardLocation.PLATFORM_CLASS_PATH,
prependFiles(iterable, bootclasspaths));
}
}
this.flags |= EclipseFileManager.HAS_BOOTCLASSPATH;
return true;
} else {
throw new IllegalArgumentException();
}
}
if ("-classpath".equals(current) || "-cp".equals(current)) {//$NON-NLS-1$//$NON-NLS-2$
if (remaining.hasNext()) {
final Iterable extends File> classpaths = getPathsFrom(remaining.next());
if (classpaths != null) {
Iterable extends File> iterable = getLocation(StandardLocation.CLASS_PATH);
if (iterable != null) {
setLocation(StandardLocation.CLASS_PATH,
concatFiles(iterable, classpaths));
} else {
setLocation(StandardLocation.CLASS_PATH, classpaths);
}
if ((this.flags & EclipseFileManager.HAS_PROCESSORPATH) == 0) {
setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, classpaths);
}
}
return true;
} else {
throw new IllegalArgumentException();
}
}
if ("-encoding".equals(current)) {//$NON-NLS-1$
if (remaining.hasNext()) {
this.charset = Charset.forName(remaining.next());
return true;
} else {
throw new IllegalArgumentException();
}
}
if ("-sourcepath".equals(current)) {//$NON-NLS-1$
if (remaining.hasNext()) {
final Iterable extends File> sourcepaths = getPathsFrom(remaining.next());
if (sourcepaths != null) setLocation(StandardLocation.SOURCE_PATH, sourcepaths);
return true;
} else {
throw new IllegalArgumentException();
}
}
if ("-extdirs".equals(current)) {//$NON-NLS-1$
if (remaining.hasNext()) {
Iterable extends File> iterable = getLocation(StandardLocation.PLATFORM_CLASS_PATH);
setLocation(StandardLocation.PLATFORM_CLASS_PATH,
concatFiles(iterable, getExtdirsFrom(remaining.next())));
this.flags |= EclipseFileManager.HAS_EXT_DIRS;
return true;
} else {
throw new IllegalArgumentException();
}
}
if ("-endorseddirs".equals(current)) {//$NON-NLS-1$
if (remaining.hasNext()) {
Iterable extends File> iterable = getLocation(StandardLocation.PLATFORM_CLASS_PATH);
setLocation(StandardLocation.PLATFORM_CLASS_PATH,
prependFiles(iterable, getEndorsedDirsFrom(remaining.next())));
this.flags |= EclipseFileManager.HAS_ENDORSED_DIRS;
return true;
} else {
throw new IllegalArgumentException();
}
}
if ("-d".equals(current)) { //$NON-NLS-1$
if (remaining.hasNext()) {
final Iterable extends File> outputDir = getOutputDir(remaining.next());
if (outputDir != null) {
setLocation(StandardLocation.CLASS_OUTPUT, outputDir);
}
return true;
} else {
throw new IllegalArgumentException();
}
}
if ("-s".equals(current)) { //$NON-NLS-1$
if (remaining.hasNext()) {
final Iterable extends File> outputDir = getOutputDir(remaining.next());
if (outputDir != null) {
setLocation(StandardLocation.SOURCE_OUTPUT, outputDir);
}
return true;
} else {
throw new IllegalArgumentException();
}
}
if ("-processorpath".equals(current)) {//$NON-NLS-1$
if (remaining.hasNext()) {
final Iterable extends File> processorpaths = getPathsFrom(remaining.next());
if (processorpaths != null) {
setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, processorpaths);
}
this.flags |= EclipseFileManager.HAS_PROCESSORPATH;
return true;
} else {
throw new IllegalArgumentException();
}
}
} catch (IOException e) {
// ignore
}
return false;
}
/* (non-Javadoc)
* @see javax.tools.JavaFileManager#hasLocation(javax.tools.JavaFileManager.Location)
*/
@Override
public boolean hasLocation(Location location) {
return this.locations != null && this.locations.containsKey(location.getName());
}
/* (non-Javadoc)
* @see javax.tools.JavaFileManager#inferBinaryName(javax.tools.JavaFileManager.Location, javax.tools.JavaFileObject)
*/
@Override
public String inferBinaryName(Location location, JavaFileObject file) {
String name = file.getName();
JavaFileObject javaFileObject = null;
int index = name.lastIndexOf('.');
if (index != -1) {
name = name.substring(0, index);
}
try {
javaFileObject = getJavaFileForInput(location, name, file.getKind());
} catch (IOException e) {
// ignore
} catch (IllegalArgumentException iae) {
return null; // Either unknown kind or location not present
}
if (javaFileObject == null) {
return null;
}
return name.replace('/', '.');
}
private boolean isArchive(File f) {
String extension = getExtension(f);
return extension.equalsIgnoreCase(".jar") || extension.equalsIgnoreCase(".zip");//$NON-NLS-1$//$NON-NLS-2$
}
/* (non-Javadoc)
* @see javax.tools.StandardJavaFileManager#isSameFile(javax.tools.FileObject, javax.tools.FileObject)
*/
@Override
public boolean isSameFile(FileObject fileObject1, FileObject fileObject2) {
// EclipseFileManager creates only EcliseFileObject
if (!(fileObject1 instanceof EclipseFileObject)) throw new IllegalArgumentException("Unsupported file object class : " + fileObject1.getClass());//$NON-NLS-1$
if (!(fileObject2 instanceof EclipseFileObject)) throw new IllegalArgumentException("Unsupported file object class : " + fileObject2.getClass());//$NON-NLS-1$
return fileObject1.equals(fileObject2);
}
/* (non-Javadoc)
* @see javax.tools.OptionChecker#isSupportedOption(java.lang.String)
*/
@Override
public int isSupportedOption(String option) {
return Options.processOptionsFileManager(option);
}
/* (non-Javadoc)
* @see javax.tools.JavaFileManager#list(javax.tools.JavaFileManager.Location, java.lang.String, java.util.Set, boolean)
*/
@Override
public Iterable list(Location location, String packageName, Set kinds, boolean recurse)
throws IOException {
Iterable extends File> allFilesInLocations = getLocation(location);
if (allFilesInLocations == null) {
throw new IllegalArgumentException("Unknown location : " + location);//$NON-NLS-1$
}
ArrayList collector = new ArrayList<>();
String normalizedPackageName = normalized(packageName);
for (File file : allFilesInLocations) {
collectAllMatchingFiles(file, normalizedPackageName, kinds, recurse, collector);
}
return collector;
}
private String normalized(String className) {
char[] classNameChars = className.toCharArray();
for (int i = 0, max = classNameChars.length; i < max; i++) {
switch(classNameChars[i]) {
case '\\' :
classNameChars[i] = '/';
break;
case '.' :
classNameChars[i] = '/';
}
}
return new String(classNameChars);
}
private Iterable extends File> prependFiles(Iterable extends File> iterable,
Iterable extends File> iterable2) {
if (iterable2 == null) return iterable;
ArrayList list = new ArrayList<>();
for (Iterator extends File> iterator = iterable2.iterator(); iterator.hasNext(); ) {
list.add(iterator.next());
}
for (Iterator extends File> iterator = iterable.iterator(); iterator.hasNext(); ) {
list.add(iterator.next());
}
return list;
}
/* (non-Javadoc)
* @see javax.tools.StandardJavaFileManager#setLocation(javax.tools.JavaFileManager.Location, java.lang.Iterable)
*/
@Override
public void setLocation(Location location, Iterable extends File> path) throws IOException {
if (path != null) {
if (location.isOutputLocation()) {
// output location
int count = 0;
for (Iterator extends File> iterator = path.iterator(); iterator.hasNext(); ) {
iterator.next();
count++;
}
if (count != 1) {
throw new IllegalArgumentException("output location can only have one path");//$NON-NLS-1$
}
}
this.locations.put(location.getName(), path);
}
}
public void setLocale(Locale locale) {
this.locale = locale == null ? Locale.getDefault() : locale;
try {
this.bundle = ResourceBundleFactory.getBundle(this.locale);
} catch(MissingResourceException e) {
System.out.println("Missing resource : " + Main.bundleName.replace('.', '/') + ".properties for locale " + locale); //$NON-NLS-1$//$NON-NLS-2$
throw e;
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
public void processPathEntries(final int defaultSize, final ArrayList paths,
final String currentPath, String customEncoding, boolean isSourceOnly,
boolean rejectDestinationPathOnJars) {
String currentClasspathName = null;
String currentDestinationPath = null;
ArrayList currentRuleSpecs = new ArrayList(defaultSize);
StringTokenizer tokenizer = new StringTokenizer(currentPath,
File.pathSeparator + "[]", true); //$NON-NLS-1$
ArrayList tokens = new ArrayList();
while (tokenizer.hasMoreTokens()) {
tokens.add(tokenizer.nextToken());
}
// state machine
final int start = 0;
final int readyToClose = 1;
// 'path' 'path1[rule];path2'
final int readyToCloseEndingWithRules = 2;
// 'path[rule]' 'path1;path2[rule]'
final int readyToCloseOrOtherEntry = 3;
// 'path[rule];' 'path;' 'path1;path2;'
final int rulesNeedAnotherRule = 4;
// 'path[rule1;'
final int rulesStart = 5;
// 'path[' 'path1;path2['
final int rulesReadyToClose = 6;
// 'path[rule' 'path[rule1;rule2'
final int destinationPathReadyToClose = 7;
// 'path[-d bin'
final int readyToCloseEndingWithDestinationPath = 8;
// 'path[-d bin]' 'path[rule][-d bin]'
final int destinationPathStart = 9;
// 'path[rule]['
final int bracketOpened = 10;
// '.*[.*'
final int bracketClosed = 11;
// '.*([.*])+'
final int error = 99;
int state = start;
String token = null;
int cursor = 0, tokensNb = tokens.size(), bracket = -1;
while (cursor < tokensNb && state != error) {
token = (String) tokens.get(cursor++);
if (token.equals(File.pathSeparator)) {
switch (state) {
case start:
case readyToCloseOrOtherEntry:
case bracketOpened:
break;
case readyToClose:
case readyToCloseEndingWithRules:
case readyToCloseEndingWithDestinationPath:
state = readyToCloseOrOtherEntry;
addNewEntry(paths, currentClasspathName, currentRuleSpecs,
customEncoding, currentDestinationPath, isSourceOnly,
rejectDestinationPathOnJars);
currentRuleSpecs.clear();
break;
case rulesReadyToClose:
state = rulesNeedAnotherRule;
break;
case destinationPathReadyToClose:
throw new IllegalArgumentException(
this.bind("configure.incorrectDestinationPathEntry", //$NON-NLS-1$
currentPath));
case bracketClosed:
cursor = bracket + 1;
state = rulesStart;
break;
default:
state = error;
}
} else if (token.equals("[")) { //$NON-NLS-1$
switch (state) {
case start:
currentClasspathName = ""; //$NON-NLS-1$
//$FALL-THROUGH$
case readyToClose:
bracket = cursor - 1;
//$FALL-THROUGH$
case bracketClosed:
state = bracketOpened;
break;
case readyToCloseEndingWithRules:
state = destinationPathStart;
break;
case readyToCloseEndingWithDestinationPath:
state = rulesStart;
break;
case bracketOpened:
default:
state = error;
}
} else if (token.equals("]")) { //$NON-NLS-1$
switch (state) {
case rulesReadyToClose:
state = readyToCloseEndingWithRules;
break;
case destinationPathReadyToClose:
state = readyToCloseEndingWithDestinationPath;
break;
case bracketOpened:
state = bracketClosed;
break;
case bracketClosed:
default:
state = error;
}
} else {
// regular word
switch (state) {
case start:
case readyToCloseOrOtherEntry:
state = readyToClose;
currentClasspathName = token;
break;
case rulesStart:
if (token.startsWith("-d ")) { //$NON-NLS-1$
if (currentDestinationPath != null) {
throw new IllegalArgumentException(
this.bind("configure.duplicateDestinationPathEntry", //$NON-NLS-1$
currentPath));
}
currentDestinationPath = token.substring(3).trim();
state = destinationPathReadyToClose;
break;
} // else we proceed with a rule
//$FALL-THROUGH$
case rulesNeedAnotherRule:
if (currentDestinationPath != null) {
throw new IllegalArgumentException(
this.bind("configure.accessRuleAfterDestinationPath", //$NON-NLS-1$
currentPath));
}
state = rulesReadyToClose;
currentRuleSpecs.add(token);
break;
case destinationPathStart:
if (!token.startsWith("-d ")) { //$NON-NLS-1$
state = error;
} else {
currentDestinationPath = token.substring(3).trim();
state = destinationPathReadyToClose;
}
break;
case bracketClosed:
for (int i = bracket; i < cursor ; i++) {
currentClasspathName += (String) tokens.get(i);
}
state = readyToClose;
break;
case bracketOpened:
break;
default:
state = error;
}
}
if (state == bracketClosed && cursor == tokensNb) {
cursor = bracket + 1;
state = rulesStart;
}
}
switch(state) {
case readyToCloseOrOtherEntry:
break;
case readyToClose:
case readyToCloseEndingWithRules:
case readyToCloseEndingWithDestinationPath:
addNewEntry(paths, currentClasspathName, currentRuleSpecs,
customEncoding, currentDestinationPath, isSourceOnly,
rejectDestinationPathOnJars);
break;
case bracketOpened:
case bracketClosed:
default :
// we go on anyway
}
}
@SuppressWarnings({"rawtypes", "unchecked"})
protected void addNewEntry(ArrayList paths, String currentClasspathName,
ArrayList currentRuleSpecs, String customEncoding,
String destPath, boolean isSourceOnly,
boolean rejectDestinationPathOnJars) {
int rulesSpecsSize = currentRuleSpecs.size();
AccessRuleSet accessRuleSet = null;
if (rulesSpecsSize != 0) {
AccessRule[] accessRules = new AccessRule[currentRuleSpecs.size()];
boolean rulesOK = true;
Iterator i = currentRuleSpecs.iterator();
int j = 0;
while (i.hasNext()) {
String ruleSpec = (String) i.next();
char key = ruleSpec.charAt(0);
String pattern = ruleSpec.substring(1);
if (pattern.length() > 0) {
switch (key) {
case '+':
accessRules[j++] = new AccessRule(pattern
.toCharArray(), 0);
break;
case '~':
accessRules[j++] = new AccessRule(pattern
.toCharArray(),
IProblem.DiscouragedReference);
break;
case '-':
accessRules[j++] = new AccessRule(pattern
.toCharArray(),
IProblem.ForbiddenReference);
break;
case '?':
accessRules[j++] = new AccessRule(pattern
.toCharArray(),
IProblem.ForbiddenReference, true/*keep looking for accessible type*/);
break;
default:
rulesOK = false;
}
} else {
rulesOK = false;
}
}
if (rulesOK) {
accessRuleSet = new AccessRuleSet(accessRules, AccessRestriction.COMMAND_LINE, currentClasspathName);
} else {
return;
}
}
if (Main.NONE.equals(destPath)) {
destPath = Main.NONE; // keep == comparison valid
}
if (rejectDestinationPathOnJars && destPath != null &&
(currentClasspathName.endsWith(".jar") || //$NON-NLS-1$
currentClasspathName.endsWith(".zip"))) { //$NON-NLS-1$
throw new IllegalArgumentException(
this.bind("configure.unexpectedDestinationPathEntryFile", //$NON-NLS-1$
currentClasspathName));
}
FileSystem.Classpath currentClasspath = FileSystem.getClasspath(
currentClasspathName,
customEncoding,
isSourceOnly,
accessRuleSet,
destPath, null);
if (currentClasspath != null) {
paths.add(currentClasspath);
}
}
/*
* Lookup the message with the given ID in this catalog and bind its
* substitution locations with the given string.
*/
private String bind(String id, String binding) {
return bind(id, new String[] { binding });
}
/*
* Lookup the message with the given ID in this catalog and bind its
* substitution locations with the given string values.
*/
private String bind(String id, String[] arguments) {
if (id == null)
return "No message available"; //$NON-NLS-1$
String message = null;
try {
message = this.bundle.getString(id);
} catch (MissingResourceException e) {
// If we got an exception looking for the message, fail gracefully by just returning
// the id we were looking for. In most cases this is semi-informative so is not too bad.
return "Missing message: " + id + " in: " + Main.bundleName; //$NON-NLS-2$ //$NON-NLS-1$
}
return MessageFormat.format(message, (Object[]) arguments);
}
}