Created
January 14, 2026 12:13
-
-
Save basilevs/eabbfbbc4a141d87d1062268c7cc24b1 to your computer and use it in GitHub Desktop.
A script to get an URL of Maven artifact in a remote repository. Naive implementation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /******************************************************************************* | |
| * Copyright (c) 2025 Xored Software Inc and others. | |
| * All rights reserved. This program and the accompanying materials | |
| * are made available under the terms of the Eclipse Public License v2.0 | |
| * which accompanies this distribution, and is available at | |
| * https://www.eclipse.org/legal/epl-v20.html | |
| * | |
| * Contributors: | |
| * Xored Software Inc - initial API and implementation and/or initial documentation | |
| *******************************************************************************/ | |
| package com.example; | |
| import static java.util.Objects.requireNonNull; | |
| import java.io.IOException; | |
| import java.io.InputStream; | |
| import java.net.URI; | |
| import java.net.URL; | |
| import java.util.Arrays; | |
| import java.util.Iterator; | |
| import java.util.stream.Collectors; | |
| import java.util.stream.Stream; | |
| import javax.xml.parsers.DocumentBuilder; | |
| import javax.xml.parsers.DocumentBuilderFactory; | |
| import javax.xml.parsers.ParserConfigurationException; | |
| import javax.xml.xpath.XPath; | |
| import javax.xml.xpath.XPathConstants; | |
| import javax.xml.xpath.XPathExpressionException; | |
| import javax.xml.xpath.XPathFactory; | |
| import org.w3c.dom.Document; | |
| import org.w3c.dom.Node; | |
| import org.xml.sax.SAXException; | |
| public class ResolveMavenArtifact { | |
| private URI repository= URI.create("https://repo.eclipse.org/content/repositories/rcptt-snapshots/"); | |
| private String artifactId="agent-server-products", groupId="org.eclipse.rcptt.cloud", version, classifier="", extension="zip"; | |
| private enum Parameter { | |
| REPOSITORY { | |
| @Override | |
| void process(ResolveMavenArtifact configuration, Iterator<String> commandLine) { | |
| configuration.repository = URI.create(commandLine.next()); | |
| } | |
| }, | |
| GROUPID { | |
| @Override | |
| void process(ResolveMavenArtifact configuration, Iterator<String> commandLine) { | |
| configuration.groupId = consumeIdentifier(commandLine); | |
| } | |
| }, | |
| ARTIFACTID { | |
| @Override | |
| void process(ResolveMavenArtifact configuration, Iterator<String> commandLine) { | |
| configuration.artifactId = consumeIdentifier(commandLine); | |
| } | |
| }, | |
| VERSION { | |
| @Override | |
| void process(ResolveMavenArtifact configuration, Iterator<String> commandLine) { | |
| configuration.version = consumeIdentifier(commandLine); | |
| } | |
| }, | |
| CLASSIFIER { | |
| @Override | |
| void process(ResolveMavenArtifact configuration, Iterator<String> commandLine) { | |
| configuration.classifier = consumeIdentifier(commandLine); | |
| } | |
| }, | |
| EXTENSION { | |
| @Override | |
| void process(ResolveMavenArtifact configuration, Iterator<String> commandLine) { | |
| configuration.extension = consumeIdentifier(commandLine); | |
| } | |
| }; | |
| boolean matches(String argument) { | |
| return argument.contentEquals("--" + name().toLowerCase()) | |
| || argument.equals("-" + name().substring(0, 1).toLowerCase()); | |
| } | |
| abstract void process(ResolveMavenArtifact configuration, Iterator<String> commandLine); | |
| } | |
| public void parseCommandLine(Iterator<String> command) { | |
| while (command.hasNext()) { | |
| Parameter parameter = toParameter(command.next()); | |
| try { | |
| parameter.process(this, command); | |
| } catch (RuntimeException e) { | |
| throw new IllegalArgumentException("Failed to process parameter " + parameter, e); | |
| } | |
| } | |
| } | |
| public static void main(String[] args) throws IOException { | |
| ResolveMavenArtifact resolve = new ResolveMavenArtifact(); | |
| resolve.parseCommandLine(Arrays.asList(args).iterator()); | |
| URI result = resolve.resolveArtifact(); | |
| System.out.println(result); | |
| } | |
| private URI resolveArtifact() throws IOException { | |
| requireNonNull(artifactId, "artifactId"); | |
| requireNonNull(version, "version"); | |
| URI directory = repository.resolve(groupId.replace('.', '/')+"/").resolve(artifactId+"/").resolve(version+"/"); | |
| String resolvedVersion = version; | |
| if (version.endsWith("-SNAPSHOT")) { | |
| final URL url = directory.resolve("maven-metadata.xml").toURL(); | |
| try (var is = url.openStream()) { | |
| resolvedVersion = version.substring(0, version.length() - 8) + parseLatestSnapshot(is); | |
| } catch (SAXException e) { | |
| throw new IOException(e); | |
| } | |
| } | |
| String filename = artifactId + "-" + resolvedVersion + (classifier.isEmpty() ? "" : "-"+classifier) + "." + extension; | |
| return directory.resolve(filename); | |
| } | |
| public static String parseLatestSnapshot(InputStream input) throws IOException, SAXException { | |
| try { | |
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | |
| factory.setNamespaceAware(false); | |
| factory.setExpandEntityReferences(false); | |
| DocumentBuilder builder = factory.newDocumentBuilder(); | |
| Document document = builder.parse(input); | |
| Node snapshotNode = xpathNode(document, "/metadata/versioning/snapshot"); | |
| return Stream.of("timestamp", "buildNumber").map(p -> xpathNode(snapshotNode, p)).map(Node::getTextContent) | |
| .collect(Collectors.joining("-")); | |
| } catch (ParserConfigurationException e) { | |
| throw new AssertionError(e); | |
| } | |
| } | |
| private static Node xpathNode(Node origin, String expression) { | |
| XPath xpath = XPathFactory.newInstance().newXPath(); | |
| try { | |
| return (Node) xpath.evaluate(expression, origin, XPathConstants.NODE); | |
| } catch (XPathExpressionException e) { | |
| throw new IllegalArgumentException(e); | |
| } | |
| } | |
| private static String consumeIdentifier(Iterator<String> commandLine) { | |
| return commandLine.next(); | |
| } | |
| private static Parameter toParameter(String argument) { | |
| var matching = Arrays.stream(Parameter.values()).filter(p -> p.matches(argument)).toList(); | |
| if (matching.size() != 1) { | |
| throw new IllegalArgumentException( | |
| "Argument " + argument + " is ambigious. It matches parameters: " + matching); | |
| } | |
| return matching.getFirst(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment