// 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()); } }