package org.eclipse.jdt.internal.core;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaModelStatusConstants;
import org.eclipse.jdt.core.IModuleDescription;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.env.IModule;
import org.eclipse.jdt.internal.compiler.env.IModulePathEntry;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.util.JRTUtil;
import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject;
import org.eclipse.jdt.internal.core.util.Util;
public class JrtPackageFragmentRoot extends JarPackageFragmentRoot implements IModulePathEntry {
String moduleName;
public static final ThreadLocal<Boolean> workingOnOldClasspath = new ThreadLocal<>();
protected JrtPackageFragmentRoot(IPath jrtPath, String moduleName, JavaProject project, IClasspathAttribute[] extraAttributes) {
super(null, jrtPath, project, extraAttributes);
this.moduleName = moduleName;
}
@Override
protected boolean computeChildren(OpenableElementInfo info, IResource underlyingResource) throws JavaModelException {
final HashtableOfArrayToObject rawPackageInfo = new HashtableOfArrayToObject();
final String compliance = CompilerOptions.VERSION_1_8;
rawPackageInfo.put(CharOperation.NO_STRINGS, new ArrayList[] { EMPTY_LIST, EMPTY_LIST });
try {
org.eclipse.jdt.internal.compiler.util.JRTUtil.walkModuleImage(this.jarPath.toFile(),
new org.eclipse.jdt.internal.compiler.util.JRTUtil.JrtFileVisitor<Path>() {
@Override
public FileVisitResult visitPackage(Path dir, Path mod, BasicFileAttributes attrs) throws IOException {
initRawPackageInfo(rawPackageInfo, dir.toString(), true, compliance);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path path, Path mod, BasicFileAttributes attrs) throws IOException {
initRawPackageInfo(rawPackageInfo, path.toString(), false, compliance);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitModule(Path path, String name) throws IOException {
if (!JrtPackageFragmentRoot.this.moduleName.equals(name)) {
return FileVisitResult.SKIP_SUBTREE;
}
return FileVisitResult.CONTINUE;
}
}, JRTUtil.NOTIFY_ALL);
} catch (IOException e) {
Util.log(IStatus.ERROR, "Error reading modules" + toStringWithAncestors());
}
info.setChildren(createChildren(rawPackageInfo));
((JarPackageFragmentRootInfo) info).rawPackageInfo = rawPackageInfo;
return true;
}
@Override
SourceMapper createSourceMapper(IPath sourcePath, IPath rootPath) throws JavaModelException {
IClasspathEntry entry = ((JavaProject) getParent()).getClasspathEntryFor(getPath());
String encoding = (entry== null) ? null : ((ClasspathEntry) entry).getSourceAttachmentEncoding();
IModule mod = getModule();
String modName = mod == null ? null : new String(mod.name());
SourceMapper mapper = new SourceMapper(
sourcePath,
rootPath == null ? modName : rootPath.toOSString(),
getJavaProject().getOptions(true),
encoding);
return mapper;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o instanceof JrtPackageFragmentRoot) {
JrtPackageFragmentRoot other= (JrtPackageFragmentRoot) o;
return this.moduleName.equals(other.moduleName) &&
this.jarPath.equals(other.jarPath) &&
Arrays.equals(this.extraAttributes, other.extraAttributes);
}
return false;
}
@Override
public String getElementName() {
return this.moduleName;
}
@Override
public PackageFragment getPackageFragment(String[] pkgName) {
return new JarPackageFragment(this, pkgName);
}
@Override
public int hashCode() {
return this.jarPath.hashCode() + this.moduleName.hashCode() + Arrays.hashCode(this.extraAttributes);
}
@Override
protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
buffer.append(tabString(tab));
buffer.append("<module:").append(this.moduleName).append(">");
if (info == null) {
buffer.append(" (not open)");
}
}
@Override
public IModule getModule() {
IModuleDescription desc = getModuleDescription();
if (desc != null) {
try {
return (IModule)((JavaElement) desc).getElementInfo();
} catch (JavaModelException e) {
Util.log(e);
}
}
return null;
}
@Override
protected boolean isComplianceJava9OrHigher() {
return true;
}
@Override
public char[][] getModulesDeclaringPackage(String qualifiedPackageName, String requestedModuleName) {
if (requestedModuleName != null && !requestedModuleName.equals(this.moduleName))
return null;
if (getPackageFragment(qualifiedPackageName).exists()) {
return new char[][] { requestedModuleName.toCharArray() };
}
return null;
}
@Override
protected boolean ignoreErrorStatus(IStatus status) {
if (status.getCode() == IJavaModelStatusConstants.ELEMENT_NOT_ON_CLASSPATH
&& workingOnOldClasspath.get() == Boolean.TRUE)
return true;
return false;
}
}