diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/artifact/ArtifactFactory.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/artifact/ArtifactFactory.java deleted file mode 100644 index b6fbc65..0000000 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/artifact/ArtifactFactory.java +++ /dev/null @@ -1,55 +0,0 @@ -package me.bristermitten.pdmlibs.artifact; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Set; -import java.util.regex.Pattern; - -import static java.util.stream.Collectors.toSet; - -public class ArtifactFactory -{ - - private static final String SNAPSHOT_SUFFIX = "-SNAPSHOT"; - private static final Pattern DESCRIPTOR_SEPARATOR = Pattern.compile(":"); - - @NotNull - public Artifact toArtifact(@NotNull final String artifactDescriptor) - { - final String[] parts = DESCRIPTOR_SEPARATOR.split(artifactDescriptor); - final String group = parts[0]; - final String artifact = parts[1]; - final String version = parts[2]; - - return toArtifact(group, artifact, version, null, null); - } - - @NotNull - public Artifact toArtifact(@NotNull final ArtifactDTO dto) - { - Set transitive = null; - if (dto.getTransitive() != null) - { - transitive = dto.getTransitive().stream().map(this::toArtifact).collect(toSet()); - } - - return toArtifact(dto.getGroupId(), dto.getArtifactId(), dto.getVersion(), dto.getRepositoryAlias(), transitive); - } - - @NotNull - public Artifact toArtifact(@NotNull final String group, - @NotNull final String artifact, - @NotNull final String version, - @Nullable final String repoAlias, - @Nullable final Set transitive) - { - - if (version.endsWith(SNAPSHOT_SUFFIX)) - { - return new SnapshotArtifact(group, artifact, version, repoAlias, transitive); - } - - return new ReleaseArtifact(group, artifact, version, repoAlias, transitive); - } -} diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/artifact/ReleaseArtifact.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/artifact/ReleaseArtifact.java deleted file mode 100644 index 5746612..0000000 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/artifact/ReleaseArtifact.java +++ /dev/null @@ -1,39 +0,0 @@ -package me.bristermitten.pdmlibs.artifact; - -import me.bristermitten.pdmlibs.http.HTTPService; -import me.bristermitten.pdmlibs.util.URLs; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.net.URL; -import java.util.Set; - -public class ReleaseArtifact extends Artifact -{ - - - public ReleaseArtifact(@NotNull String groupId, @NotNull String artifactId, @NotNull String version) - { - super(groupId, artifactId, version, null, null); - } - - public ReleaseArtifact(@NotNull String groupId, @NotNull String artifactId, @NotNull String version, @Nullable String repoBaseURL, @Nullable Set transitive) - { - super(groupId, artifactId, version, transitive, repoBaseURL); - } - - @Override - @Nullable - public URL getJarURL(@NotNull String baseRepoURL, @NotNull HTTPService service) - { - return URLs.parseURL(createBaseURL(baseRepoURL) + getArtifactId() + "-" + getVersion() + ".jar"); - } - - @Override - @Nullable - public URL getPomURL(@NotNull String baseRepoURL, @NotNull HTTPService service) - { - return URLs.parseURL(createBaseURL(baseRepoURL) + getArtifactId() + "-" + getVersion() + ".pom"); - } - -} diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/config/CacheConfiguration.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/config/CacheConfiguration.java index de0182b..2af0332 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/config/CacheConfiguration.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/config/CacheConfiguration.java @@ -10,7 +10,8 @@ public final class CacheConfiguration private final boolean cacheParsedPoms; private final boolean cacheOtherData; - public CacheConfiguration(boolean cachePoms, boolean cacheJars, boolean cacheParsedPoms, boolean cacheOtherData) + private CacheConfiguration(final boolean cachePoms, final boolean cacheJars, + final boolean cacheParsedPoms, final boolean cacheOtherData) { this.cachePoms = cachePoms; this.cacheJars = cacheJars; @@ -18,11 +19,18 @@ public CacheConfiguration(boolean cachePoms, boolean cacheJars, boolean cachePar this.cacheOtherData = cacheOtherData; } - public static @NotNull Builder builder() + @NotNull + public static Builder builder() { return new Builder(); } + @NotNull + public static CacheConfiguration of(final boolean cachePoms, final boolean cacheJars, + final boolean cacheParsedPoms, final boolean cacheOtherData) { + return new CacheConfiguration(cachePoms, cacheJars, cacheParsedPoms, cacheOtherData); + } + public boolean cachePoms() { return cachePoms; @@ -51,31 +59,36 @@ public static class Builder private boolean cacheParsedPoms = true; private boolean cacheOtherData = true; - public @NotNull Builder disablePomCaching() + @NotNull + public Builder disablePomCaching() { cachePoms = false; return this; } - public @NotNull Builder disableJarCaching() + @NotNull + public Builder disableJarCaching() { cacheJars = false; return this; } - public @NotNull Builder disableParsedPomCaching() + @NotNull + public Builder disableParsedPomCaching() { cacheParsedPoms = false; return this; } - public @NotNull Builder disableOtherDataCaching() + @NotNull + public Builder disableOtherDataCaching() { cacheOtherData = false; return this; } - public @NotNull CacheConfiguration build() + @NotNull + public CacheConfiguration build() { return new CacheConfiguration(cachePoms, cacheJars, cacheParsedPoms, cacheOtherData); } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/artifact/Artifact.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/dependency/Dependency.java similarity index 69% rename from common-lib/src/main/java/me/bristermitten/pdmlibs/artifact/Artifact.java rename to common-lib/src/main/java/me/bristermitten/pdmlibs/dependency/Dependency.java index c820b5b..8829bf1 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/artifact/Artifact.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/dependency/Dependency.java @@ -1,13 +1,14 @@ -package me.bristermitten.pdmlibs.artifact; +package me.bristermitten.pdmlibs.dependency; import me.bristermitten.pdmlibs.http.HTTPService; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.net.URL; +import java.util.Map; import java.util.Set; -public abstract class Artifact +public abstract class Dependency { private static final String JAR_NAME_FORMAT = "%s-%s.jar"; @@ -21,15 +22,20 @@ public abstract class Artifact @Nullable private final String repoAlias; @Nullable - private Set transitiveDependencies; + private Set transitiveDependencies; + @Nullable + private Map relocations; - protected Artifact(@NotNull String groupId, @NotNull String artifactId, @NotNull String version, @Nullable Set transitiveDependencies, @Nullable String repoAlias) + protected Dependency(@NotNull final String groupId, @NotNull final String artifactId, + @NotNull final String version, @Nullable final Set transitiveDependencies, + @Nullable final String repoAlias, @Nullable final Map relocations) { this.groupId = groupId; this.artifactId = artifactId; this.version = version; this.transitiveDependencies = transitiveDependencies; this.repoAlias = repoAlias; + this.relocations = relocations; } @Nullable @@ -63,28 +69,34 @@ public String getVersion() } /** - * Get the transitive dependencies of this artifact. + * Get the transitive dependencies of this dependency. *

* There are semantics attached to the returned value: * {@code null} implies that the transitive dependencies have not been looked up, and so should be located by the runtime. - * An empty set implies that the transitive dependencies have been looked up and are empty. That is, the artifact has no transitive dependencies. + * An empty set implies that the transitive dependencies have been looked up and are empty. That is, the dependency has no transitive dependencies. * A set with elements will have those elements downloaded, without querying the transitive dependencies again. * - * @return the transitive dependencies of this artifact. + * @return the transitive dependencies of this dependency. */ @Nullable - public Set getTransitiveDependencies() + public Set getTransitiveDependencies() { return transitiveDependencies; } - public void setTransitiveDependencies(@Nullable Set transitiveDependencies) + @Nullable + public Map getRelocations() { + return relocations; + } + + public void setTransitiveDependencies(@Nullable final Set transitiveDependencies) { this.transitiveDependencies = transitiveDependencies; } + @NotNull @Override - public @NotNull String toString() + public String toString() { return "Artifact{" + "groupId='" + groupId + '\'' + @@ -101,7 +113,7 @@ protected final String createBaseURL(@NotNull final String repoURL) } @NotNull - private String addSlashIfNecessary(@NotNull final String concatTo) + private static String addSlashIfNecessary(@NotNull final String concatTo) { if (concatTo.endsWith("/")) { @@ -120,6 +132,7 @@ public final String toArtifactURL() ); } + @NotNull public String getJarName() { return String.format(JAR_NAME_FORMAT, artifactId, version); diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/artifact/ArtifactDTO.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/dependency/DependencyDTO.java similarity index 59% rename from common-lib/src/main/java/me/bristermitten/pdmlibs/artifact/ArtifactDTO.java rename to common-lib/src/main/java/me/bristermitten/pdmlibs/dependency/DependencyDTO.java index ccdd428..50e793e 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/artifact/ArtifactDTO.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/dependency/DependencyDTO.java @@ -1,12 +1,13 @@ -package me.bristermitten.pdmlibs.artifact; +package me.bristermitten.pdmlibs.dependency; import com.google.gson.annotations.SerializedName; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Map; import java.util.Set; -public class ArtifactDTO +public class DependencyDTO { @NotNull @@ -21,15 +22,21 @@ public class ArtifactDTO private final String repositoryAlias; @Nullable - private final Set transitive; + private final Set transitive; - public ArtifactDTO(@NotNull String groupId, @NotNull String artifactId, @NotNull String version, @Nullable String sourceRepository, @Nullable Set transitive) + @Nullable + private final Map relocations; + + public DependencyDTO(@NotNull final String groupId, @NotNull final String artifactId, + @NotNull final String version, @Nullable final String sourceRepository, + @Nullable final Set transitive, @Nullable final Map relocations) { this.groupId = groupId; this.artifactId = artifactId; this.version = version; this.repositoryAlias = sourceRepository; this.transitive = transitive; + this.relocations = relocations; } @NotNull @@ -57,8 +64,13 @@ public String getRepositoryAlias() } @Nullable - public Set getTransitive() + public Set getTransitive() { return transitive; } + + @Nullable + public Map getRelocations() { + return relocations; + } } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/dependency/DependencyFactory.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/dependency/DependencyFactory.java new file mode 100644 index 0000000..4f63691 --- /dev/null +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/dependency/DependencyFactory.java @@ -0,0 +1,53 @@ +package me.bristermitten.pdmlibs.dependency; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +import static java.util.stream.Collectors.toSet; + +public class DependencyFactory +{ + + private static final String SNAPSHOT_SUFFIX = "-SNAPSHOT"; + private static final Pattern DESCRIPTOR_SEPARATOR = Pattern.compile(":"); + + @NotNull + public Dependency toArtifact(@NotNull final String artifactDescriptor) + { + final String[] parts = DESCRIPTOR_SEPARATOR.split(artifactDescriptor); + final String group = parts[0]; + final String artifact = parts[1]; + final String version = parts[2]; + + return toArtifact(group, artifact, version, null, null, null); + } + + @NotNull + public Dependency toArtifact(@NotNull final DependencyDTO dto) + { + Set transitive = null; + if (dto.getTransitive() != null) + { + transitive = dto.getTransitive().stream().map(this::toArtifact).collect(toSet()); + } + + return toArtifact(dto.getGroupId(), dto.getArtifactId(), dto.getVersion(), dto.getRepositoryAlias(), transitive, dto.getRelocations()); + } + + @NotNull + public Dependency toArtifact(@NotNull final String group, @NotNull final String artifact, + @NotNull final String version, @Nullable final String repoAlias, + @Nullable final Set transitive, @Nullable final Map relocations) + { + if (version.endsWith(SNAPSHOT_SUFFIX)) + { + return new SnapshotDependency(group, artifact, version, repoAlias, transitive, relocations); + } + + return new ReleaseDependency(group, artifact, version, repoAlias, transitive, relocations); + } +} diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/dependency/ReleaseDependency.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/dependency/ReleaseDependency.java new file mode 100644 index 0000000..6fa1712 --- /dev/null +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/dependency/ReleaseDependency.java @@ -0,0 +1,41 @@ +package me.bristermitten.pdmlibs.dependency; + +import me.bristermitten.pdmlibs.http.HTTPService; +import me.bristermitten.pdmlibs.util.URLs; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.net.URL; +import java.util.Map; +import java.util.Set; + +public class ReleaseDependency extends Dependency +{ + + public ReleaseDependency(@NotNull final String groupId, @NotNull final String artifactId, + @NotNull final String version) + { + super(groupId, artifactId, version, null, null, null); + } + + public ReleaseDependency(@NotNull final String groupId, @NotNull final String artifactId, + @NotNull final String version, @Nullable final String repoBaseURL, + @Nullable final Set transitive, @Nullable final Map relocations) + { + super(groupId, artifactId, version, transitive, repoBaseURL, relocations); + } + + @Nullable + @Override + public URL getJarURL(@NotNull final String baseRepoURL, @NotNull final HTTPService service) + { + return URLs.parseURL(createBaseURL(baseRepoURL) + getArtifactId() + "-" + getVersion() + ".jar"); + } + + @Nullable + @Override + public URL getPomURL(@NotNull final String baseRepoURL, @NotNull final HTTPService service) + { + return URLs.parseURL(createBaseURL(baseRepoURL) + getArtifactId() + "-" + getVersion() + ".pom"); + } +} diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/artifact/SnapshotArtifact.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/dependency/SnapshotDependency.java similarity index 74% rename from common-lib/src/main/java/me/bristermitten/pdmlibs/artifact/SnapshotArtifact.java rename to common-lib/src/main/java/me/bristermitten/pdmlibs/dependency/SnapshotDependency.java index e690644..4b18395 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/artifact/SnapshotArtifact.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/dependency/SnapshotDependency.java @@ -1,4 +1,4 @@ -package me.bristermitten.pdmlibs.artifact; +package me.bristermitten.pdmlibs.dependency; import me.bristermitten.pdmlibs.http.HTTPService; import me.bristermitten.pdmlibs.pom.PomParser; @@ -8,26 +8,31 @@ import org.jetbrains.annotations.Nullable; import java.net.URL; +import java.util.Map; import java.util.Set; -public class SnapshotArtifact extends Artifact +public class SnapshotDependency extends Dependency { - public SnapshotArtifact(@NotNull String groupId, @NotNull String artifactId, @NotNull String version) + public SnapshotDependency(@NotNull final String groupId, @NotNull final String artifactId, + @NotNull final String version) { - super(groupId, artifactId, version, null, null); + super(groupId, artifactId, version, null, null, null); } - public SnapshotArtifact(@NotNull String groupId, @NotNull String artifactId, @NotNull String version, @Nullable String repoBaseURL, @Nullable Set transitive) + public SnapshotDependency(@NotNull final String groupId, @NotNull final String artifactId, + @NotNull final String version, @Nullable final String repoBaseURL, + @Nullable final Set transitive, @Nullable final Map relocations) { - super(groupId, artifactId, version, transitive, repoBaseURL); + super(groupId, artifactId, version, transitive, repoBaseURL, relocations); } - @Override @Nullable + @Override public URL getJarURL(@NotNull final String baseRepoURL, @NotNull final HTTPService httpService) { final String latestSnapshotVersion = getLatestVersion(baseRepoURL, httpService); + if (latestSnapshotVersion == null) { return null; @@ -40,6 +45,7 @@ public URL getJarURL(@NotNull final String baseRepoURL, @NotNull final HTTPServi public @Nullable URL getPomURL(@NotNull final String baseRepoURL, @NotNull final HTTPService httpService) { final String latestSnapshotVersion = getLatestVersion(baseRepoURL, httpService); + if (latestSnapshotVersion == null) { return null; @@ -52,16 +58,19 @@ public URL getJarURL(@NotNull final String baseRepoURL, @NotNull final HTTPServi private String getLatestVersion(@NotNull String baseURL, @NotNull HTTPService httpService) { final URL metadataURL = URLs.parseURL(createBaseURL(baseURL) + "maven-metadata.xml"); + if (metadataURL == null) { return null; } + if (!httpService.ping(metadataURL)) { return null; //Don't even attempt to parse if the request will fail } - PomParser pomParser = new PomParser(); + final PomParser pomParser = new PomParser(); + try { return pomParser.parse(new GetLatestSnapshotVersionParseProcess(), httpService.readFrom(metadataURL)); diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/http/HTTPCache.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/http/HTTPCache.java index 2974e7e..566b343 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/http/HTTPCache.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/http/HTTPCache.java @@ -14,7 +14,7 @@ public class HTTPCache { private final String userAgent; - private final @NotNull LoadingCache urlCache; + @NotNull private final LoadingCache urlCache; public HTTPCache(String userAgent) { @@ -25,7 +25,7 @@ public HTTPCache(String userAgent) @NotNull - public byte[] fetch(@NotNull final URL url) + public byte @NotNull [] fetch(@NotNull final URL url) { return urlCache.getUnchecked(url); } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/http/HTTPService.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/http/HTTPService.java index bbf146d..6e196ff 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/http/HTTPService.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/http/HTTPService.java @@ -1,7 +1,7 @@ package me.bristermitten.pdmlibs.http; -import me.bristermitten.pdmlibs.artifact.Artifact; import me.bristermitten.pdmlibs.config.CacheConfiguration; +import me.bristermitten.pdmlibs.dependency.Dependency; import me.bristermitten.pdmlibs.util.Streams; import me.bristermitten.pdmlibs.util.URLs; import org.jetbrains.annotations.NotNull; @@ -16,10 +16,11 @@ public class HTTPService private static final String USER_AGENT_FORMAT = "PDM/%s; Plugin:%s"; private final String userAgent; - private final @NotNull HTTPCache cache; + @NotNull private final HTTPCache cache; private final CacheConfiguration cacheConfiguration; - public HTTPService(@NotNull final String managing, @NotNull final String version, CacheConfiguration cacheConfiguration) + public HTTPService(@NotNull final String managing, @NotNull final String version, + @NotNull final CacheConfiguration cacheConfiguration) { this.cacheConfiguration = cacheConfiguration; this.userAgent = String.format(USER_AGENT_FORMAT, version, managing); @@ -52,24 +53,28 @@ public boolean ping(@NotNull final URL url) } @NotNull - public InputStream readJar(@NotNull final String repoURL, @NotNull final Artifact artifact) + public InputStream readJar(@NotNull final String repoURL, @NotNull final Dependency dependency) { - URL jarURL = artifact.getJarURL(repoURL, this); + final URL jarURL = dependency.getJarURL(repoURL, this); + if (jarURL == null) { return new ByteArrayInputStream(new byte[0]); } + return readFrom(jarURL, URLType.JAR); } @NotNull - public InputStream readPom(@NotNull final String repoURL, @NotNull final Artifact artifact) + public InputStream readPom(@NotNull final String repoURL, @NotNull final Dependency dependency) { - URL pomURL = artifact.getPomURL(repoURL, this); + final URL pomURL = dependency.getPomURL(repoURL, this); + if (pomURL == null) { return Streams.createEmptyStream(); } + return readFrom(pomURL, URLType.POM); } } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/http/URLType.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/http/URLType.java index 5982998..4f8a187 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/http/URLType.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/http/URLType.java @@ -7,13 +7,14 @@ public enum URLType { + JAR(CacheConfiguration::cacheJars), POM(CacheConfiguration::cachePoms), OTHER(CacheConfiguration::cacheOtherData); private final Predicate allowedCheck; - URLType(Predicate allowedCheck) + URLType(@NotNull final Predicate allowedCheck) { this.allowedCheck = allowedCheck; } @@ -22,5 +23,4 @@ public boolean canBeCached(@NotNull final CacheConfiguration configuration) { return allowedCheck.test(configuration); } - } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/DefaultParseProcess.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/DefaultParseProcess.java index 87269fd..dfda26f 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/DefaultParseProcess.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/DefaultParseProcess.java @@ -1,7 +1,7 @@ package me.bristermitten.pdmlibs.pom; -import me.bristermitten.pdmlibs.artifact.Artifact; -import me.bristermitten.pdmlibs.artifact.ArtifactFactory; +import me.bristermitten.pdmlibs.dependency.Dependency; +import me.bristermitten.pdmlibs.dependency.DependencyFactory; import me.bristermitten.pdmlibs.http.HTTPService; import me.bristermitten.pdmlibs.repository.RepositoryManager; import org.jetbrains.annotations.NotNull; @@ -14,41 +14,40 @@ /** * @author AlexL */ -public class DefaultParseProcess implements ParseProcess> +public class DefaultParseProcess implements ParseProcess> { @NotNull - private final ArtifactFactory artifactFactory; + private final DependencyFactory dependencyFactory; - private final @NotNull ExtractParentsParseStage extractParentsParseStage; + @NotNull + private final ExtractParentsParseStage extractParentsParseStage; - public DefaultParseProcess(@NotNull final ArtifactFactory artifactFactory, - @NotNull final RepositoryManager repositoryManager, + public DefaultParseProcess(@NotNull final DependencyFactory dependencyFactory, @NotNull final RepositoryManager repositoryManager, @NotNull final HTTPService httpService) { - this.artifactFactory = artifactFactory; - extractParentsParseStage = new ExtractParentsParseStage(artifactFactory, repositoryManager, httpService); + this.dependencyFactory = dependencyFactory; + extractParentsParseStage = new ExtractParentsParseStage(dependencyFactory, repositoryManager, httpService); } @NotNull @Override - public Set parse(@NotNull Document document) + public Set parse(@NotNull Document document) { final List parents = extractParentsParseStage.parse(document); - MavenPlaceholderReplacer placeholderReplacer = new MavenPlaceholderReplacer(Collections.emptyMap()); + final MavenPlaceholderReplacer placeholderReplacer = new MavenPlaceholderReplacer(Collections.emptyMap()); final ExtractPropertiesParseStage propertiesParseStage = new ExtractPropertiesParseStage(placeholderReplacer); Collections.reverse(parents); - for (Document parent : parents) + + for (final Document parent : parents) { placeholderReplacer.addAllFrom(propertiesParseStage.parse(parent)); } final MavenPlaceholderReplacer placeholders = propertiesParseStage.parse(document); - - final ParseStage> dependenciesParseStage = new ExtractDependenciesParseStage(this.artifactFactory, placeholders); + final ParseStage> dependenciesParseStage = new ExtractDependenciesParseStage(this.dependencyFactory, placeholders); return dependenciesParseStage.parse(document); } - } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/DependencyNotationExtractor.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/DependencyNotationExtractor.java index 3a7975a..ea8cab9 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/DependencyNotationExtractor.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/DependencyNotationExtractor.java @@ -1,6 +1,6 @@ package me.bristermitten.pdmlibs.pom; -import me.bristermitten.pdmlibs.artifact.ArtifactDTO; +import me.bristermitten.pdmlibs.dependency.DependencyDTO; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.w3c.dom.Element; @@ -15,12 +15,13 @@ private DependencyNotationExtractor() } @Nullable - public static ArtifactDTO extractFrom(@NotNull final Element element) + public static DependencyDTO extractFrom(@NotNull final Element element) { final String groupId = element.getElementsByTagName("groupId").item(0).getTextContent(); final String artifactId = element.getElementsByTagName("artifactId").item(0).getTextContent(); final NodeList versionNodeList = element.getElementsByTagName("version"); + if (versionNodeList == null || versionNodeList.getLength() == 0) { return null; @@ -28,6 +29,6 @@ public static ArtifactDTO extractFrom(@NotNull final Element element) final String version = versionNodeList.item(0).getTextContent(); - return new ArtifactDTO(groupId, artifactId, version, null, null); + return new DependencyDTO(groupId, artifactId, version, null, null, null); } } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ExtractDependenciesParseStage.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ExtractDependenciesParseStage.java index 4389105..22bb228 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ExtractDependenciesParseStage.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ExtractDependenciesParseStage.java @@ -1,8 +1,9 @@ package me.bristermitten.pdmlibs.pom; -import me.bristermitten.pdmlibs.artifact.Artifact; -import me.bristermitten.pdmlibs.artifact.ArtifactDTO; -import me.bristermitten.pdmlibs.artifact.ArtifactFactory; +import com.google.common.collect.Sets; +import me.bristermitten.pdmlibs.dependency.Dependency; +import me.bristermitten.pdmlibs.dependency.DependencyDTO; +import me.bristermitten.pdmlibs.dependency.DependencyFactory; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.w3c.dom.Document; @@ -10,25 +11,23 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import java.util.Arrays; -import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; /** * @author AlexL */ -public class ExtractDependenciesParseStage implements ParseStage> +public class ExtractDependenciesParseStage implements ParseStage> { - private static final Set DEFAULT_SCOPES_TO_DROP = new HashSet<>(Arrays.asList( + private static final Set DEFAULT_SCOPES_TO_DROP = Sets.newHashSet( "test", "provided", "system" - )); + ); @NotNull - private final ArtifactFactory artifactFactory; + private final DependencyFactory dependencyFactory; @NotNull private final Set ignoredScopes; @@ -36,45 +35,47 @@ public class ExtractDependenciesParseStage implements ParseStage> @NotNull private final MavenPlaceholderReplacer placeholderReplacer; - public ExtractDependenciesParseStage(@NotNull final ArtifactFactory artifactFactory, @NotNull final MavenPlaceholderReplacer placeholders) + public ExtractDependenciesParseStage(@NotNull final DependencyFactory dependencyFactory, @NotNull final MavenPlaceholderReplacer placeholders) { - this(artifactFactory, DEFAULT_SCOPES_TO_DROP, placeholders); + this(dependencyFactory, DEFAULT_SCOPES_TO_DROP, placeholders); } - public ExtractDependenciesParseStage(@NotNull final ArtifactFactory artifactFactory, - @NotNull final Set ignoredScopes, + public ExtractDependenciesParseStage(@NotNull final DependencyFactory dependencyFactory, @NotNull final Set ignoredScopes, @NotNull final MavenPlaceholderReplacer placeholders) { - this.artifactFactory = artifactFactory; + this.dependencyFactory = dependencyFactory; this.ignoredScopes = ignoredScopes; this.placeholderReplacer = placeholders; } @NotNull @Override - public Set parse(@NotNull Document document) + public Set parse(@NotNull final Document document) { - final Set dependencySet = new LinkedHashSet<>(); - - NodeList dependenciesNodeList = document.getElementsByTagName("dependencies"); - Element dependenciesElement = (Element) dependenciesNodeList.item(0); + final Set dependencySet = new LinkedHashSet<>(); + final NodeList dependenciesNodeList = document.getElementsByTagName("dependencies"); + final Element dependenciesElement = (Element) dependenciesNodeList.item(0); if (dependenciesElement == null) { return dependencySet; } - NodeList dependencies = dependenciesElement.getElementsByTagName("dependency"); + + final NodeList dependencies = dependenciesElement.getElementsByTagName("dependency"); + if (dependencies == null) { return dependencySet; } + for (int temp = 0; temp < dependencies.getLength(); temp++) { - Node node = dependencies.item(temp); + final Node node = dependencies.item(temp); if (node instanceof Element) { - Artifact parsed = getDependencyFromXML((Element) node); + final Dependency parsed = getDependencyFromXML((Element) node); + if (parsed != null) { dependencySet.add(parsed); @@ -85,22 +86,25 @@ public Set parse(@NotNull Document document) return dependencySet; } - public @Nullable Artifact getDependencyFromXML(@NotNull Element dependencyElement) + @Nullable + public Dependency getDependencyFromXML(@NotNull final Element dependencyElement) { - final ArtifactDTO artifactDTO = DependencyNotationExtractor.extractFrom(dependencyElement); - if (artifactDTO == null) + final DependencyDTO dependencyDTO = DependencyNotationExtractor.extractFrom(dependencyElement); + + if (dependencyDTO == null) { return null; } - final String groupId = placeholderReplacer.replace(artifactDTO.getGroupId()); - final String artifactId = placeholderReplacer.replace(artifactDTO.getArtifactId()); - final String version = placeholderReplacer.replace(artifactDTO.getVersion()); - + final String groupId = placeholderReplacer.replace(dependencyDTO.getGroupId()); + final String artifactId = placeholderReplacer.replace(dependencyDTO.getArtifactId()); + final String version = placeholderReplacer.replace(dependencyDTO.getVersion()); final NodeList scopeList = dependencyElement.getElementsByTagName("scope"); + if (scopeList != null && scopeList.getLength() > 0) { - String scope = scopeList.item(0).getTextContent(); + final String scope = scopeList.item(0).getTextContent(); + if (ignoredScopes.contains(scope)) { return null; @@ -111,16 +115,18 @@ public Set parse(@NotNull Document document) * TODO currently we're just skipping optional dependencies. * In the future we should look into having them loaded or not based on if they are actually needed */ - Node optional = dependencyElement.getElementsByTagName("optional").item(0); + final Node optional = dependencyElement.getElementsByTagName("optional").item(0); + if (optional instanceof Element) { - String isOptional = optional.getTextContent(); + final String isOptional = optional.getTextContent(); + if (isOptional.equals("true")) { return null; } } - return artifactFactory.toArtifact(groupId, artifactId, version, null, null); + return dependencyFactory.toArtifact(groupId, artifactId, version, null, null, null); } } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ExtractParentsParseStage.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ExtractParentsParseStage.java index 20f1f26..cad3e94 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ExtractParentsParseStage.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ExtractParentsParseStage.java @@ -1,8 +1,8 @@ package me.bristermitten.pdmlibs.pom; -import me.bristermitten.pdmlibs.artifact.Artifact; -import me.bristermitten.pdmlibs.artifact.ArtifactDTO; -import me.bristermitten.pdmlibs.artifact.ArtifactFactory; +import me.bristermitten.pdmlibs.dependency.Dependency; +import me.bristermitten.pdmlibs.dependency.DependencyDTO; +import me.bristermitten.pdmlibs.dependency.DependencyFactory; import me.bristermitten.pdmlibs.http.HTTPService; import me.bristermitten.pdmlibs.repository.Repository; import me.bristermitten.pdmlibs.repository.RepositoryManager; @@ -20,22 +20,21 @@ public class ExtractParentsParseStage implements ParseStage<@NotNull List>, ParseProcess<@NotNull List> { - - private final ArtifactFactory artifactFactory; - + private final DependencyFactory dependencyFactory; private final RepositoryManager repositoryManager; private final HTTPService httpService; - public ExtractParentsParseStage(ArtifactFactory artifactFactory, RepositoryManager repositoryManager, HTTPService httpService) + public ExtractParentsParseStage(@NotNull final DependencyFactory dependencyFactory, @NotNull final RepositoryManager repositoryManager, + @NotNull final HTTPService httpService) { - this.artifactFactory = artifactFactory; + this.dependencyFactory = dependencyFactory; this.repositoryManager = repositoryManager; this.httpService = httpService; } @NotNull @Override - public List parse(@NotNull Document document) + public List parse(@NotNull final Document document) { final List parentTree = new LinkedList<>(); @@ -50,32 +49,33 @@ public List parse(@NotNull Document document) } @Nullable - private Document loadParent(@NotNull Document document) + private Document loadParent(@NotNull final Document document) { final Node parent = document.getElementsByTagName("parent").item(0); + if (!(parent instanceof Element)) { return null; } - final ArtifactDTO parentDTO = DependencyNotationExtractor.extractFrom((Element) parent); - final Artifact artifact = artifactFactory.toArtifact(parentDTO); + final DependencyDTO parentDTO = DependencyNotationExtractor.extractFrom((Element) parent); + final Dependency dependency = dependencyFactory.toArtifact(parentDTO); + final Repository containingRepo = repositoryManager.firstContaining(dependency); - final Repository containingRepo = repositoryManager.firstContaining(artifact); if (containingRepo == null) { //TODO log a warning? return null; } - try (final InputStream inputStream = httpService.readPom(containingRepo.getURL(), artifact)) + try (final InputStream inputStream = httpService.readPom(containingRepo.getURL(), dependency)) { return new PomParser().getDocument(inputStream); } - catch (IOException e) + catch (IOException exception) { - e.printStackTrace(); + exception.printStackTrace(); return null; } } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ExtractPropertiesParseStage.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ExtractPropertiesParseStage.java index 6c6b04f..a9fec1b 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ExtractPropertiesParseStage.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ExtractPropertiesParseStage.java @@ -14,7 +14,8 @@ public class ExtractPropertiesParseStage implements ParseStage { - private final @NotNull MavenPlaceholderReplacer replacer; + @NotNull + private final MavenPlaceholderReplacer replacer; public ExtractPropertiesParseStage() { @@ -29,10 +30,11 @@ public ExtractPropertiesParseStage(@NotNull final MavenPlaceholderReplacer repla @NotNull @Override - public MavenPlaceholderReplacer parse(@NotNull Document document) + public MavenPlaceholderReplacer parse(@NotNull final Document document) { //Default Placeholders final String groupId = document.getElementsByTagName("groupId").item(0).getTextContent(); + if (groupId != null) { replacer.addPlaceholder("project.groupId", groupId); @@ -42,6 +44,7 @@ public MavenPlaceholderReplacer parse(@NotNull Document document) } final String artifactId = document.getElementsByTagName("artifactId").item(0).getTextContent(); + if (artifactId != null) { replacer.addPlaceholder("project.artifactId", artifactId); @@ -51,6 +54,7 @@ public MavenPlaceholderReplacer parse(@NotNull Document document) } final String version = document.getElementsByTagName("version").item(0).getTextContent(); + if (version != null) { replacer.addPlaceholder("project.version", version); @@ -59,26 +63,30 @@ public MavenPlaceholderReplacer parse(@NotNull Document document) throw new IllegalArgumentException("No version"); } - NodeList propertiesElement = document.getElementsByTagName("properties"); + final NodeList propertiesElement = document.getElementsByTagName("properties"); + if (propertiesElement == null) { return replacer; } - Node firstProperties = propertiesElement.item(0); + final Node firstProperties = propertiesElement.item(0); + if (firstProperties == null) { return replacer; } - NodeList propertiesList = firstProperties.getChildNodes(); + final NodeList propertiesList = firstProperties.getChildNodes(); for (int i = 0; i < propertiesList.getLength(); i++) { - Node item = propertiesList.item(i); + final Node item = propertiesList.item(i); + if (item instanceof Element) { - Node child = item.getFirstChild(); + final Node child = item.getFirstChild(); + if (child == null) { continue; diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/MavenPlaceholderReplacer.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/MavenPlaceholderReplacer.java index a93efa5..00b26ea 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/MavenPlaceholderReplacer.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/MavenPlaceholderReplacer.java @@ -29,14 +29,15 @@ public MavenPlaceholderReplacer(@NotNull final Map placeholders) public void addPlaceholder(@NotNull final String placeholder, @NotNull String replacement) { - String format = Strings.escapeRegex(String.format(PATTERN_FORMAT, placeholder)); + final String format = Strings.escapeRegex(String.format(PATTERN_FORMAT, placeholder)); + final String replace = replace(replacement); - String replace = replace(replacement); if (replace.contains("$")) { LOGGER.fine(() -> replace + " is an invalid placeholder, it will be discarded."); return; } + this.placeholders.put(Pattern.compile(format).matcher(""), replace); } @@ -49,15 +50,18 @@ public void addAllFrom(@NotNull final MavenPlaceholderReplacer other) public String replace(@NotNull final String value) { String temp = value; + for (Map.Entry entry : placeholders.entrySet()) { - Matcher matcher = entry.getKey(); + final Matcher matcher = entry.getKey(); matcher.reset(temp); - String replacement = entry.getValue(); + final String replacement = entry.getValue(); + if (replacement == null) { continue; } + temp = matcher.replaceAll(replacement); } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ParseProcess.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ParseProcess.java index e1da01d..75020fd 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ParseProcess.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ParseProcess.java @@ -11,5 +11,6 @@ public interface ParseProcess { - @Nullable T parse(@NotNull final Document document); + @Nullable + T parse(@NotNull final Document document); } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ParseStage.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ParseStage.java index 8213a77..c2315e8 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ParseStage.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/ParseStage.java @@ -10,5 +10,6 @@ public interface ParseStage { - @Nullable T parse(@NotNull final Document document); + @Nullable + T parse(@NotNull final Document document); } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/PomParser.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/PomParser.java index 8293ab0..32fb011 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/PomParser.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/PomParser.java @@ -15,18 +15,17 @@ public class PomParser { - private static final DocumentBuilderFactory dbFactory; + private static final DocumentBuilderFactory DB_FACTORY; static { - dbFactory = DocumentBuilderFactory.newInstance(); - dbFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - dbFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); + DB_FACTORY = DocumentBuilderFactory.newInstance(); + DB_FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + DB_FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); } public @NotNull T parse(@NotNull final ParseProcess parseProcess, @NotNull final InputStream pomContent) { - final Document document = getDocument(pomContent); return Objects.requireNonNull(parseProcess.parse(document), "Parse Process " + parseProcess + " returned null!"); @@ -37,16 +36,16 @@ public Document getDocument(@NotNull final InputStream pomContent) { try { - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + final DocumentBuilder dBuilder = DB_FACTORY.newDocumentBuilder(); + final Document doc = dBuilder.parse(pomContent); - Document doc = dBuilder.parse(pomContent); doc.normalizeDocument(); return doc; } - catch (@NotNull ParserConfigurationException | SAXException | IOException e) + catch (ParserConfigurationException | SAXException | IOException exception) { - throw new IllegalArgumentException(e); + throw new IllegalArgumentException(exception); } } } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/snapshot/GetLatestSnapshotVersionParseProcess.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/snapshot/GetLatestSnapshotVersionParseProcess.java index f93f2b8..c76c365 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/snapshot/GetLatestSnapshotVersionParseProcess.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/snapshot/GetLatestSnapshotVersionParseProcess.java @@ -15,22 +15,24 @@ public class GetLatestSnapshotVersionParseProcess implements ParseProcess<@Nulla private final SnapshotVersionParseStage snapshotVersionParseStage = new SnapshotVersionParseStage(); private final JitpackLatestSnapshotParseStage jitpackLatestSnapshotParseStage = new JitpackLatestSnapshotParseStage(); - @NotNull + @Nullable @Override - public @Nullable String parse(@NotNull Document document) + public String parse(@NotNull Document document) { final String latest = latestElementParseStage.parse(document); + if (latest != null) { return latest; } final String latestSnapshotVersion = snapshotVersionParseStage.parse(document); + if (latestSnapshotVersion != null) { return latestSnapshotVersion; } - final String jitpackSnapshot = jitpackLatestSnapshotParseStage.parse(document); - return jitpackSnapshot; + + return jitpackLatestSnapshotParseStage.parse(document); } } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/snapshot/JitpackLatestSnapshotParseStage.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/snapshot/JitpackLatestSnapshotParseStage.java index a3f0296..384ceaf 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/snapshot/JitpackLatestSnapshotParseStage.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/snapshot/JitpackLatestSnapshotParseStage.java @@ -16,11 +16,12 @@ public class JitpackLatestSnapshotParseStage implements ParseStage<@Nullable Str private static final String JITPACK_JAR_NAME_FORMAT = "-%s-%s"; - @Override @Nullable + @Override public String parse(@NotNull Document document) { final Node versioning = document.getElementsByTagName("versioning").item(0); + if (!(versioning instanceof Element)) { return null; @@ -28,26 +29,27 @@ public String parse(@NotNull Document document) final Element versioningElement = (Element) versioning; final Node snapshot = versioningElement.getElementsByTagName("snapshot").item(0); + if (!(snapshot instanceof Element)) { return null; } final Element snapshotElement = (Element) snapshot; + final Node buildNumber = snapshotElement.getElementsByTagName("buildNumber").item(0); - Node buildNumber = snapshotElement.getElementsByTagName("buildNumber").item(0); if (buildNumber == null) { return null; } - Node timestamp = snapshotElement.getElementsByTagName("timestamp").item(0); + final Node timestamp = snapshotElement.getElementsByTagName("timestamp").item(0); + if (timestamp == null) { return null; } - return String.format(JITPACK_JAR_NAME_FORMAT, timestamp.getTextContent(), buildNumber.getTextContent()); } } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/snapshot/LatestElementParseStage.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/snapshot/LatestElementParseStage.java index 0c0169c..c217c98 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/snapshot/LatestElementParseStage.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/snapshot/LatestElementParseStage.java @@ -13,11 +13,12 @@ public class LatestElementParseStage implements ParseStage<@Nullable String> { - @Override @Nullable - public String parse(@NotNull Document document) + @Override + public String parse(@NotNull final Document document) { final Node versioning = document.getElementsByTagName("versioning").item(0); + if (!(versioning instanceof Element)) { return null; @@ -25,6 +26,7 @@ public String parse(@NotNull Document document) final Element versioningElement = (Element) versioning; final Node latestElement = versioningElement.getElementsByTagName("latest").item(0); + if (!(latestElement instanceof Element)) { return null; diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/snapshot/SnapshotVersionParseStage.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/snapshot/SnapshotVersionParseStage.java index e2d5030..d03ca76 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/snapshot/SnapshotVersionParseStage.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/pom/snapshot/SnapshotVersionParseStage.java @@ -14,19 +14,21 @@ public class SnapshotVersionParseStage implements ParseStage<@Nullable String> { - @Override @Nullable - public String parse(@NotNull Document document) + @Override + public String parse(@NotNull final Document document) { - Element versioning = (Element) document.getElementsByTagName("versioning").item(0); + final Element versioning = (Element) document.getElementsByTagName("versioning").item(0); + final NodeList versions = versioning.getElementsByTagName("snapshotVersions"); + final Element snapshotVersions = (Element) versions.item(0); - NodeList versions = versioning.getElementsByTagName("snapshotVersions"); - Element snapshotVersions = (Element) versions.item(0); if (snapshotVersions == null) { return null; } - NodeList snapshotVersion = snapshotVersions.getElementsByTagName("snapshotVersion"); + + final NodeList snapshotVersion = snapshotVersions.getElementsByTagName("snapshotVersion"); + if (snapshotVersion == null) { return null; @@ -34,14 +36,16 @@ public String parse(@NotNull Document document) for (int j = 0; j < snapshotVersion.getLength(); j++) { - Element snapshotItem = (Element) snapshotVersion.item(j); - String extension = snapshotItem.getElementsByTagName("extension").item(0).getTextContent(); - Node classifier = snapshotItem.getElementsByTagName("classifier").item(0); + final Element snapshotItem = (Element) snapshotVersion.item(j); + final String extension = snapshotItem.getElementsByTagName("extension").item(0).getTextContent(); + final Node classifier = snapshotItem.getElementsByTagName("classifier").item(0); + if (extension.equals("jar") && classifier == null) { return snapshotItem.getElementsByTagName("value").item(0).getTextContent(); } } + return null; } } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/DownloadResponse.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/DownloadResponse.java index 17f8d9e..0fc6fbf 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/DownloadResponse.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/DownloadResponse.java @@ -6,7 +6,7 @@ public class DownloadResponse private final boolean success; private final byte[] content; - public DownloadResponse(boolean success, byte[] content) + public DownloadResponse(final boolean success, final byte[] content) { this.success = success; this.content = content; diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/MavenCentral.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/MavenCentral.java index 07f3ee4..05be048 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/MavenCentral.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/MavenCentral.java @@ -5,6 +5,7 @@ public final class MavenCentral public static final String MAVEN_CENTRAL_ALIAS = "maven-central"; public static final String DEFAULT_CENTRAL_MIRROR = "https://repo.bristermitten.me/repository/maven-central/"; + private MavenCentral() { diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/MavenRepository.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/MavenRepository.java index 24ce8e5..b2cec4e 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/MavenRepository.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/MavenRepository.java @@ -1,6 +1,6 @@ package me.bristermitten.pdmlibs.repository; -import me.bristermitten.pdmlibs.artifact.Artifact; +import me.bristermitten.pdmlibs.dependency.Dependency; import me.bristermitten.pdmlibs.http.HTTPService; import me.bristermitten.pdmlibs.pom.ParseProcess; import me.bristermitten.pdmlibs.pom.PomParser; @@ -18,100 +18,106 @@ public class MavenRepository implements Repository { - private final Set containingArtifacts = ConcurrentHashMap.newKeySet(); + private final Set containingDependencies = ConcurrentHashMap.newKeySet(); @NotNull private final String baseURL; @NotNull private final HTTPService httpService; @NotNull - private final ParseProcess> parseProcess; + private final ParseProcess> parseProcess; @NotNull private final PomParser pomParser = new PomParser(); - public MavenRepository(@NotNull final String baseURL, @NotNull HTTPService httpService, @NotNull ParseProcess> parseProcess) + public MavenRepository(@NotNull final String baseURL, @NotNull final HTTPService httpService, + @NotNull final ParseProcess> parseProcess) { this.baseURL = baseURL; this.httpService = httpService; this.parseProcess = parseProcess; } - @Override @NotNull + @Override public String getURL() { return baseURL; } @Override - public boolean contains(@NotNull Artifact artifact) + public boolean contains(@NotNull final Dependency dependency) { - if (containingArtifacts.contains(artifact)) + if (containingDependencies.contains(dependency)) { return true; } - final URL pomURL = artifact.getPomURL(baseURL, httpService); + + final URL pomURL = dependency.getPomURL(baseURL, httpService); + if (pomURL == null) { return false; } - boolean contains = httpService.ping(pomURL); + + final boolean contains = httpService.ping(pomURL); + if (contains) { - containingArtifacts.add(artifact); + containingDependencies.add(dependency); } return contains; } - @Override @NotNull - public byte @NotNull [] download(@NotNull Artifact artifact) + @Override + public byte @NotNull [] download(@NotNull final Dependency dependency) { - return Streams.toByteArray(fetchJarContent(artifact)); + return Streams.toByteArray(fetchJarContent(dependency)); } - @Override @NotNull - public InputStream fetchJarContent(@NotNull Artifact artifact) + @Override + public InputStream fetchJarContent(@NotNull final Dependency dependency) { - return httpService.readJar(baseURL, artifact); + return httpService.readJar(baseURL, dependency); } - @Override @NotNull - public Set getTransitiveDependencies(@NotNull final Artifact artifact) + @Override + public Set getTransitiveDependencies(@NotNull final Dependency dependency) { - try (@NotNull InputStream pom = httpService.readPom(baseURL, artifact)) + try (final InputStream pom = httpService.readPom(baseURL, dependency)) { if (pom.available() == 0) { return Collections.emptySet(); } - return parse(artifact, pom); + return parse(dependency, pom); } - catch (IOException e) + catch (IOException exception) { - e.printStackTrace(); + exception.printStackTrace(); return Collections.emptySet(); } } - private @NotNull Set parse(@NotNull final Artifact artifact, @NotNull final InputStream pom) + @NotNull + private Set parse(@NotNull final Dependency dependency, @NotNull final InputStream pom) { try { return pomParser.parse(parseProcess, pom); } - catch (final @NotNull Exception e) + catch (Exception exception) { - throw new IllegalArgumentException("Could not parse pom for " + artifact + " at " + artifact.getPomURL(baseURL, httpService), e); + throw new IllegalArgumentException("Could not parse pom for " + dependency + " at " + dependency.getPomURL(baseURL, httpService), exception); } } @Override - public boolean equals(Object o) + public boolean equals(final Object o) { if (this == o) return true; if (!(o instanceof MavenRepository)) return false; @@ -125,8 +131,9 @@ public int hashCode() return Objects.hash(baseURL); } + @NotNull @Override - public @NotNull String toString() + public String toString() { return "MavenRepository{" + "baseURL='" + baseURL + '\'' + diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/MavenRepositoryFactory.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/MavenRepositoryFactory.java index 93d420f..3e635a8 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/MavenRepositoryFactory.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/MavenRepositoryFactory.java @@ -1,6 +1,6 @@ package me.bristermitten.pdmlibs.repository; -import me.bristermitten.pdmlibs.artifact.Artifact; +import me.bristermitten.pdmlibs.dependency.Dependency; import me.bristermitten.pdmlibs.http.HTTPService; import me.bristermitten.pdmlibs.pom.ParseProcess; import org.jetbrains.annotations.NotNull; @@ -14,16 +14,17 @@ public class MavenRepositoryFactory private final HTTPService httpService; @NotNull - private final ParseProcess> parseProcess; + private final ParseProcess> parseProcess; - public MavenRepositoryFactory(@NotNull HTTPService httpService, @NotNull final ParseProcess> parseProcess) + public MavenRepositoryFactory(@NotNull final HTTPService httpService, @NotNull final ParseProcess> parseProcess) { this.httpService = httpService; this.parseProcess = parseProcess; } - public @NotNull Repository create(@NotNull final String baseURL) + @NotNull + public Repository create(@NotNull final String baseURL) { return new MavenRepository(baseURL, httpService, parseProcess); } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/Repository.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/Repository.java index 0b9e44e..cecfce5 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/Repository.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/Repository.java @@ -1,6 +1,6 @@ package me.bristermitten.pdmlibs.repository; -import me.bristermitten.pdmlibs.artifact.Artifact; +import me.bristermitten.pdmlibs.dependency.Dependency; import org.jetbrains.annotations.NotNull; import java.io.InputStream; @@ -21,16 +21,16 @@ public interface Repository * Download the Jar content of a given Artifact in bytes. *

* Downloading may fail, usually if the artifact is not present in this repository. In this case an empty array will be returned. - * However, callers should usually check {@link Repository#contains(Artifact)} before calling this method. + * However, callers should usually check {@link Repository#contains(Dependency)} before calling this method. *

- * This method will likely use {@link Repository#fetchJarContent(Artifact)} in its implementation (although this is not guaranteed), + * This method will likely use {@link Repository#fetchJarContent(Dependency)} in its implementation (although this is not guaranteed), * so the same semantics usually apply. * - * @param artifact the Artifact to download + * @param dependency the Artifact to download * @return an array containing the bytes of the downloaded jar, or an empty array if downloading failed. */ @NotNull - byte[] download(@NotNull final Artifact artifact); + byte @NotNull [] download(@NotNull final Dependency dependency); /** * Get the Jar content of a given Artifact. @@ -38,15 +38,15 @@ public interface Repository * The returned stream should provide access to all of the bytes of the Jar's content, * and will be empty if the repository does not contain the given Artifact. * - * @param artifact the Artifact to download + * @param dependency the Artifact to download * @return an {@link InputStream} containing the bytes of the Jar, or empty if downloading failed - * @see Repository#download(Artifact) + * @see Repository#download(Dependency) */ @NotNull - InputStream fetchJarContent(@NotNull final Artifact artifact); + InputStream fetchJarContent(@NotNull final Dependency dependency); @NotNull - Set getTransitiveDependencies(@NotNull final Artifact artifact); + Set getTransitiveDependencies(@NotNull final Dependency dependency); - boolean contains(@NotNull final Artifact artifact); + boolean contains(@NotNull final Dependency dependency); } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/RepositoryManager.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/RepositoryManager.java index 9889d1e..75008a7 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/RepositoryManager.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/repository/RepositoryManager.java @@ -1,6 +1,6 @@ package me.bristermitten.pdmlibs.repository; -import me.bristermitten.pdmlibs.artifact.Artifact; +import me.bristermitten.pdmlibs.dependency.Dependency; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -16,15 +16,16 @@ public class RepositoryManager private final Map byAlias = new HashMap<>(); private final Map byURL = new HashMap<>(); + @NotNull private final Logger logger; - public RepositoryManager(Logger logger) + public RepositoryManager(@NotNull final Logger logger) { this.logger = logger; } @Nullable - public synchronized Repository getByAlias(String name) + public synchronized Repository getByAlias(@NotNull final String name) { return byAlias.get(name); } @@ -35,7 +36,7 @@ public synchronized Repository getByURL(@NotNull final String url) return byURL.get(url); } - public synchronized void addRepository(String alias, @NotNull Repository repository) + public synchronized void addRepository(@NotNull final String alias, @NotNull final Repository repository) { if (getByAlias(alias) != null) { @@ -45,33 +46,36 @@ public synchronized void addRepository(String alias, @NotNull Repository reposit byURL.put(repository.getURL(), repository); } - public @NotNull Collection getRepositories() + @NotNull + public Collection getRepositories() { return Collections.unmodifiableCollection(byAlias.values()); } @Nullable - public Repository firstContaining(@NotNull final Artifact artifact) + public Repository firstContaining(@NotNull final Dependency dependency) { - if (artifact.getRepoAlias() != null) + if (dependency.getRepoAlias() != null) { - final Repository configuredRepo = getByAlias(artifact.getRepoAlias()); + final Repository configuredRepo = getByAlias(dependency.getRepoAlias()); + if (configuredRepo != null) { - if (configuredRepo.contains(artifact)) + if (configuredRepo.contains(dependency)) { return configuredRepo; } - logger.warning(() -> "Despite being the configured repository, repo " + configuredRepo + " did not contain artifact " + artifact); + + logger.warning(() -> "Despite being the configured repository, repo " + configuredRepo + " did not contain artifact " + dependency); } if (configuredRepo == null) { - logger.warning(() -> "There was no configured repository with the alias " + artifact.getRepoAlias()); + logger.warning(() -> "There was no configured repository with the alias " + dependency.getRepoAlias()); } } return byURL.values().stream() - .filter(repo -> repo.contains(artifact)) + .filter(repo -> repo.contains(dependency)) .findFirst().orElse(null); } } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/util/Reflection.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/util/Reflection.java index f415650..8b01bfb 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/util/Reflection.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/util/Reflection.java @@ -12,24 +12,26 @@ public final class Reflection private Reflection() { + } + @NotNull @SuppressWarnings("unchecked") - public static @NotNull T getFieldValue(@NotNull Object instance, @NotNull String name) + public static T getFieldValue(@NotNull final Object instance, @NotNull final String name) { try { - Field field = instance.getClass().getDeclaredField(name); + final Field field = instance.getClass().getDeclaredField(name); field.setAccessible(true); return (T) field.get(instance); } - catch (NoSuchFieldException e) + catch (NoSuchFieldException exception) { - throw new RuntimeException("Field could not be found", e); + throw new RuntimeException("Field could not be found", exception); } - catch (IllegalAccessException e) + catch (IllegalAccessException exception) { - throw new AssertionError("Field could not be accessed after setting accessible = true", e); + throw new AssertionError("Field could not be accessed after setting accessible = true", exception); } } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/util/Streams.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/util/Streams.java index c783c5c..7711421 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/util/Streams.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/util/Streams.java @@ -13,25 +13,29 @@ public final class Streams private Streams() { + } @Nullable public static String toString(@NotNull final InputStream stream) { final byte[] bytes = toByteArray(stream); + if (bytes.length == 0) { return null; } + return new String(bytes); } @NotNull public static byte @NotNull [] toByteArray(@NotNull final InputStream stream) { - try (InputStream in = stream) + try (final InputStream in = stream) { - ByteArrayOutputStream output = new ByteArrayOutputStream(); + final ByteArrayOutputStream output = new ByteArrayOutputStream(); + int next; while ((next = in.read()) != -1) { @@ -40,7 +44,7 @@ public static String toString(@NotNull final InputStream stream) return output.toByteArray(); } - catch (IOException e) + catch (IOException exception) { return new byte[0]; } diff --git a/common-lib/src/main/java/me/bristermitten/pdmlibs/util/URLs.java b/common-lib/src/main/java/me/bristermitten/pdmlibs/util/URLs.java index 9727776..9d3cc19 100644 --- a/common-lib/src/main/java/me/bristermitten/pdmlibs/util/URLs.java +++ b/common-lib/src/main/java/me/bristermitten/pdmlibs/util/URLs.java @@ -24,16 +24,18 @@ public static URLConnection prepareConnection(@NotNull final URL url, @NotNull f { try { - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestProperty("User-Agent", userAgent); connection.connect(); + if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { return null; } + return connection; } - catch (IOException e) + catch (IOException exception) { return null; } @@ -46,7 +48,7 @@ public static byte[] getBytes(@NotNull final URL url, @NotNull final String user { return Streams.toByteArray(inputStream); } - catch (IOException e) + catch (IOException exception) { return new byte[0]; } @@ -55,7 +57,8 @@ public static byte[] getBytes(@NotNull final URL url, @NotNull final String user @NotNull public static InputStream read(@NotNull final URL url, @NotNull final String userAgent) { - URLConnection connection = URLs.prepareConnection(url, userAgent); + final URLConnection connection = URLs.prepareConnection(url, userAgent); + if (connection == null) { return Streams.createEmptyStream(); @@ -77,7 +80,7 @@ public static URL parseURL(@NotNull final String url) { return new URL(url); } - catch (MalformedURLException e) + catch (MalformedURLException exception) { return null; } diff --git a/common-lib/src/test/kotlin/me/bristermitten/pdmlibs/artifact/ReleaseArtifactTests.kt b/common-lib/src/test/kotlin/me/bristermitten/pdmlibs/dependency/ReleaseDependencyTests.kt similarity index 77% rename from common-lib/src/test/kotlin/me/bristermitten/pdmlibs/artifact/ReleaseArtifactTests.kt rename to common-lib/src/test/kotlin/me/bristermitten/pdmlibs/dependency/ReleaseDependencyTests.kt index 3c8f819..a6c0aca 100644 --- a/common-lib/src/test/kotlin/me/bristermitten/pdmlibs/artifact/ReleaseArtifactTests.kt +++ b/common-lib/src/test/kotlin/me/bristermitten/pdmlibs/dependency/ReleaseDependencyTests.kt @@ -1,4 +1,4 @@ -package me.bristermitten.pdmlibs.artifact +package me.bristermitten.pdmlibs.dependency import me.bristermitten.pdmlibs.config.CacheConfiguration import me.bristermitten.pdmlibs.http.HTTPService @@ -9,19 +9,20 @@ import org.junit.jupiter.api.Test /** * @author AlexL */ -class ReleaseArtifactTests +class ReleaseDependencyTests { @Test fun `Test Processing of Sonatype Nexus Release Artifact`() { - val artifactFactory = ArtifactFactory() + val artifactFactory = DependencyFactory() val artifact = artifactFactory.toArtifact( "me.bristermitten", "common-lib", "0.0.2", null, - null + null, + mapOf("me.bristermitten.common-lib" to "me.bristermitten.pdmlibs.libs.common-lib") ) val httpService = HTTPService("PDM-Test-Suite", "N/A", CacheConfiguration.builder().build()) diff --git a/common-lib/src/test/kotlin/me/bristermitten/pdmlibs/artifact/SnapshotArtifactTests.kt b/common-lib/src/test/kotlin/me/bristermitten/pdmlibs/dependency/SnapshotDependencyTests.kt similarity index 76% rename from common-lib/src/test/kotlin/me/bristermitten/pdmlibs/artifact/SnapshotArtifactTests.kt rename to common-lib/src/test/kotlin/me/bristermitten/pdmlibs/dependency/SnapshotDependencyTests.kt index 977797f..823a89c 100644 --- a/common-lib/src/test/kotlin/me/bristermitten/pdmlibs/artifact/SnapshotArtifactTests.kt +++ b/common-lib/src/test/kotlin/me/bristermitten/pdmlibs/dependency/SnapshotDependencyTests.kt @@ -1,4 +1,4 @@ -package me.bristermitten.pdmlibs.artifact +package me.bristermitten.pdmlibs.dependency import me.bristermitten.pdmlibs.config.CacheConfiguration import me.bristermitten.pdmlibs.http.HTTPService @@ -9,18 +9,19 @@ import org.junit.jupiter.api.Test /** * @author AlexL */ -class SnapshotArtifactTests +class SnapshotDependencyTests { @Test fun `Test Processing of Jitpack Snapshot Artifact`() { - val artifactFactory = ArtifactFactory() + val artifactFactory = DependencyFactory() val artifact = artifactFactory.toArtifact( "com.github.JohnnyJayJay", "compatre", "master-SNAPSHOT", null, - null + null, + mapOf("com.github.johnnyjayjay.compatre" to "me.bristermitten.pdmlibs.libs.compatre") ) val httpService = HTTPService("PDM-Test-Suite", "N/A", CacheConfiguration.builder().build()) @@ -32,13 +33,14 @@ class SnapshotArtifactTests @Test fun `Test Processing of Sonatype Nexus Snapshot Artifact`() { - val artifactFactory = ArtifactFactory() + val artifactFactory = DependencyFactory() val artifact = artifactFactory.toArtifact( "me.bristermitten", "fluency", "1.1-SNAPSHOT", null, - null + null, + mapOf("me.bristermitten.fluency" to "me.bristermitten.pdmlibs.libs.fluency") ) val httpService = HTTPService("PDM-Test-Suite", "N/A", CacheConfiguration.builder().build()) diff --git a/common-lib/src/test/kotlin/me/bristermitten/pdmlibs/pom/DefaultParseProcessTest.kt b/common-lib/src/test/kotlin/me/bristermitten/pdmlibs/pom/DefaultParseProcessTest.kt index ad291d8..702c5e7 100644 --- a/common-lib/src/test/kotlin/me/bristermitten/pdmlibs/pom/DefaultParseProcessTest.kt +++ b/common-lib/src/test/kotlin/me/bristermitten/pdmlibs/pom/DefaultParseProcessTest.kt @@ -1,7 +1,7 @@ package me.bristermitten.pdmlibs.pom -import me.bristermitten.pdmlibs.artifact.ArtifactFactory import me.bristermitten.pdmlibs.config.CacheConfiguration +import me.bristermitten.pdmlibs.dependency.DependencyFactory import me.bristermitten.pdmlibs.http.HTTPService import me.bristermitten.pdmlibs.repository.RepositoryManager import org.intellij.lang.annotations.Language @@ -24,7 +24,7 @@ class DefaultParseProcessTest val repositoryManager = RepositoryManager(logger) val httpService = HTTPService("PDM-Test-Suite", "N/A", CacheConfiguration.builder().build()) - val defaultParseProcess = DefaultParseProcess(ArtifactFactory(), repositoryManager, httpService) + val defaultParseProcess = DefaultParseProcess(DependencyFactory(), repositoryManager, httpService) val results = PomParser().parse(defaultParseProcess, pom) diff --git a/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/PDM.kt b/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/PDM.kt index 81e53c1..ed3ba16 100644 --- a/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/PDM.kt +++ b/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/PDM.kt @@ -1,12 +1,11 @@ package me.bristermitten.pdm -import me.bristermitten.pdmlibs.artifact.ArtifactFactory +import me.bristermitten.pdmlibs.dependency.DependencyFactory import me.bristermitten.pdmlibs.repository.RepositoryManager import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.ExternalModuleDependency -import org.gradle.util.ConfigureUtil import java.util.logging.Logger class PDM : Plugin @@ -14,7 +13,7 @@ class PDM : Plugin companion object { const val CONFIGURATION_NAME = "pdm" } - private val artifactFactory = ArtifactFactory() + private val artifactFactory = DependencyFactory() private val repositoryManager = RepositoryManager(Logger.getLogger(javaClass.name)) diff --git a/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/PDMGenDependenciesTask.kt b/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/PDMGenDependenciesTask.kt index 8f5e1c8..e59847f 100644 --- a/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/PDMGenDependenciesTask.kt +++ b/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/PDMGenDependenciesTask.kt @@ -5,8 +5,8 @@ import me.bristermitten.pdm.json.ArtifactDTO import me.bristermitten.pdm.json.DependenciesConfiguration import me.bristermitten.pdm.json.ExcludeRule import me.bristermitten.pdm.json.PDMDependency -import me.bristermitten.pdmlibs.artifact.Artifact -import me.bristermitten.pdmlibs.artifact.ArtifactFactory +import me.bristermitten.pdmlibs.dependency.Dependency +import me.bristermitten.pdmlibs.dependency.DependencyFactory import me.bristermitten.pdmlibs.http.HTTPService import me.bristermitten.pdmlibs.pom.DefaultParseProcess import me.bristermitten.pdmlibs.repository.MavenRepositoryFactory @@ -14,7 +14,6 @@ import me.bristermitten.pdmlibs.repository.Repository import me.bristermitten.pdmlibs.repository.RepositoryManager import org.gradle.api.Project import org.gradle.api.artifacts.Configuration -import org.gradle.api.artifacts.ExternalModuleDependency import org.gradle.api.artifacts.ModuleDependency import org.gradle.api.artifacts.ProjectDependency import org.gradle.api.artifacts.repositories.MavenArtifactRepository @@ -22,10 +21,10 @@ import org.slf4j.LoggerFactory import java.io.File class PDMGenDependenciesTask( - private val artifactFactory: ArtifactFactory, + private val dependencyFactory: DependencyFactory, private val pdmDependency: Configuration, private val config: PDMExtension, - private val repositoryManager: RepositoryManager, + private val repositoryManager: RepositoryManager, private val gson: Gson = Gson() ) : (Project) -> Unit { @@ -38,7 +37,7 @@ class PDMGenDependenciesTask( private fun generateProjectState(project: Project): ProjectState { val httpService = HTTPService(project.name, config.version, config.caching) - val repositoryFactory = MavenRepositoryFactory(httpService, DefaultParseProcess(artifactFactory, repositoryManager, httpService)) + val repositoryFactory = MavenRepositoryFactory(httpService, DefaultParseProcess(dependencyFactory, repositoryManager, httpService)) return generateProjectState(project, repositoryFactory) } @@ -88,7 +87,7 @@ class PDMGenDependenciesTask( { val artifacts = state.dependencies.map { - val artifact = artifactFactory.toArtifact(it.group, it.artifact, it.version, null, null) + val artifact = dependencyFactory.toArtifact(it.group, it.artifact, it.version, null, null, null) artifact.resolvePDMDependency( config.spigot, @@ -124,7 +123,7 @@ class PDMGenDependenciesTask( process(state, project) } - private fun Artifact.resolvePDMDependency( + private fun Dependency.resolvePDMDependency( spigot: Boolean, searchRepositories: Boolean, repositories: Map, diff --git a/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/PDMTask.kt b/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/PDMTask.kt index bfce1e8..74c5abe 100644 --- a/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/PDMTask.kt +++ b/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/PDMTask.kt @@ -2,7 +2,7 @@ package me.bristermitten.pdm import com.google.gson.GsonBuilder import me.bristermitten.pdm.json.RepositoryTypeAdapter -import me.bristermitten.pdmlibs.artifact.ArtifactFactory +import me.bristermitten.pdmlibs.dependency.DependencyFactory import me.bristermitten.pdmlibs.http.HTTPService import me.bristermitten.pdmlibs.pom.DefaultParseProcess import me.bristermitten.pdmlibs.repository.MavenRepositoryFactory @@ -17,7 +17,7 @@ import java.io.File class PDMTask( private val config: PDMExtension, private val pdmDependency: Configuration, - private val artifactFactory: ArtifactFactory, + private val dependencyFactory: DependencyFactory, private val repositoryManager: RepositoryManager, private val dependenciesTask: PDMGenDependenciesTask ) : (Project, Task) -> Unit @@ -31,7 +31,7 @@ class PDMTask( } val httpService = HTTPService(project.name, config.version, config.caching) - val repositoryFactory = MavenRepositoryFactory(httpService, DefaultParseProcess(artifactFactory, repositoryManager, httpService)) + val repositoryFactory = MavenRepositoryFactory(httpService, DefaultParseProcess(dependencyFactory, repositoryManager, httpService)) val gson = GsonBuilder().registerTypeAdapter(Repository::class.java, RepositoryTypeAdapter(repositoryFactory)).create() val state = dependenciesTask.generateProjectState(project, repositoryFactory) diff --git a/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/SpigotDependencies.kt b/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/SpigotDependencies.kt index 45e5c16..cef81d6 100644 --- a/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/SpigotDependencies.kt +++ b/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/SpigotDependencies.kt @@ -1,6 +1,6 @@ package me.bristermitten.pdm -import me.bristermitten.pdmlibs.artifact.Artifact +import me.bristermitten.pdmlibs.dependency.Dependency private val SPIGOT_GROUP_IDS = setOf( "net.minecraft", @@ -23,7 +23,7 @@ private val SPIGOT_ARTIFACT_IDS = setOf( * * This is determined by comparing the group and artifact id with a given table (which includes NMS, Bukkit, CraftBukkit, and Paper too) */ -fun Artifact.isSpigotArtifact(): Boolean +fun Dependency.isSpigotArtifact(): Boolean { return groupId in SPIGOT_GROUP_IDS && artifactId in SPIGOT_ARTIFACT_IDS } diff --git a/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/json/ArtifactDTO.kt b/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/json/ArtifactDTO.kt index b4ce290..6cfb58b 100644 --- a/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/json/ArtifactDTO.kt +++ b/pdm-gradle/src/main/kotlin/me/bristermitten/pdm/json/ArtifactDTO.kt @@ -1,6 +1,6 @@ package me.bristermitten.pdm.json -import me.bristermitten.pdmlibs.artifact.Artifact +import me.bristermitten.pdmlibs.dependency.Dependency data class ArtifactDTO( val group: String, @@ -12,14 +12,14 @@ data class ArtifactDTO( data class ExcludeRule(val group: String?, val module: String?) { - fun match(artifact: Artifact): Boolean + fun match(dependency: Dependency): Boolean { return if(group != null && module != null) { - artifact.groupId.equals(group, ignoreCase = true) && artifact.artifactId.equals(module, ignoreCase = true) + dependency.groupId.equals(group, ignoreCase = true) && dependency.artifactId.equals(module, ignoreCase = true) } else if(group != null) { - artifact.groupId.equals(group, ignoreCase = true) + dependency.groupId.equals(group, ignoreCase = true) } else { - artifact.artifactId.equals(module, ignoreCase = true) + dependency.artifactId.equals(module, ignoreCase = true) } } } diff --git a/pdm/build.gradle b/pdm/build.gradle index 1db8a41..6fdbed1 100644 --- a/pdm/build.gradle +++ b/pdm/build.gradle @@ -11,6 +11,10 @@ repositories { dependencies { api project(':common-lib') + implementation('me.lucko:jar-relocator:1.4') { +// exclude group: 'org.ow2.asm', module: 'asm-commons' +// exclude group: 'org.ow2.asm', module: 'asm' + } compileOnly 'org.jetbrains:annotations:19.0.0' compileOnly 'org.spigotmc:spigot-api:1.15.2-R0.1-SNAPSHOT' diff --git a/pdm/src/main/java/me/bristermitten/pdm/DependencyLoader.java b/pdm/src/main/java/me/bristermitten/pdm/DependencyLoader.java deleted file mode 100644 index 9884ec8..0000000 --- a/pdm/src/main/java/me/bristermitten/pdm/DependencyLoader.java +++ /dev/null @@ -1,55 +0,0 @@ -package me.bristermitten.pdm; - -import me.bristermitten.pdm.util.ClassLoaderReflection; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.File; -import java.net.MalformedURLException; -import java.net.URLClassLoader; -import java.util.HashSet; -import java.util.Set; -import java.util.function.Function; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class DependencyLoader -{ - - @NotNull - private final URLClassLoader classLoader; - @NotNull - private final Logger logger; - - @NotNull - private final Set loaded = new HashSet<>(); - - public DependencyLoader(@NotNull final URLClassLoader classLoader, @NotNull final Function logger) - { - this.classLoader = classLoader; - this.logger = logger.apply(getClass().getName()); - } - - public void loadDependency(@Nullable final File file) - { - if (file == null) - { - return; - } - - if (loaded.contains(file)) - { - return; - } - - try - { - ClassLoaderReflection.addURL(classLoader, file.toURI().toURL()); - loaded.add(file); - } - catch (MalformedURLException exception) - { - logger.log(Level.SEVERE, exception, () -> "Could not load dependency from file " + file); - } - } -} diff --git a/pdm/src/main/java/me/bristermitten/pdm/DependencyManager.java b/pdm/src/main/java/me/bristermitten/pdm/DependencyManager.java index 4fe6feb..7e25311 100644 --- a/pdm/src/main/java/me/bristermitten/pdm/DependencyManager.java +++ b/pdm/src/main/java/me/bristermitten/pdm/DependencyManager.java @@ -1,9 +1,14 @@ package me.bristermitten.pdm; +import com.google.common.collect.ImmutableSet; +import me.bristermitten.pdm.loading.types.ClasspathAddendumDependencyLoader; +import me.bristermitten.pdm.loading.types.IsolatedDependencyLoader; +import me.bristermitten.pdm.relocation.RelocationHandler; import me.bristermitten.pdm.repository.SpigotRepository; import me.bristermitten.pdm.util.FileUtils; -import me.bristermitten.pdmlibs.artifact.Artifact; -import me.bristermitten.pdmlibs.artifact.ArtifactFactory; +import me.bristermitten.pdmlibs.dependency.Dependency; +import me.bristermitten.pdmlibs.dependency.DependencyFactory; +import me.bristermitten.pdmlibs.dependency.ReleaseDependency; import me.bristermitten.pdmlibs.http.HTTPService; import me.bristermitten.pdmlibs.pom.DefaultParseProcess; import me.bristermitten.pdmlibs.repository.MavenRepositoryFactory; @@ -16,6 +21,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; @@ -31,21 +37,30 @@ public class DependencyManager public static final String PDM_DIRECTORY_NAME = "PluginLibraries"; + private static final Set PDM_REQUIREMENTS = ImmutableSet.builder() + .add(new ReleaseDependency("me.lucko", "jar-relocator", "1.4")) + .add(new ReleaseDependency("org.ow2.asm", "asm", "7.1")) + .add(new ReleaseDependency("org.ow2.asm", "asm-commons", "7.1")) + .build(); + @NotNull private final PDMSettings settings; @NotNull private final RepositoryManager repositoryManager; @NotNull private final MavenRepositoryFactory repositoryFactory; - @NotNull private final DependencyLoader loader; - private final ArtifactFactory artifactFactory = new ArtifactFactory(); + @NotNull private final IsolatedDependencyLoader isolatedDependencyLoader; + @NotNull private final ClasspathAddendumDependencyLoader classpathAddendumDependencyLoader; + private final DependencyFactory dependencyFactory = new DependencyFactory(); @NotNull private final HTTPService httpService; + private RelocationHandler relocationHandler; + /** * A Map that caches download tasks for artifacts. *

* This ensures that artifacts are only downloaded once, rather than a potential race condition that involves multiple * tasks writing to the same file. */ - private final Map> downloadsInProgress = new ConcurrentHashMap<>(); + private final Map> downloadsInProgress = new ConcurrentHashMap<>(); private final Logger logger; @NotNull private final DefaultParseProcess parseProcess; private File pdmDirectory; @@ -60,12 +75,13 @@ public DependencyManager(@NotNull final PDMSettings settings, @NotNull final Str { this.settings = settings; this.logger = settings.getLoggerSupplier().apply(getClass().getName()); - this.loader = new DependencyLoader(settings.getClassLoader(), settings.getLoggerSupplier()); + this.isolatedDependencyLoader = new IsolatedDependencyLoader(settings.getLoggerSupplier()); + this.classpathAddendumDependencyLoader = new ClasspathAddendumDependencyLoader(settings.getLoggerSupplier(), settings.getClassLoader()); this.httpService = httpService; this.repositoryManager = new RepositoryManager(settings.getLoggerSupplier().apply(RepositoryManager.class.getName())); - this.parseProcess = new DefaultParseProcess(artifactFactory, repositoryManager, httpService); + this.parseProcess = new DefaultParseProcess(dependencyFactory, repositoryManager, httpService); this.repositoryFactory = new MavenRepositoryFactory(httpService, parseProcess); loadRepositories(); @@ -100,9 +116,9 @@ SpigotRepository.SPIGOT_ALIAS, new SpigotRepository(httpService, parseProcess) } @NotNull - public ArtifactFactory getArtifactFactory() + public DependencyFactory getArtifactFactory() { - return artifactFactory; + return dependencyFactory; } @NotNull @@ -112,13 +128,31 @@ public MavenRepositoryFactory getRepositoryFactory() } @NotNull - public CompletableFuture downloadAndLoad(@NotNull final Artifact dependency) + public CompletableFuture downloadAndLoadPDMDependencies() { + final Set> futures = PDM_REQUIREMENTS.stream() + .map(this::downloadAndRelocate) + .collect(Collectors.toSet()); + + return CompletableFuture.allOf(futures.toArray(new CompletableFuture[]{})) + .thenAccept(v -> { + final File[] files = futures.stream() + .map(CompletableFuture::join) + .toArray(File[]::new); + + isolatedDependencyLoader.loadDependency(files); + this.relocationHandler = new RelocationHandler(isolatedDependencyLoader.getClassLoader(files[0])); + }); + } + + @NotNull + public CompletableFuture downloadAndRelocateAndLoad(@NotNull final Dependency dependency) { - return download(dependency).thenAccept(loader::loadDependency); + return downloadAndRelocate(dependency) + .thenAccept(classpathAddendumDependencyLoader::loadDependency); } @NotNull - public CompletableFuture download(@NotNull final Artifact dependency) + public CompletableFuture downloadAndRelocate(@NotNull final Dependency dependency) { final CompletableFuture inProgress = downloadsInProgress.get(dependency); @@ -151,6 +185,15 @@ public CompletableFuture download(@NotNull final Artifact dependency) { final InputStream jarContent = containingRepo.fetchJarContent(dependency); writeToFile(jarContent, file); + + Optional.ofNullable(dependency.getRelocations()) + .ifPresent(relocations -> { + final File relocated = new File(file.getPath() + "-remapped"); + relocationHandler.relocate(file.toPath(), relocated.toPath(), relocations); + + file.delete(); + relocated.renameTo(file); + }); } return file; @@ -167,39 +210,39 @@ public CompletableFuture download(@NotNull final Artifact dependency) } @NotNull - private Set> downloadTransitiveDependencies(@NotNull final Repository repository, @NotNull final Artifact artifact) + private Set> downloadTransitiveDependencies(@NotNull final Repository repository, @NotNull final Dependency dependency) { - logger.fine(() -> "Downloading Transitive Dependencies for " + artifact); + logger.fine(() -> "Downloading Transitive Dependencies for " + dependency); - Set transitiveDependencies = artifact.getTransitiveDependencies(); + Set transitiveDependencies = dependency.getTransitiveDependencies(); if (transitiveDependencies == null) { - transitiveDependencies = repository.getTransitiveDependencies(artifact); - artifact.setTransitiveDependencies(transitiveDependencies); //To save potential repeated lookups + transitiveDependencies = repository.getTransitiveDependencies(dependency); + dependency.setTransitiveDependencies(transitiveDependencies); //To save potential repeated lookups } return transitiveDependencies.stream() - .map(this::downloadAndLoad) + .map(this::downloadAndRelocateAndLoad) .collect(Collectors.toSet()); } @Nullable - private Repository getRepositoryFor(@NotNull final Artifact artifact) + private Repository getRepositoryFor(@NotNull final Dependency dependency) { - if (artifact.getRepoAlias() != null) + if (dependency.getRepoAlias() != null) { - final Repository byURL = repositoryManager.getByAlias(artifact.getRepoAlias()); + final Repository byURL = repositoryManager.getByAlias(dependency.getRepoAlias()); if (byURL == null) { - logger.warning(() -> "No repository configured for " + artifact.getRepoAlias()); + logger.warning(() -> "No repository configured for " + dependency.getRepoAlias()); return null; } return byURL; } else { - return repositoryManager.firstContaining(artifact); + return repositoryManager.firstContaining(dependency); } } diff --git a/pdm/src/main/java/me/bristermitten/pdm/PluginDependencyManager.java b/pdm/src/main/java/me/bristermitten/pdm/PluginDependencyManager.java index 9403ed6..23ab711 100644 --- a/pdm/src/main/java/me/bristermitten/pdm/PluginDependencyManager.java +++ b/pdm/src/main/java/me/bristermitten/pdm/PluginDependencyManager.java @@ -3,8 +3,8 @@ import com.google.gson.JsonParseException; import me.bristermitten.pdm.dependency.JSONDependencies; import me.bristermitten.pdm.util.Constants; -import me.bristermitten.pdmlibs.artifact.Artifact; import me.bristermitten.pdmlibs.config.CacheConfiguration; +import me.bristermitten.pdmlibs.dependency.Dependency; import me.bristermitten.pdmlibs.http.HTTPService; import me.bristermitten.pdmlibs.repository.Repository; import org.jetbrains.annotations.NotNull; @@ -29,7 +29,7 @@ public final class PluginDependencyManager private final DependencyManager manager; @NotNull - private final Set requiredDependencies = new HashSet<>(); + private final Set requiredDependencies = new HashSet<>(); @NotNull private final Logger logger; @@ -52,7 +52,7 @@ public final class PluginDependencyManager } } - public void addRequiredDependency(@NotNull final Artifact dependency) + public void addRequiredDependency(@NotNull final Dependency dependency) { requiredDependencies.add(dependency); } @@ -101,7 +101,7 @@ private void loadDependenciesFromFile(@NotNull final InputStream dependenciesRes }); jsonDependencies.getDependencies().forEach(dto -> { - final Artifact dependency = manager.getArtifactFactory().toArtifact(dto); + final Dependency dependency = manager.getArtifactFactory().toArtifact(dto); addRequiredDependency(dependency); }); @@ -113,7 +113,7 @@ private void loadDependenciesFromFile(@NotNull final InputStream dependenciesRes /** * Download (if applicable) and load all required dependencies - * as configured by {@link PluginDependencyManager#addRequiredDependency(Artifact)} and {@link PluginDependencyManager#loadDependenciesFromFile(InputStream)} + * as configured by {@link PluginDependencyManager#addRequiredDependency(Dependency)} and {@link PluginDependencyManager#loadDependenciesFromFile(InputStream)} *

* This method is non blocking, and returns a {@link CompletableFuture} * which is completed once all dependencies have been downloaded (if applicable), loaded into the classpath, or failed. @@ -132,14 +132,16 @@ public CompletableFuture loadAllDependencies() logger.warning("There were no dependencies to load! This might be intentional, but if not, check your dependencies configuration!"); } - return CompletableFuture.allOf(requiredDependencies.stream() - .map(manager::downloadAndLoad) - .toArray(CompletableFuture[]::new)); + //todo: i've got no idea if this will work + return manager.downloadAndLoadPDMDependencies() + .thenCombine(CompletableFuture.allOf(requiredDependencies.stream() + .map(manager::downloadAndRelocateAndLoad) + .toArray(CompletableFuture[]::new)), (v1, v2) -> v1); } /** * Download (if applicable) all required dependencies - * as configured by {@link PluginDependencyManager#addRequiredDependency(Artifact)} and {@link PluginDependencyManager#loadDependenciesFromFile(InputStream)} + * as configured by {@link PluginDependencyManager#addRequiredDependency(Dependency)} and {@link PluginDependencyManager#loadDependenciesFromFile(InputStream)} *

* This method is non blocking, and returns a {@link CompletableFuture} * which is completed once all dependencies have been downloaded (if applicable), or failed. @@ -157,7 +159,7 @@ public CompletableFuture> downloadAllDependencies() return CompletableFuture.supplyAsync( () -> requiredDependencies.stream() - .map(manager::download) + .map(manager::downloadAndRelocate) .map(CompletableFuture::join) .collect(Collectors.toList()) ); diff --git a/pdm/src/main/java/me/bristermitten/pdm/dependency/JSONDependencies.java b/pdm/src/main/java/me/bristermitten/pdm/dependency/JSONDependencies.java index 6e700fb..054e75f 100644 --- a/pdm/src/main/java/me/bristermitten/pdm/dependency/JSONDependencies.java +++ b/pdm/src/main/java/me/bristermitten/pdm/dependency/JSONDependencies.java @@ -1,6 +1,6 @@ package me.bristermitten.pdm.dependency; -import me.bristermitten.pdmlibs.artifact.ArtifactDTO; +import me.bristermitten.pdmlibs.dependency.DependencyDTO; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -13,12 +13,12 @@ public class JSONDependencies @NotNull private final Map repositories; @NotNull - private final Set dependencies; + private final Set dependencies; @Nullable private final String dependenciesDirectory; - public JSONDependencies(@NotNull final Map repositories, @NotNull final Set dependencies, + public JSONDependencies(@NotNull final Map repositories, @NotNull final Set dependencies, @Nullable final String dependenciesDirectory) { this.repositories = repositories; @@ -33,7 +33,7 @@ public Map getRepositories() } @NotNull - public Set getDependencies() + public Set getDependencies() { return dependencies; } diff --git a/pdm/src/main/java/me/bristermitten/pdm/loading/DependencyLoader.java b/pdm/src/main/java/me/bristermitten/pdm/loading/DependencyLoader.java new file mode 100644 index 0000000..c3b1137 --- /dev/null +++ b/pdm/src/main/java/me/bristermitten/pdm/loading/DependencyLoader.java @@ -0,0 +1,45 @@ +package me.bristermitten.pdm.loading; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.net.MalformedURLException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.logging.Level; +import java.util.logging.Logger; + +// ------------------------------ +// Copyright (c) PiggyPiglet 2020 +// https://www.piggypiglet.me +// ------------------------------ +public abstract class DependencyLoader { + private final Set loaded = new HashSet<>(); + + private final Logger logger; + + protected DependencyLoader(@NotNull final Function logger) { + this.logger = logger.apply(getClass().getName()); + } + + protected abstract void load(@NotNull final File @NotNull ... files) throws MalformedURLException; + + public void loadDependency(@Nullable final File @Nullable ... files) { + if (files == null || Arrays.stream(files).anyMatch(Objects::isNull) || Arrays.stream(files).noneMatch(loaded::contains)) { + return; + } + + try { + //noinspection NullableProblems + load(files); + } catch (MalformedURLException exception) { + logger.log(Level.SEVERE, exception, () -> "Could not load dependenc(y/ies) from files: " + Arrays.toString(files)); + } + + loaded.addAll(Arrays.asList(files)); + } +} diff --git a/pdm/src/main/java/me/bristermitten/pdm/loading/loaders/IsolatedClassLoader.java b/pdm/src/main/java/me/bristermitten/pdm/loading/loaders/IsolatedClassLoader.java new file mode 100644 index 0000000..a6312db --- /dev/null +++ b/pdm/src/main/java/me/bristermitten/pdm/loading/loaders/IsolatedClassLoader.java @@ -0,0 +1,55 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.bristermitten.pdm.loading.loaders; + +import org.jetbrains.annotations.NotNull; + +import java.net.URL; +import java.net.URLClassLoader; + +/** + * A classloader "isolated" from the rest of the Minecraft server. + * + *

Used to load specific LuckPerms dependencies without causing conflicts + * with other plugins, or libraries provided by the server implementation.

+ */ +public final class IsolatedClassLoader extends URLClassLoader { + static { + ClassLoader.registerAsParallelCapable(); + } + + public IsolatedClassLoader(@NotNull final URL @NotNull ... urls) { + /* + * ClassLoader#getSystemClassLoader returns the AppClassLoader + * + * Calling #getParent on this returns the ExtClassLoader (Java 8) or + * the PlatformClassLoader (Java 9). Since we want this classloader to + * be isolated from the Minecraft server (the app), we set the parent + * to be the platform class loader. + */ + super(urls, ClassLoader.getSystemClassLoader().getParent()); + } +} diff --git a/pdm/src/main/java/me/bristermitten/pdm/loading/types/ClasspathAddendumDependencyLoader.java b/pdm/src/main/java/me/bristermitten/pdm/loading/types/ClasspathAddendumDependencyLoader.java new file mode 100644 index 0000000..6d5f066 --- /dev/null +++ b/pdm/src/main/java/me/bristermitten/pdm/loading/types/ClasspathAddendumDependencyLoader.java @@ -0,0 +1,48 @@ +package me.bristermitten.pdm.loading.types; + +import me.bristermitten.pdm.loading.DependencyLoader; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.function.Function; +import java.util.logging.Logger; + +// ------------------------------ +// Copyright (c) PiggyPiglet 2020 +// https://www.piggypiglet.me +// ------------------------------ +public final class ClasspathAddendumDependencyLoader extends DependencyLoader { + private static final Method ADD_URL; + + static { + try { + ADD_URL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); + ADD_URL.setAccessible(true); + } catch (NoSuchMethodException exception) { + throw new AssertionError(exception); + } + } + + private final URLClassLoader loader; + + public ClasspathAddendumDependencyLoader(@NotNull final Function logger, @NotNull final URLClassLoader loader) { + super(logger); + this.loader = loader; + } + + @Override + protected void load(@NotNull final File @NotNull ... files) throws MalformedURLException { + for (final File file : files) { + try { + ADD_URL.invoke(loader, file.toURI().toURL()); + } catch (IllegalAccessException | InvocationTargetException exception) { + throw new AssertionError(exception); + } + } + } +} diff --git a/pdm/src/main/java/me/bristermitten/pdm/loading/types/IsolatedDependencyLoader.java b/pdm/src/main/java/me/bristermitten/pdm/loading/types/IsolatedDependencyLoader.java new file mode 100644 index 0000000..e0da737 --- /dev/null +++ b/pdm/src/main/java/me/bristermitten/pdm/loading/types/IsolatedDependencyLoader.java @@ -0,0 +1,41 @@ +package me.bristermitten.pdm.loading.types; + +import me.bristermitten.pdm.loading.DependencyLoader; +import me.bristermitten.pdm.loading.loaders.IsolatedClassLoader; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.*; +import java.util.function.Function; +import java.util.logging.Logger; + +// ------------------------------ +// Copyright (c) PiggyPiglet 2020 +// https://www.piggypiglet.me +// ------------------------------ +public final class IsolatedDependencyLoader extends DependencyLoader { + private final Map loaders = new HashMap<>(); + + public IsolatedDependencyLoader(@NotNull final Function logger) { + super(logger); + } + + @Override + protected void load(@NotNull final File @NotNull ... files) throws MalformedURLException { + final Set urls = new HashSet<>(); + + for (final File file : files) { + urls.add(file.toURI().toURL()); + } + + final ClassLoader loader = new IsolatedClassLoader(urls.toArray(new URL[0])); + Arrays.stream(files).forEach(file -> loaders.put(file, loader)); + } + + @NotNull + public ClassLoader getClassLoader(@NotNull final File file) { + return loaders.get(file); + } +} diff --git a/pdm/src/main/java/me/bristermitten/pdm/relocation/RelocationHandler.java b/pdm/src/main/java/me/bristermitten/pdm/relocation/RelocationHandler.java new file mode 100644 index 0000000..f552103 --- /dev/null +++ b/pdm/src/main/java/me/bristermitten/pdm/relocation/RelocationHandler.java @@ -0,0 +1,45 @@ +package me.bristermitten.pdm.relocation; + +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.nio.file.Path; +import java.util.Map; + +// ------------------------------ +// Copyright (c) PiggyPiglet 2020 +// https://www.piggypiglet.me +// ------------------------------ +public final class RelocationHandler { + private static final String CLASS_NAME = "me.lucko.jarrelocator.JarRelocator"; + private static final String RUN_METHOD = "run"; + + private final Constructor constructor; + private final Method run; + + public RelocationHandler(@NotNull final ClassLoader loader) { + try { + final Class clazz = loader.loadClass(CLASS_NAME); + + this.constructor = clazz.getDeclaredConstructor(File.class, File.class, Map.class); + this.constructor.setAccessible(true); + + this.run = clazz.getDeclaredMethod(RUN_METHOD); + this.run.setAccessible(true); + } catch (Exception exception) { + throw new RuntimeException(exception); + } + } + + public void relocate(@NotNull final Path input, @NotNull final Path output, + @NotNull final Map relocations) { + try { + final Object relocator = constructor.newInstance(input.toFile(), output.toFile(), relocations); + run.invoke(relocator); + } catch (Exception exception) { + throw new RuntimeException(exception); + } + } +} diff --git a/pdm/src/main/java/me/bristermitten/pdm/repository/SpigotRepository.java b/pdm/src/main/java/me/bristermitten/pdm/repository/SpigotRepository.java index e356c25..54fe296 100644 --- a/pdm/src/main/java/me/bristermitten/pdm/repository/SpigotRepository.java +++ b/pdm/src/main/java/me/bristermitten/pdm/repository/SpigotRepository.java @@ -1,7 +1,7 @@ package me.bristermitten.pdm.repository; import com.google.common.collect.ImmutableSet; -import me.bristermitten.pdmlibs.artifact.Artifact; +import me.bristermitten.pdmlibs.dependency.Dependency; import me.bristermitten.pdmlibs.http.HTTPService; import me.bristermitten.pdmlibs.pom.ParseProcess; import me.bristermitten.pdmlibs.repository.MavenRepository; @@ -9,7 +9,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Unmodifiable; -import java.util.*; +import java.util.Collections; +import java.util.Objects; +import java.util.Set; import java.util.logging.Logger; public final class SpigotRepository extends MavenRepository @@ -35,7 +37,7 @@ public final class SpigotRepository extends MavenRepository ).build(); private static final Logger LOGGER = Logger.getLogger("SpigotRepository"); - public SpigotRepository(@NotNull final HTTPService httpService, @NotNull final ParseProcess> parseProcess) + public SpigotRepository(@NotNull final HTTPService httpService, @NotNull final ParseProcess> parseProcess) { super(SPIGOT_ALIAS, httpService, parseProcess); } @@ -43,20 +45,20 @@ public SpigotRepository(@NotNull final HTTPService httpService, @NotNull final P @NotNull @Override - public Set getTransitiveDependencies(@NotNull final Artifact dependency) + public Set getTransitiveDependencies(@NotNull final Dependency dependency) { return Collections.emptySet(); } @Override - public boolean contains(@NotNull final Artifact artifact) + public boolean contains(@NotNull final Dependency dependency) { - return isSpigotDependency(artifact); + return isSpigotDependency(dependency); } @NotNull @Override - public byte @NotNull [] download(@NotNull final Artifact dependency) + public byte @NotNull [] download(@NotNull final Dependency dependency) { final String version = Bukkit.getVersion(); @@ -68,7 +70,7 @@ public boolean contains(@NotNull final Artifact artifact) return new byte[0]; } - private boolean isSpigotDependency(@NotNull final Artifact dependency) + private boolean isSpigotDependency(@NotNull final Dependency dependency) { return SPIGOT_DEPENDENCY_GROUPS.contains(dependency.getGroupId().toLowerCase()) && SPIGOT_DEPENDENCY_ARTIFACTS.contains(dependency.getArtifactId().toLowerCase()); diff --git a/pdm/src/main/java/me/bristermitten/pdm/util/ClassLoaderReflection.java b/pdm/src/main/java/me/bristermitten/pdm/util/ClassLoaderReflection.java deleted file mode 100644 index 393b4c4..0000000 --- a/pdm/src/main/java/me/bristermitten/pdm/util/ClassLoaderReflection.java +++ /dev/null @@ -1,48 +0,0 @@ -package me.bristermitten.pdm.util; - -import org.jetbrains.annotations.NotNull; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; - -public class ClassLoaderReflection -{ - - private static final Method ADD_URL_METHOD; - - static - { - final Method addURL; - - try - { - addURL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); - addURL.setAccessible(true); - } - catch (NoSuchMethodException exception) - { - throw new AssertionError(exception); - } - - ADD_URL_METHOD = addURL; - } - - private ClassLoaderReflection() - { - throw new AssertionError("This class cannot be instantiated."); - } - - public static void addURL(@NotNull final URLClassLoader classLoader, @NotNull final URL url) - { - try - { - ADD_URL_METHOD.invoke(classLoader, url); - } - catch (IllegalAccessException | InvocationTargetException exception) - { - throw new IllegalArgumentException(exception); - } - } -} diff --git a/pdm/src/test/java/me/bristermitten/pdm/SimpleTest.java b/pdm/src/test/java/me/bristermitten/pdm/SimpleTest.java index 669dc5b..d2c26e5 100644 --- a/pdm/src/test/java/me/bristermitten/pdm/SimpleTest.java +++ b/pdm/src/test/java/me/bristermitten/pdm/SimpleTest.java @@ -1,6 +1,6 @@ package me.bristermitten.pdm; -import me.bristermitten.pdmlibs.artifact.ReleaseArtifact; +import me.bristermitten.pdmlibs.dependency.ReleaseDependency; import org.junit.jupiter.api.Test; import java.io.IOException; @@ -18,7 +18,7 @@ public SimpleTest() throws IOException void simplePDMTest() { pdm.addRequiredDependency( - new ReleaseArtifact( + new ReleaseDependency( "org.jetbrains.kotlin", "kotlin-stdlib-jdk8", "1.3.72" @@ -36,7 +36,7 @@ void simplePDMTest() void simplePDMTest2() { pdm.addRequiredDependency( - new ReleaseArtifact( + new ReleaseDependency( "com.zaxxer", "HikariCP", "3.4.5" @@ -55,7 +55,7 @@ void simplePDMTest3() { pdm.addRepository("bintray", "https://jcenter.bintray.com"); pdm.addRequiredDependency( - new ReleaseArtifact( + new ReleaseDependency( "net.dv8tion", "JDA", "4.2.0_187"