// Copyright 2014 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 static java.util.Objects.requireNonNull; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; 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.rules.java.JavaRuleOutputJarsProvider.OutputJar; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.skylarkbuildapi.java.JavaRuleOutputJarsProviderApi; import com.google.devtools.build.lib.skylarkbuildapi.java.OutputJarApi; import com.google.devtools.build.lib.syntax.SkylarkList; import java.util.Collection; import java.util.stream.Collectors; import javax.annotation.Nullable; /** Provides information about jar files produced by a Java rule. */ @Immutable @AutoCodec public final class JavaRuleOutputJarsProvider implements TransitiveInfoProvider, JavaRuleOutputJarsProviderApi { public static final JavaRuleOutputJarsProvider EMPTY = new JavaRuleOutputJarsProvider( ImmutableList.of(), /* jdeps= */ null, /* nativeHeaders= */ null); /** A collection of artifacts associated with a jar output. */ @Immutable @AutoCodec public static class OutputJar implements OutputJarApi { @Nullable private final Artifact classJar; @Nullable private final Artifact iJar; @Nullable private final Artifact manifestProto; @Nullable private final ImmutableList srcJars; public OutputJar( @Nullable Artifact classJar, @Nullable Artifact iJar, @Nullable Artifact manifestProto, @Nullable Iterable srcJars) { this.classJar = classJar; this.iJar = iJar; this.manifestProto = manifestProto; this.srcJars = ImmutableList.copyOf(srcJars); } @Nullable @Override public Artifact getClassJar() { return classJar; } @Nullable @Override public Artifact getIJar() { return iJar; } @Nullable @Override public Artifact getManifestProto() { return manifestProto; } @Nullable @Override public Artifact getSrcJar() { return Iterables.getOnlyElement(srcJars, null); } @Nullable @Override public SkylarkList getSrcJarsSkylark() { return SkylarkList.createImmutable(srcJars); } public Iterable getSrcJars() { return srcJars; } } final ImmutableList outputJars; @Nullable final Artifact jdeps; /** An archive of native header files. */ @Nullable final Artifact nativeHeaders; private JavaRuleOutputJarsProvider( ImmutableList outputJars, @Nullable Artifact jdeps, @Nullable Artifact nativeHeaders) { this.outputJars = outputJars; this.jdeps = jdeps; this.nativeHeaders = nativeHeaders; } @AutoCodec.VisibleForSerialization @AutoCodec.Instantiator static JavaRuleOutputJarsProvider create( ImmutableList outputJars, @Nullable Artifact jdeps, @Nullable Artifact nativeHeaders) { if (outputJars.isEmpty() && jdeps == null && nativeHeaders == null) { return EMPTY; } return new JavaRuleOutputJarsProvider(outputJars, jdeps, nativeHeaders); } @Override public ImmutableList getOutputJars() { return outputJars; } /** * Collects all class output jars from {@link #outputJars} */ public Iterable getAllClassOutputJars() { return outputJars.stream().map(OutputJar::getClassJar).collect(Collectors.toList()); } /** * Collects all source output jars from {@link #outputJars} */ public Iterable getAllSrcOutputJars() { return outputJars .stream() .map(OutputJar::getSrcJars) .reduce(ImmutableList.of(), Iterables::concat); } @Nullable @Override public Artifact getJdeps() { return jdeps; } @Nullable @Override public Artifact getNativeHeaders() { return nativeHeaders; } public static Builder builder() { return new Builder(); } public static JavaRuleOutputJarsProvider merge( Collection providers) { Builder builder = new Builder(); for (JavaRuleOutputJarsProvider provider : providers) { builder.addOutputJars(provider.getOutputJars()); } return builder.build(); } /** * Builder for {@link JavaRuleOutputJarsProvider}. */ public static class Builder { private final ImmutableList.Builder outputJars = ImmutableList.builder(); private Artifact jdeps; private Artifact nativeHeaders; public Builder addOutputJar( @Nullable Artifact classJar, @Nullable Artifact iJar, @Nullable Artifact manifestProto, @Nullable ImmutableList sourceJars) { Preconditions.checkState(classJar != null || iJar != null || !sourceJars.isEmpty()); outputJars.add(new OutputJar(classJar, iJar, manifestProto, sourceJars)); return this; } public Builder addOutputJar(OutputJar outputJar) { outputJars.add(outputJar); return this; } public Builder addOutputJars(Iterable outputJars) { this.outputJars.addAll(outputJars); return this; } public Builder setJdeps(Artifact jdeps) { this.jdeps = jdeps; return this; } public Builder setNativeHeaders(Artifact nativeHeaders) { this.nativeHeaders = requireNonNull(nativeHeaders); return this; } public JavaRuleOutputJarsProvider build() { return new JavaRuleOutputJarsProvider(outputJars.build(), jdeps, nativeHeaders); } } }