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

io.github.algomaster99.terminator.commons.jar.JarScanner Maven / Gradle / Ivy

package io.github.algomaster99.terminator.commons.jar;

import static io.github.algomaster99.terminator.commons.fingerprint.classfile.HashComputer.computeHash;

import io.github.algomaster99.terminator.commons.fingerprint.classfile.ClassFileAttributes;
import io.github.algomaster99.terminator.commons.fingerprint.classfile.ClassFileUtilities;
import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class JarScanner {

    private JarScanner() {}

    public static void goInsideJarAndUpdateFingerprints(
            File artifactFileOnSystem,
            Map> fingerprints,
            String algorithm,
            String... provenanceInformation) {
        try (JarFile jarFile = new JarFile(artifactFileOnSystem)) {
            Enumeration jarEntries = jarFile.entries();
            while (jarEntries.hasMoreElements()) {
                JarEntry jarEntry = jarEntries.nextElement();
                if (jarEntry.getName().endsWith(".class")) {
                    String jarEntryName =
                            jarEntry.getName().substring(0, jarEntry.getName().length() - ".class".length());
                    String strippedJarEntryName = stripMetaInf(jarEntryName);

                    byte[] classfileBytes = jarFile.getInputStream(jarEntry).readAllBytes();
                    String classfileVersion = ClassFileUtilities.getVersion(classfileBytes);
                    String hashOfClass = computeHash(classfileBytes);

                    ClassFileAttributes classFileAttributes =
                            new ClassFileAttributes(classfileVersion, hashOfClass, algorithm);

                    if (fingerprints.containsKey(strippedJarEntryName)) {
                        Set alreadyExistingProvenance = fingerprints.get(strippedJarEntryName);
                        alreadyExistingProvenance.add(classFileAttributes);
                    } else {
                        Set newProvenance = new HashSet<>();
                        newProvenance.add(classFileAttributes);
                        fingerprints.put(strippedJarEntryName, newProvenance);
                    }
                }
            }
        } catch (IOException e) {
            System.err.println("Could not open JAR file: " + artifactFileOnSystem);
            throw new RuntimeException(e);
        }
    }

    /** Strips the META-INF/versions/{java_version}/ from the class name. */
    private static String stripMetaInf(String jarEntryName) {
        if (!jarEntryName.startsWith("META-INF")) {
            return jarEntryName;
        }
        final String regex = "META-INF\\/versions\\/[0-9]+\\/(.*)";
        final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
        final Matcher matcher = pattern.matcher(jarEntryName);
        matcher.find();
        return matcher.group(1);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy