Skip to content

Commit

Permalink
Reading same class from multiple files
Browse files Browse the repository at this point in the history
  • Loading branch information
nielsbasjes committed Nov 5, 2023
1 parent 0c4fa84 commit 0e49770
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 10 deletions.
22 changes: 21 additions & 1 deletion src/main/java/org/vafer/jdependency/Clazz.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,36 @@ public final class Clazz implements Comparable<Clazz> {
private final Set<Clazz> references = new HashSet<>();
private final Map<ClazzpathUnit, String> units = new HashMap<>();

// Usually a class is only in a single file.
// When using MultiRelease Jar files this can be multiple files, one for each java release specified.
// The default filename is under the key "8".
private final Map<String, String> classFilenames = new HashMap<>();

// The name of the class (like "org.vafer.jdependency.Clazz")
private final String name;

public Clazz( final String pName ) {
name = pName;
classFilenames.put("8", pName.replace(".", "/"));
}

public Clazz( final String pName, final String pForJava, final String pFileName ) {
name = pName;
classFilenames.put(pForJava, pFileName);
}

public void addMultiReleaseFile(String pForJava, String pFileName) {
classFilenames.put(pForJava, pFileName);
}

public String getName() {
return name;
}

public Map<String, String> getFileNames() {
return classFilenames;
}

public void addClazzpathUnit( final ClazzpathUnit pUnit, final String pDigest ) {
units.put(pUnit, pDigest);
}
Expand Down Expand Up @@ -116,7 +136,7 @@ public int compareTo( final Clazz pO ) {
}

public String toString() {
return name;
return name + " in " + classFilenames;
}

}
36 changes: 27 additions & 9 deletions src/main/java/org/vafer/jdependency/Clazzpath.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.objectweb.asm.ClassReader;
import org.apache.commons.io.input.MessageDigestCalculatingInputStream;
Expand All @@ -45,21 +47,35 @@ public final class Clazzpath {
private final Map<String, Clazz> clazzes = new HashMap<>();
private final boolean versions;

private static final Pattern EXTRACT_MULTI_RELEASE_JAVA_VERSION = Pattern.compile("META-INF[/\\\\]versions[/\\\\](\\d+)[/\\\\]([^.]+).class$");

private abstract static class Resource {

private static final int ext = ".class".length();

public final String fileName;
public final String forJava;
public final String name;

Resource( final String pName ) {
Resource( final String pFileName ) {
super();
this.fileName = pFileName;

final int all = pFileName.length();

Matcher matcher = EXTRACT_MULTI_RELEASE_JAVA_VERSION.matcher(pFileName);
if (matcher.find()) {
forJava = matcher.group(1);
this.name = separatorsToUnix(matcher.group(2))
.replace('/', '.');
} else {
forJava = "8";
// foo/bar/Foo.class -> // foo.bar.Foo
this.name = separatorsToUnix(pFileName)
.substring(0, all - ext)
.replace('/', '.');
}

final int all = pName.length();

// foo/bar/Foo.class -> // foo.bar.Foo
this.name = separatorsToUnix(pName)
.substring(0, all - ext)
.replace('/', '.');
}

abstract InputStream getInputStream() throws IOException;
Expand All @@ -68,7 +84,7 @@ private abstract static class Resource {
private static boolean isValidResourceName( final String pName ) {
return pName != null
&& pName.endsWith(".class")
&& !pName.contains( "-" );
&& ( !pName.contains( "-" ) || pName.contains("META-INF/versions/") );
}

public Clazzpath() {
Expand Down Expand Up @@ -187,8 +203,10 @@ private ClazzpathUnit addClazzpathUnit( final Iterable<Resource> resources, fina
// already marked missing
clazz = missing.remove(clazzName);
} else {
clazz = new Clazz(clazzName);
clazz = new Clazz(clazzName, resource.forJava, resource.fileName);
}
} else {
clazz.addMultiReleaseFile(resource.forJava, resource.fileName);
}
final String d = Base64.getEncoder().encodeToString(digest.digest());
clazz.addClazzpathUnit(unit, d);
Expand Down
11 changes: 11 additions & 0 deletions src/test/java/org/vafer/jdependency/ClazzpathUnitTestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,15 @@ public void testDependencies() throws IOException {

}

@Test
public void testMultiReleaseJar() throws IOException {
final Clazzpath cp = new Clazzpath();
final ClazzpathUnit u = cp.addClazzpathUnit(resourceFile("src/test/resources/multi-jdk-1.0.0.jar"));
for (Clazz clazz : u.getClazzes()) {
System.out.println(clazz);
}
}



}
Binary file added src/test/resources/multi-jdk-1.0.0.jar
Binary file not shown.

0 comments on commit 0e49770

Please sign in to comment.