org.eclipse.jdt.internal.compiler.batch.ClasspathJsr199 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
Eclipse Compiler for Java(TM)
/*******************************************************************************
* Copyright (c) 2015, 2018 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Kenneth Olson - initial API and implementation
* Dennis Hendriks - initial API and implementation
* IBM Corporation - Contribution for bug 188796
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.batch;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.env.IModule;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
@SuppressWarnings({ "rawtypes", "unchecked" })
public class ClasspathJsr199 extends ClasspathLocation {
private static final Set fileTypes = new HashSet<>();
static {
fileTypes.add(JavaFileObject.Kind.CLASS);
}
private JavaFileManager fileManager;
private JavaFileManager.Location location;
private Classpath jrt;
public ClasspathJsr199(JavaFileManager file, JavaFileManager.Location location) {
super(null, null);
this.fileManager = file;
this.location = location;
}
public ClasspathJsr199(Classpath jrt, JavaFileManager file, JavaFileManager.Location location) {
super(null, null);
this.fileManager = file;
this.jrt = jrt;
this.location = location;
}
/*
* Maintain two separate constructors to avoid this being constructed with any other kind of classpath
* (other than ClasspathJrt and ClasspathJep249
*/
public ClasspathJsr199(ClasspathJep247 older, JavaFileManager file, JavaFileManager.Location location) {
super(null, null);
this.fileManager = file;
this.jrt = older;
this.location = location;
}
@Override
public List fetchLinkedJars(FileSystem.ClasspathSectionProblemReporter problemReporter) {
// Assume no linked jars
return null;
}
@Override
public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String moduleName,
String aQualifiedBinaryFileName, boolean asBinaryOnly) {
if (this.jrt != null) {
return this.jrt.findClass(typeName, qualifiedPackageName, moduleName, aQualifiedBinaryFileName, asBinaryOnly);
}
String qualifiedBinaryFileName = File.separatorChar == '/'
? aQualifiedBinaryFileName
: aQualifiedBinaryFileName.replace(File.separatorChar, '/');
try {
int lastDot = qualifiedBinaryFileName.lastIndexOf('.');
String className = lastDot < 0 ? qualifiedBinaryFileName : qualifiedBinaryFileName.substring(0, lastDot);
JavaFileObject jfo = null;
try {
jfo = this.fileManager.getJavaFileForInput(this.location, className, JavaFileObject.Kind.CLASS);
} catch (IOException e) {
// treat as if class file is missing
}
if (jfo == null)
return null; // most common case
try (InputStream inputStream = jfo.openInputStream()) {
ClassFileReader reader = ClassFileReader.read(inputStream, qualifiedBinaryFileName);
if (reader != null) {
return new NameEnvironmentAnswer(reader, fetchAccessRestriction(qualifiedBinaryFileName));
}
}
} catch (ClassFormatException e) {
// treat as if class file is missing
} catch (IOException e) {
// treat as if class file is missing
}
return null;
}
@Override
public char[][][] findTypeNames(String aQualifiedPackageName, String moduleName) {
if (this.jrt != null) {
return this.jrt.findTypeNames(aQualifiedPackageName, moduleName);
}
String qualifiedPackageName = File.separatorChar == '/' ? aQualifiedPackageName : aQualifiedPackageName.replace(
File.separatorChar, '/');
Iterable files = null;
try {
files = this.fileManager.list(this.location, qualifiedPackageName, fileTypes, false);
} catch (IOException e) {
// treat as if empty
}
if (files == null) {
return null;
}
ArrayList answers = new ArrayList();
char[][] packageName = CharOperation.splitOn(File.separatorChar, qualifiedPackageName.toCharArray());
for (JavaFileObject file : files) {
String fileName = file.toUri().getPath();
int last = fileName.lastIndexOf('/');
if (last > 0) {
int indexOfDot = fileName.lastIndexOf('.');
if (indexOfDot != -1) {
String typeName = fileName.substring(last + 1, indexOfDot);
answers.add(CharOperation.arrayConcat(packageName, typeName.toCharArray()));
}
}
}
int size = answers.size();
if (size != 0) {
char[][][] result = new char[size][][];
answers.toArray(result);
return result;
}
return null;
}
@Override
public void initialize() throws IOException {
if (this.jrt != null) {
this.jrt.initialize();
}
}
@Override
public void acceptModule(IModule mod) {
// do nothing
}
@Override
public char[][] getModulesDeclaringPackage(String aQualifiedPackageName, String moduleName) {
if (this.jrt != null) {
return this.jrt.getModulesDeclaringPackage(aQualifiedPackageName, moduleName);
}
String qualifiedPackageName = File.separatorChar == '/' ? aQualifiedPackageName : aQualifiedPackageName.replace(
File.separatorChar, '/');
boolean result = false;
try {
Iterable files = this.fileManager.list(this.location, qualifiedPackageName, fileTypes, false);
Iterator f = files.iterator();
// if there is any content, assume a package
if (f.hasNext()) {
result = true;
} else {
// I hate to do this since it is expensive and will throw off garbage
// but can't think of an alternative now
files = this.fileManager.list(this.location, qualifiedPackageName, fileTypes, true);
f = files.iterator();
// if there is any content, assume a package
if (f.hasNext()) {
result = true;
}
}
} catch (IOException e) {
// treat as if missing
}
return singletonModuleNameIf(result);
}
@Override
public boolean hasCompilationUnit(String qualifiedPackageName, String moduleName) {
if (this.jrt != null)
return this.jrt.hasCompilationUnit(qualifiedPackageName, moduleName);
return false;
}
@Override
public void reset() {
try {
super.reset();
this.fileManager.flush();
} catch (IOException e) {
// ignore
}
if (this.jrt != null) {
this.jrt.reset();
}
}
@Override
public String toString() {
return "Classpath for Jsr 199 JavaFileManager: " + this.location; //$NON-NLS-1$
}
@Override
public char[] normalizedPath() {
if (this.normalizedPath == null) {
this.normalizedPath = this.path.toCharArray();
}
return this.normalizedPath;
}
@Override
public String getPath() {
if (this.path == null) {
this.path = this.location.getName();
}
return this.path;
}
@Override
public int getMode() {
return BINARY;
}
@Override
public boolean hasAnnotationFileFor(String qualifiedTypeName) {
return false;
}
@Override
public Collection getModuleNames(Collection limitModules) {
if (this.jrt != null)
return this.jrt.getModuleNames(limitModules);
return Collections.emptyList();
}
@Override
public boolean hasModule() {
if (this.jrt != null) {
return this.jrt.hasModule();
}
return super.hasModule();
}
@Override
public IModule getModule(char[] name) {
if (this.jrt != null) {
return this.jrt.getModule(name);
}
return super.getModule(name);
}
@Override
public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName,
String moduleName, String qualifiedBinaryFileName) {
//
return findClass(typeName, qualifiedPackageName, moduleName, qualifiedBinaryFileName, false);
}
}