io.hawt.aether.MavenURL Maven / Gradle / Ivy
/**
* Copyright (C) 2013 the original author or authors.
* See the notice.md file distributed with this work for additional
* information regarding copyright ownership.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.hawt.aether;
/**
* Copyright 2005-2014 Red Hat, Inc.
*
* Red Hat licenses this file to you under the Apache License, version
* 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
import java.net.MalformedURLException;
/**
* Parser for mvn: protocol.
*/
public class MavenURL {
/**
* Syntax for the url; to be shown on exception messages.
*/
private static final String SYNTAX = "mvn:[repository_url!]groupId/artifactId[/[version]/[type]]";
/**
* Separator between repository and artifact definition.
*/
private static final String REPOSITORY_SEPARATOR = "!";
/**
* Artifact definition segments separator.
*/
private static final String ARTIFACT_SEPARATOR = "/";
/**
* Default version if none present in the url.
*/
private static final String VERSION_LATEST = "LATEST";
/**
* Snapshot version
*/
private static final String VERSION_SNAPSHOT = "SNAPSHOT";
/**
* Default type if not present in the url.
*/
private static final String TYPE_JAR = "jar";
/**
* Final artifact path separator.
*/
public static final String FILE_SEPARATOR = "/";
/**
* Group id path separator.
*/
private static final String GROUP_SEPARATOR = "\\.";
/**
* Separator used to constructs the artifact file name.
*/
private static final String VERSION_SEPARATOR = "-";
/**
* Artifact extension(type) separator.
*/
private static final String TYPE_SEPARATOR = ".";
/**
* Separator used to separate classifier in artifact name.
*/
private static final String CLASSIFIER_SEPARATOR = "-";
/**
* Maven metadata file.
*/
private static final String METADATA_FILE = "maven-metadata.xml";
/**
* Maven local metadata file.
*/
private static final String METADATA_FILE_LOCAL = "maven-metadata-local.xml";
/**
* Repository URL. Null if not present.
*/
private MavenRepositoryURL m_repositoryURL;
/**
* Artifact group id.
*/
private String m_group;
/**
* Artifact id.
*/
private String m_artifact;
/**
* Artifact version.
*/
private String m_version;
/**
* Artifact type.
*/
private String m_type;
/**
* Artifact classifier.
*/
private String m_classifier;
/**
* Artifact classifier to use to build artifact name.
*/
private String m_fullClassifier;
/**
* Lets trim any kind of "mvn:" prefix before parsing
*/
public static MavenURL parsePathWithSchemePrefix(String location) throws MalformedURLException {
String withoutMvnPrefix = location;
boolean done = false;
while (!done) {
int idx = withoutMvnPrefix.indexOf(':');
if (idx >= 0) {
withoutMvnPrefix = withoutMvnPrefix.substring(idx + 1);
}
// there may be a inlined maven repo location (assuming http), so we are done if we find that
if (withoutMvnPrefix.startsWith("http:") || withoutMvnPrefix.startsWith("https:")) {
done = true;
} else if (withoutMvnPrefix.indexOf(':') < 0) {
done = true;
}
}
return new MavenURL(withoutMvnPrefix);
}
/**
* Creates a new protocol parser.
*
* @param path the path part of the url (without starting mvn:)
* @throws MalformedURLException if provided path does not comply to expected syntax or an malformed repository URL
*/
public MavenURL(final String path)
throws MalformedURLException {
if (path == null) {
throw new MalformedURLException("Path cannot be null. Syntax " + SYNTAX);
}
if (path.startsWith(REPOSITORY_SEPARATOR) || path.endsWith(REPOSITORY_SEPARATOR)) {
throw new MalformedURLException(
"Path cannot start or end with " + REPOSITORY_SEPARATOR + ". Syntax " + SYNTAX
);
}
if (path.contains(REPOSITORY_SEPARATOR)) {
int pos = path.lastIndexOf(REPOSITORY_SEPARATOR);
String artifact = path.substring(pos + 1);
String url = path.substring(0, pos);
parseArtifactPart(artifact);
m_repositoryURL = new MavenRepositoryURL(url);
} else {
parseArtifactPart(path);
}
}
/**
* Parses the artifact part of the url ( without the repository).
*
* @param part url part without protocol and repository.
* @throws MalformedURLException if provided path does not comply to syntax.
*/
private void parseArtifactPart(final String part)
throws MalformedURLException {
String[] segments = part.split(ARTIFACT_SEPARATOR);
if (segments.length < 2) {
throw new MalformedURLException("Invalid path. Syntax " + SYNTAX);
}
// we must have a valid group
m_group = segments[0];
if (m_group.trim().length() == 0) {
throw new MalformedURLException("Invalid groupId. Syntax " + SYNTAX);
}
// valid artifact
m_artifact = segments[1];
if (m_artifact.trim().length() == 0) {
throw new MalformedURLException("Invalid artifactId. Syntax " + SYNTAX);
}
// version is optional but we have a default value
m_version = VERSION_LATEST;
if (segments.length >= 3 && segments[2].trim().length() > 0) {
m_version = segments[2];
}
// type is optional but we have a default value
m_type = TYPE_JAR;
if (segments.length >= 4 && segments[3].trim().length() > 0) {
m_type = segments[3];
}
// classifier is optional (if not pressent or empty we will have a null classsifier
m_fullClassifier = "";
if (segments.length >= 5 && segments[4].trim().length() > 0) {
m_classifier = segments[4];
m_fullClassifier = CLASSIFIER_SEPARATOR + m_classifier;
}
}
/**
* Returns the repository URL if present, null otherwise
*
* @return repository URL
*/
public MavenRepositoryURL getRepositoryURL() {
return m_repositoryURL;
}
/**
* Returns the group id of the artifact.
*
* @return group Id
*/
public String getGroup() {
return m_group;
}
/**
* Returns the artifact id.
*
* @return artifact id
*/
public String getArtifact() {
return m_artifact;
}
/**
* Returns the artifact version.
*
* @return version
*/
public String getVersion() {
return m_version;
}
/**
* Returns the artifact type.
*
* @return type
*/
public String getType() {
return m_type;
}
/**
* Returns the artifact classifier.
*
* @return classifier
*/
public String getClassifier() {
return m_classifier;
}
/**
* Returns the complete path to artifact as stated by Maven 2 repository layout.
*
* @return artifact path
*/
public String getArtifactPath() {
return getArtifactPath(m_version);
}
/**
* Returns the complete path to artifact as stated by Maven 2 repository layout.
*
* @param version The version of the artifact.
* @return artifact path
*/
public String getArtifactPath(final String version) {
return new StringBuilder()
.append(m_group.replaceAll(GROUP_SEPARATOR, FILE_SEPARATOR))
.append(FILE_SEPARATOR)
.append(m_artifact)
.append(FILE_SEPARATOR)
.append(version)
.append(FILE_SEPARATOR)
.append(m_artifact)
.append(VERSION_SEPARATOR)
.append(version)
.append(m_fullClassifier)
.append(TYPE_SEPARATOR)
.append(m_type)
.toString();
}
/**
* Returns the version for an artifact for a snapshot version.
*
* @param version The version of the snapshot.
* @param timestamp The timestamp of the snapshot.
* @param buildnumber The buildnumber of the snapshot.
* @return artifact path
*/
public String getSnapshotVersion(final String version, final String timestamp, final String buildnumber) {
return version.replace(VERSION_SNAPSHOT, timestamp) + VERSION_SEPARATOR + buildnumber;
}
/**
* Returns the complete path to artifact for a snapshot file.
*
* @param version The version of the snapshot.
* @param timestamp The timestamp of the snapshot.
* @param buildnumber The buildnumber of the snapshot.
* @return artifact path
*/
public String getSnapshotPath(final String version, final String timestamp, final String buildnumber) {
return new StringBuilder()
.append(m_group.replaceAll(GROUP_SEPARATOR, FILE_SEPARATOR))
.append(FILE_SEPARATOR)
.append(m_artifact)
.append(FILE_SEPARATOR)
.append(version)
.append(FILE_SEPARATOR)
.append(m_artifact)
.append(VERSION_SEPARATOR)
.append(getSnapshotVersion(version, timestamp, buildnumber))
.append(m_fullClassifier)
.append(TYPE_SEPARATOR)
.append(m_type)
.toString();
}
/**
* Returns the path to metdata file corresponding to this artifact version.
*
* @param version The version of the the metadata.
* @return metadata file path
*/
public String getVersionMetadataPath(final String version) {
return new StringBuilder()
.append(m_group.replaceAll(GROUP_SEPARATOR, FILE_SEPARATOR))
.append(FILE_SEPARATOR)
.append(m_artifact)
.append(FILE_SEPARATOR)
.append(version)
.append(FILE_SEPARATOR)
.append(METADATA_FILE)
.toString();
}
/**
* Returns the path to local metdata file corresponding to this artifact version.
*
* @param version The version of the the metadata.
* @return metadata file path
*/
public String getVersionLocalMetadataPath(final String version) {
return new StringBuilder()
.append(m_group.replaceAll(GROUP_SEPARATOR, FILE_SEPARATOR))
.append(FILE_SEPARATOR)
.append(m_artifact)
.append(FILE_SEPARATOR)
.append(version)
.append(FILE_SEPARATOR)
.append(METADATA_FILE_LOCAL)
.toString();
}
/**
* Returns the complete path to artifact local metadata file.
*
* @return artifact path
*/
public String getArtifactLocalMetdataPath() {
return new StringBuilder()
.append(m_group.replaceAll(GROUP_SEPARATOR, FILE_SEPARATOR))
.append(FILE_SEPARATOR)
.append(m_artifact)
.append(FILE_SEPARATOR)
.append(METADATA_FILE_LOCAL)
.toString();
}
/**
* Returns the complete path to artifact metadata file.
*
* @return artifact path
*/
public String getArtifactMetdataPath() {
return new StringBuilder()
.append(m_group.replaceAll(GROUP_SEPARATOR, FILE_SEPARATOR))
.append(FILE_SEPARATOR)
.append(m_artifact)
.append(FILE_SEPARATOR)
.append(METADATA_FILE)
.toString();
}
}