// Copyright 2015 The Bazel Authors. All rights reserved.
//
// 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 com.google.devtools.build.workspace.maven;
import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.bazel.repository.MavenConnector;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import org.apache.maven.model.Exclusion;
import org.eclipse.aether.artifact.Artifact;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* A struct representing the fields of maven_jar to be written to the WORKSPACE file.
*/
public final class Rule implements Comparable<Rule> {
private final Artifact artifact;
private final Set<String> parents;
private final Set<String> exclusions;
private final Set<Rule> dependencies;
private String repository;
private String sha1;
public Rule(Artifact artifact) {
this.artifact = artifact;
this.parents = Sets.newHashSet();
this.dependencies = Sets.newTreeSet();
this.exclusions = Sets.newHashSet();
this.repository = MavenConnector.MAVEN_CENTRAL_URL;
}
public Rule(Artifact artifact, List<Exclusion> exclusions) {
this(artifact);
for (Exclusion exclusion : exclusions) {
String coord = String.format("%s:%s", exclusion.getGroupId(), exclusion.getArtifactId());
this.exclusions.add(coord);
}
}
public void addParent(String parent) {
parents.add(parent);
}
public void addDependency(Rule dependency) {
dependencies.add(dependency);
}
public Set<Rule> getDependencies() {
return dependencies;
}
public String artifactId() {
return artifact.getArtifactId();
}
public Set<String> getExclusions() {
return exclusions;
}
public String groupId() {
return artifact.getGroupId();
}
public String version() {
return artifact.getVersion();
}
/**
* A unique name for this artifact to use in maven_jar's name attribute.
*/
public String name() {
return Rule.name(groupId(), artifactId());
}
/**
* A unique name for this artifact to use in maven_jar's name attribute.
*/
public static String name(String groupId, String artifactId) {
return groupId.replaceAll("[.-]", "_") + "_" + artifactId.replaceAll("[.-]", "_");
}
public Artifact getArtifact() {
return artifact;
}
public String toMavenArtifactString() {
return groupId() + ":" + artifactId() + ":" + version();
}
public void setRepository(String url, EventHandler handler) {
// url is of the form repository/group/artifact/version/artifact-version.pom. Strip off
// everything after repository/.
int uriStart = url.indexOf(getUri());
if (uriStart == -1) {
// If url is actually a path to a file, it won't match the URL pattern described above.
// However, in that case we also have no way of fetching the artifact, so we'll print a
// warning.
handler.handle(Event.warn(name() + " was defined in " + url
+ " which isn't a repository URL, so we couldn't figure out how to fetch "
+ toMavenArtifactString() + " in a general way. You will need to set the \"repository\""
+ " attribute manually"));
} else {
this.repository = url.substring(0, uriStart);
}
}
public void setSha1(String sha1) {
this.sha1 = sha1;
}
private String getUri() {
return groupId().replaceAll("\\.", "/") + "/" + artifactId() + "/" + version() + "/"
+ artifactId() + "-" + version() + ".pom";
}
/**
* @return The artifact's URL.
*/
public String getUrl() {
Preconditions.checkState(repository.endsWith("/"));
return repository + getUri();
}
/**
* The way this jar should be stringified for the WORKSPACE file.
*/
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
for (String parent : parents) {
builder.append("# " + parent + "\n");
}
builder.append("maven_jar(\n"
+ " name = \"" + name() + "\",\n"
+ " artifact = \"" + toMavenArtifactString() + "\",\n"
+ (hasCustomRepository() ? " repository = \"" + repository + "\",\n" : "")
+ (sha1 != null ? " sha1 = \"" + sha1 + "\",\n" : "")
+ ")");
return builder.toString();
}
private boolean hasCustomRepository() {
return !MavenConnector.MAVEN_CENTRAL_URL.equals(repository);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Rule rule = (Rule) o;
return Objects.equals(groupId(), rule.groupId())
&& Objects.equals(artifactId(), rule.artifactId());
}
@Override
public int hashCode() {
return Objects.hash(groupId(), artifactId());
}
@Override
public int compareTo(Rule o) {
return name().compareTo(o.name());
}
}