blob: e58a375d9ed3ab0622ea551a01070af115831159 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 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:
* 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.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.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
@SuppressWarnings({ "rawtypes", "unchecked" })
public class ClasspathJsr199 extends ClasspathLocation {
private static final Set<JavaFileObject.Kind> fileTypes = new HashSet<>();
static {
fileTypes.add(JavaFileObject.Kind.CLASS);
}
private JavaFileManager fileManager;
private JavaFileManager.Location location;
public ClasspathJsr199(JavaFileManager file, JavaFileManager.Location location) {
super(null, null);
this.fileManager = file;
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 qualifiedBinaryFileName) {
return findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName, false);
}
@Override
public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String aQualifiedBinaryFileName,
boolean 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 qualifiedPackageName = File.separatorChar == '/' ? aQualifiedPackageName : aQualifiedPackageName.replace(
File.separatorChar, '/');
Iterable<JavaFileObject> 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 {
// nothing to do
}
@Override
public boolean isPackage(String aQualifiedPackageName) {
String qualifiedPackageName = File.separatorChar == '/' ? aQualifiedPackageName : aQualifiedPackageName.replace(
File.separatorChar, '/');
boolean result = false;
try {
Iterable<JavaFileObject> 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 result;
}
@Override
public void reset() {
try {
this.fileManager.flush();
} catch (IOException e) {
// ignore
}
}
@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;
}
}