blob: b910c825be6d289a790c7a95672c310253603520 [file] [log] [blame]
// 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.lib.rules.java;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.Collection;
import java.util.Map;
/** A Provider describing the java sources directly belonging to a java rule. */
@Immutable
@AutoCodec
public final class JavaSourceInfoProvider implements TransitiveInfoProvider {
private final Collection<Artifact> sourceFiles;
private final Collection<Artifact> sourceJars;
private final Collection<Artifact> jarFiles;
private final Collection<Artifact> sourceJarsForJarFiles;
private final Map<PathFragment, Artifact> resources;
@VisibleForSerialization
JavaSourceInfoProvider(
Collection<Artifact> sourceFiles,
Collection<Artifact> sourceJars,
Collection<Artifact> jarFiles,
Collection<Artifact> sourceJarsForJarFiles,
Map<PathFragment, Artifact> resources) {
this.sourceFiles = sourceFiles;
this.sourceJars = sourceJars;
this.jarFiles = jarFiles;
this.sourceJarsForJarFiles = sourceJarsForJarFiles;
this.resources = resources;
}
/** Gets the original Java source files provided as inputs to this rule. */
public Collection<Artifact> getSourceFiles() {
return sourceFiles;
}
/**
* Gets the original source jars provided as inputs to this rule.
*
* <p>These should contain Java source files, but can contain other files as well.
*/
public Collection<Artifact> getSourceJars() {
return sourceJars;
}
/**
* Gets the original pre-built jars provided as inputs to this rule.
*
* <p>These should be used where .class files are needed or wanted in place of recompiling the
* sources from {@link #getSourceJarsForJarFiles()}, as this is the source of truth used by the
* normal Java machinery.
*/
public Collection<Artifact> getJarFiles() {
return jarFiles;
}
/**
* Gets the source jars containing the sources of the jars contained in {@link #getJarFiles}.
*
* <p>These should be used in place of {@link #getJarFiles()} if and only if source is required.
*/
public Collection<Artifact> getSourceJarsForJarFiles() {
return sourceJarsForJarFiles;
}
/**
* Gets the Java resources which were included in this rule's output.
*
* <p>Each key in the map (a path within the jar) should correspond to the artifact which belongs
* at that path. The path fragment should be some suffix of the artifact's exec path.
*/
public Map<PathFragment, Artifact> getResources() {
return resources;
}
/**
* Constructs a JavaSourceInfoProvider using the sources in the given JavaTargetAttributes.
*
* @param attributes the object from which to draw the sources
* @param semantics semantics used to find the path for a resource within the jar
*/
public static JavaSourceInfoProvider fromJavaTargetAttributes(
JavaTargetAttributes attributes, JavaSemantics semantics) {
return new Builder()
.setSourceFiles(attributes.getSourceFiles())
.setSourceJars(attributes.getSourceJars())
.setResources(attributes.getResources())
.build();
}
public static JavaSourceInfoProvider merge(Collection<JavaSourceInfoProvider> sourceInfos) {
JavaSourceInfoProvider.Builder javaSourceInfo = new JavaSourceInfoProvider.Builder();
ImmutableList.Builder<Artifact> jarFiles = new ImmutableList.Builder<>();
ImmutableMap.Builder<PathFragment, Artifact> resources = new ImmutableMap.Builder<>();
ImmutableList.Builder<Artifact> sourceFiles = new ImmutableList.Builder<>();
ImmutableList.Builder<Artifact> sourceJars = new ImmutableList.Builder<>();
ImmutableList.Builder<Artifact> sourceJarsForJarFiles = new ImmutableList.Builder<>();
for (JavaSourceInfoProvider sourceInfo : sourceInfos) {
jarFiles.addAll(sourceInfo.getJarFiles());
resources.putAll(sourceInfo.getResources());
sourceFiles.addAll(sourceInfo.getSourceFiles());
sourceJars.addAll(sourceInfo.getSourceJars());
sourceJarsForJarFiles.addAll(sourceInfo.getSourceJarsForJarFiles());
}
javaSourceInfo.setJarFiles(jarFiles.build());
javaSourceInfo.setResources(resources.build());
javaSourceInfo.setSourceFiles(sourceFiles.build());
javaSourceInfo.setSourceJars(sourceJars.build());
javaSourceInfo.setSourceJarsForJarFiles(sourceJarsForJarFiles.build());
return javaSourceInfo.build();
}
/** Builder class for constructing JavaSourceInfoProviders. */
public static final class Builder {
private Collection<Artifact> sourceFiles = ImmutableList.<Artifact>of();
private Collection<Artifact> sourceJars = ImmutableList.<Artifact>of();
private Collection<Artifact> jarFiles = ImmutableList.<Artifact>of();
private Collection<Artifact> sourceJarsForJarFiles = ImmutableList.<Artifact>of();
private Map<PathFragment, Artifact> resources = ImmutableMap.<PathFragment, Artifact>of();
/** Sets the source files included as part of the sources of this rule. */
public Builder setSourceFiles(Collection<Artifact> sourceFiles) {
this.sourceFiles = Preconditions.checkNotNull(sourceFiles);
return this;
}
/** Sets the source jars included as part of the sources of this rule. */
public Builder setSourceJars(Collection<Artifact> sourceJars) {
this.sourceJars = Preconditions.checkNotNull(sourceJars);
return this;
}
/** Sets the pre-built jar files included as part of the sources of this rule. */
public Builder setJarFiles(Collection<Artifact> jarFiles) {
this.jarFiles = Preconditions.checkNotNull(jarFiles);
return this;
}
/**
* Sets the source jars corresponding to the jar files included in this rule.
*
* <p>Used by, e.g., the srcjars attribute of {@link JavaImport}.
*/
public Builder setSourceJarsForJarFiles(Collection<Artifact> sourceJarsForJarFiles) {
this.sourceJarsForJarFiles = Preconditions.checkNotNull(sourceJarsForJarFiles);
return this;
}
/**
* Sets the resources included in this rule.
*
* <p>Each key in the map (a path within the jar) should correspond to the artifact which
* belongs at that path. The path fragment should be some tail of the artifact's exec path.
*/
public Builder setResources(Map<PathFragment, Artifact> resources) {
this.resources = Preconditions.checkNotNull(resources);
return this;
}
/** Constructs the JavaSourceInfoProvider from the provided Java sources. */
public JavaSourceInfoProvider build() {
return new JavaSourceInfoProvider(
sourceFiles, sourceJars, jarFiles, sourceJarsForJarFiles, resources);
}
}
}