Skip to content

Commit

Permalink
refactor: Tweak out from checksum command
Browse files Browse the repository at this point in the history
Relates to #13
  • Loading branch information
aalmiray committed Mar 5, 2023
1 parent ed49bd0 commit 015bb87
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 53 deletions.
2 changes: 1 addition & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ org.aopalliance.intercept.MethodInterceptor
org.aopalliance.intercept.MethodInvocation
----

`jackson-core` is an Multi Release JAR (MR-JAR).
`jackson-core` is a Multi Release JAR (MR-JAR).

[source]
----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@

import java.util.Set;

import static org.kordamp.jarviz.core.internal.Colorizer.cyan;
import static org.kordamp.jarviz.core.internal.Colorizer.green;
import static org.kordamp.jarviz.core.internal.Colorizer.red;
import static org.kordamp.jarviz.util.StringUtils.padRight;

/**
Expand Down Expand Up @@ -74,19 +77,8 @@ private void output(Configuration configuration, JarProcessor.JarFileResult<Set<
configuration.getOut().println($$("output.subject", result.getJarFileName()));
result.getResult().forEach(checksum -> {
String extension = padRight(checksum.getAlgorithm().extension(), 7);
String outcome = "✅";
switch (checksum.getOutcome()) {
case FAILURE:
outcome = "❌";
break;
case UNAVAILABLE:
outcome = "🔘";
break;
default:
outcome = "✅";
}

configuration.getOut().println(result.getJarFileName() + extension + " " + outcome);
configuration.getOut().println(result.getJarFileName() + extension + " " + colorize(checksum.getOutcome()));
});
}

Expand All @@ -113,4 +105,16 @@ private void buildReport(Node root, JarProcessor.JarFileResult<Set<Checksum>> re
}
});
}

private String colorize(Checksum.Outcome outcome) {
switch (outcome) {
case SUCCESS:
return green(outcome.toString());
case FAILURE:
return red(outcome.toString());
case UNAVAILABLE:
return cyan(outcome.toString());
}
return "";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2022-2023 The Jarviz authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kordamp.jarviz.core.internal;

import org.kordamp.jarviz.core.model.Gav;
import org.kordamp.jarviz.core.model.GavAware;

import java.io.File;
import java.io.IOException;
import java.util.jar.JarFile;

/**
* @author Andres Almiray
* @since 0.3.0
*/
public class GavAwareJarFile extends JarFile implements GavAware {
private final Gav gav;

public GavAwareJarFile(File file, Gav gav) throws IOException {
super(file);
this.gav = gav;
}

@Override
public Gav getGav() {
return gav;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2022-2023 The Jarviz authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kordamp.jarviz.core.model;

import org.kordamp.jarviz.bundle.RB;
import org.kordamp.jarviz.core.JarvizException;

import java.util.Objects;
import java.util.Properties;

/**
* @author Andres Almiray
* @since 0.3.0
*/
public class Gav {
public static final String GROUP_ID = "groupId";
public static final String ARTIFACT_ID = "artifactId";
public static final String VERSION = "version";

private final String groupId;
private final String artifactId;
private final String version;
private final String classifier;

public Gav(String gav) {
String[] parts = gav.split(":");
if (parts.length == 4) {
this.groupId = parts[0].trim().replace(".", "/");
this.artifactId = parts[1].trim();
this.version = parts[2].trim();
this.classifier = parts[3].trim();
} else if (parts.length == 3) {
this.groupId = parts[0].trim().replace(".", "/");
this.artifactId = parts[1].trim();
this.version = parts[2].trim();
this.classifier = null;
} else {
throw new JarvizException(RB.$("ERROR_INVALID_GAV", gav));
}
}

public Gav(Properties props) {
this.groupId = props.getProperty(GROUP_ID);
this.artifactId = props.getProperty(ARTIFACT_ID);
this.version = props.getProperty(VERSION);
this.classifier = null;
}

public String getGroupId() {
return groupId;
}

public String getArtifactId() {
return artifactId;
}

public String getVersion() {
return version;
}

public String getClassifier() {
return classifier;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Gav gav = (Gav) o;
return groupId.equals(gav.groupId) &&
artifactId.equals(gav.artifactId) &&
version.equals(gav.version) &&
Objects.equals(classifier, gav.classifier);
}

@Override
public int hashCode() {
return Objects.hash(groupId, artifactId, version, classifier);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2022-2023 The Jarviz authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kordamp.jarviz.core.model;

/**
* @author Andres Almiray
* @since 0.3.0
*/
public interface GavAware {
Gav getGav();
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import org.kordamp.jarviz.bundle.RB;
import org.kordamp.jarviz.core.JarvizException;
import org.kordamp.jarviz.core.model.Checksum;
import org.kordamp.jarviz.core.model.Gav;
import org.kordamp.jarviz.core.model.GavAware;
import org.kordamp.jarviz.core.resolvers.JarFileResolver;
import org.kordamp.jarviz.util.Algorithm;
import org.kordamp.jarviz.util.ChecksumUtils;
Expand All @@ -39,6 +41,8 @@
import java.util.TreeSet;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static java.util.stream.Collectors.toSet;
Expand All @@ -48,10 +52,9 @@
* @since 0.3.0
*/
public class ChecksumJarProcessor implements JarProcessor<Set<Checksum>> {
private static final Pattern CHECKSUM = Pattern.compile("^([a-fA-F0-9]+).*$");

private static final String MAVEN_METADATA = "META-INF/maven/";
private static final String ARTIFACT_ID = "artifactId";
private static final String VERSION = "version";
private static final String GROUP_ID = "groupId";
private final JarFileResolver jarFileResolver;

public ChecksumJarProcessor(JarFileResolver jarFileResolver) {
Expand All @@ -66,11 +69,15 @@ public Set<JarFileResult<Set<Checksum>>> getResult() throws JarvizException {

for (JarFile jarFile : jarFiles) {
try (jarFile) {
Set<JarEntry> candidates = jarFile.stream()
.filter(entry -> entry.getName().endsWith(".properties") && entry.getName().startsWith(MAVEN_METADATA))
.collect(toSet());

findGAV(jarFile, candidates).ifPresent(props -> checksum(jarFile, props, set));
if (jarFile instanceof GavAware) {
checksum(jarFile, ((GavAware) jarFile).getGav(), set);
} else {
Set<JarEntry> candidates = jarFile.stream()
.filter(entry -> entry.getName().endsWith(".properties") && entry.getName().startsWith(MAVEN_METADATA))
.collect(toSet());

findGav(jarFile, candidates).ifPresent(gav -> checksum(jarFile, gav, set));
}
} catch (IOException e) {
throw new JarvizException(RB.$("ERROR_OPENING_JAR", jarFile.getName()));
}
Expand All @@ -79,18 +86,18 @@ public Set<JarFileResult<Set<Checksum>>> getResult() throws JarvizException {
return set;
}

private Optional<Properties> findGAV(JarFile jarFile, Set<JarEntry> candidates) {
private Optional<Gav> findGav(JarFile jarFile, Set<JarEntry> candidates) {
String fileName = Path.of(jarFile.getName()).getFileName().toString();
fileName = fileName.substring(0, fileName.length() - 4);

for (JarEntry candidate : candidates) {
try (InputStream in = jarFile.getInputStream(candidate)) {
Properties props = new Properties();
props.load(in);
String artifactId = props.getProperty(ARTIFACT_ID);
String version = props.getProperty(VERSION);
String artifactId = props.getProperty(Gav.ARTIFACT_ID);
String version = props.getProperty(Gav.VERSION);
if (fileName.startsWith(artifactId + "-" + version)) {
return Optional.of(props);
return Optional.of(new Gav(props));
}
} catch (IOException e) {
throw new JarvizException(RB.$("ERROR_OPENING_JAR", jarFile.getName()));
Expand All @@ -100,10 +107,10 @@ private Optional<Properties> findGAV(JarFile jarFile, Set<JarEntry> candidates)
return Optional.empty();
}

private void checksum(JarFile jarFile, Properties props, Set<JarFileResult<Set<Checksum>>> set) {
String groupId = props.getProperty(GROUP_ID).replace(".", "/");
String artifactId = props.getProperty(ARTIFACT_ID);
String version = props.getProperty(VERSION);
private void checksum(JarFile jarFile, Gav gav, Set<JarFileResult<Set<Checksum>>> set) {
String groupId = gav.getGroupId().replace(".", "/");
String artifactId = gav.getArtifactId();
String version = gav.getVersion();

String filename = artifactId + "-" + version + ".jar";
String baseUrl = "https://repo1.maven.org/maven2/" + groupId + "/" + artifactId + "/" + version + "/" + filename;
Expand Down Expand Up @@ -145,11 +152,21 @@ private Checksum check(JarFile jarFile, Algorithm algorithm, String baseUrl) {

try {
String localChecksum = ChecksumUtils.checksum(algorithm, localJar);
String remoteChecksum = new String(Files.readAllBytes(remoteJar));
String remoteChecksum = sanitize(new String(Files.readAllBytes(remoteJar)).trim());

return localChecksum.equals(remoteChecksum) ? Checksum.success(algorithm) : Checksum.failure(algorithm);
} catch (IOException e) {
throw new JarvizException(RB.$("ERROR_UNEXPECTED"), e);
}
}

private String sanitize(String input) {
// some checksums available ay Maven Central have this format
// 28e7eb9eeefe31a657c68755bfccc541 -
Matcher matcher = CHECKSUM.matcher(input);
if (matcher.matches()) {
return matcher.group(1);
}
return "";
}
}
Loading

0 comments on commit 015bb87

Please sign in to comment.