io.takari.maven.plugins.compile.jdt.classpath.DependencyClasspathEntry Maven / Gradle / Ivy
package io.takari.maven.plugins.compile.jdt.classpath;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
import org.eclipse.jdt.internal.compiler.env.AccessRule;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.osgi.framework.util.CaseInsensitiveDictionaryMap;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.CharStreams;
import com.google.common.io.LineProcessor;
import io.takari.maven.plugins.exportpackage.ExportPackageMojo;
public abstract class DependencyClasspathEntry implements ClasspathEntry {
protected static final String PATH_EXPORT_PACKAGE = ExportPackageMojo.PATH_EXPORT_PACKAGE;
protected static final String PATH_MANIFESTMF = "META-INF/MANIFEST.MF";
protected final Path file;
protected final Set packageNames;
protected final Set exportedPackages;
protected DependencyClasspathEntry(Path file, Collection packageNames, Collection exportedPackages) {
this.file = PathNormalizer.getCanonicalPath(file);
this.packageNames = ImmutableSet.copyOf(packageNames);
this.exportedPackages = exportedPackages != null ? ImmutableSet.copyOf(exportedPackages) : null;
}
protected AccessRestriction getAccessRestriction(String packageName) {
if (exportedPackages != null && !exportedPackages.contains(packageName)) {
AccessRule rule = new AccessRule(null /* pattern */, IProblem.ForbiddenReference, true /* keep looking for accessible type */);
return new AccessRestriction(rule, AccessRestriction.COMMAND_LINE, getEntryName());
}
return null;
}
@Override
public Collection getPackageNames() {
return packageNames;
}
protected static Collection parseExportPackage(InputStream is) throws IOException {
LineProcessor> processor = new LineProcessor>() {
final List result = new ArrayList();
@Override
public boolean processLine(String line) throws IOException {
result.add(line.replace('.', '/'));
return true; // keep reading
}
@Override
public List getResult() {
return result;
}
};
return CharStreams.readLines(new InputStreamReader(is, Charsets.UTF_8), processor);
}
protected static Collection parseBundleManifest(InputStream is) throws IOException, BundleException {
Map headers = parseManifest(is);
if (!headers.containsKey(Constants.BUNDLE_SYMBOLICNAME)) {
return null; // not an OSGi bundle
}
String exportPackageHeader = headers.get(Constants.EXPORT_PACKAGE);
if (exportPackageHeader == null) {
return ImmutableSet.of(); // nothing is exported
}
Set packages = new HashSet<>();
for (ManifestElement element : ManifestElement.parseHeader(Constants.EXPORT_PACKAGE, exportPackageHeader)) {
packages.add(element.getValue().replace('.', '/'));
}
return packages;
}
private static CaseInsensitiveDictionaryMap parseManifest(InputStream is) throws IOException, BundleException {
CaseInsensitiveDictionaryMap headers = new CaseInsensitiveDictionaryMap<>();
ManifestElement.parseBundleManifest(is, headers);
return headers;
}
@Override
public String getEntryDescription() {
StringBuilder sb = new StringBuilder(getEntryName());
if (exportedPackages != null) {
sb.append("[");
int idx = 0;
for (String exportedPackage : exportedPackages) {
if (idx++ > 0) {
sb.append(File.pathSeparatorChar);
}
sb.append('+').append(exportedPackage).append("/*");
}
if (idx > 0) {
sb.append(File.pathSeparatorChar);
}
sb.append("?**/*");
sb.append(']');
}
return sb.toString();
}
@Override
public NameEnvironmentAnswer findType(String packageName, String typeName) {
return findType(packageName, typeName, getAccessRestriction(packageName));
}
public abstract NameEnvironmentAnswer findType(String packageName, String typeName, AccessRestriction accessRestriction);
public String getEntryName() {
return file.toString();
}
}