All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.takari.maven.plugins.compile.jdt.classpath.DependencyClasspathEntry Maven / Gradle / Ivy

There is a newer version: 2.2.0
Show newest version
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();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy