/** * Copyright (c) 2014 Takari, Inc. * 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 */ package io.takari.maven.plugins.compile.jdt.classpath; import static org.eclipse.jdt.internal.compiler.util.SuffixConstants.SUFFIX_STRING_class; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException; import org.eclipse.jdt.internal.compiler.env.AccessRestriction; import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; import org.osgi.framework.BundleException; public class ClasspathJar extends DependencyClasspathEntry implements ClasspathEntry { private final ZipFile zipFile; private ClasspathJar(File file, ZipFile zipFile, Collection<String> packageNames, Collection<String> exportedPackages) throws IOException { super(file, packageNames, exportedPackages); this.zipFile = zipFile; } private static Set<String> getPackageNames(ZipFile zipFile) { Set<String> result = new HashSet<String>(); for (Enumeration e = zipFile.entries(); e.hasMoreElements();) { ZipEntry entry = (ZipEntry) e.nextElement(); String name = entry.getName(); int last = name.lastIndexOf('/'); while (last > 0) { name = name.substring(0, last); result.add(name); last = name.lastIndexOf('/'); } } return result; } @Override public NameEnvironmentAnswer findType(String packageName, String typeName, AccessRestriction accessRestriction) { try { String qualifiedFileName = packageName + "/" + typeName + SUFFIX_STRING_class; ClassFileReader reader = ClassFileReader.read(this.zipFile, qualifiedFileName); if (reader != null) { return new NameEnvironmentAnswer(reader, accessRestriction); } } catch (ClassFormatException | IOException e) { // treat as if class file is missing } return null; } @Override public String toString() { return "Classpath for jar file " + file.getPath(); //$NON-NLS-1$ } public static ClasspathJar create(File file) throws IOException { ZipFile zipFile = new ZipFile(file); Set<String> packageNames = getPackageNames(zipFile); Collection<String> exportedPackages = null; // TODO do not look for exported packages in java standard library ZipEntry entry = zipFile.getEntry(PATH_EXPORT_PACKAGE); if (entry != null) { try (InputStream is = zipFile.getInputStream(entry)) { exportedPackages = parseExportPackage(is); } } if (exportedPackages == null) { entry = zipFile.getEntry(PATH_MANIFESTMF); if (entry != null) { try (InputStream is = zipFile.getInputStream(entry)) { exportedPackages = parseBundleManifest(is); } catch (BundleException e) { // silently ignore bundle manifest parsing problems } } } return new ClasspathJar(file, zipFile, packageNames, exportedPackages); } }