com.facebook.buck.jvm.java.JavaBinaryDescription.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.buck.jvm.java.JavaBinaryDescription.java

Source

/*
 * Copyright 2014-present Facebook, Inc.
 *
 * 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.facebook.buck.jvm.java;

import com.facebook.buck.cxx.CxxPlatform;
import com.facebook.buck.cxx.CxxPlatforms;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.Flavor;
import com.facebook.buck.model.HasTests;
import com.facebook.buck.model.ImmutableFlavor;
import com.facebook.buck.parser.NoSuchBuildTargetException;
import com.facebook.buck.rules.AbstractDescriptionArg;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleParams;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.BuildTargetSourcePath;
import com.facebook.buck.rules.CellPathResolver;
import com.facebook.buck.rules.Description;
import com.facebook.buck.rules.Hint;
import com.facebook.buck.rules.ImplicitDepsInferringDescription;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.rules.SourcePathRuleFinder;
import com.facebook.buck.rules.TargetGraph;
import com.facebook.buck.versions.VersionRoot;
import com.facebook.infer.annotation.SuppressFieldNotInitialized;
import com.google.common.base.Preconditions;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;

import java.nio.file.Path;
import java.util.Optional;
import java.util.regex.Pattern;

public class JavaBinaryDescription implements Description<JavaBinaryDescription.Args>,
        ImplicitDepsInferringDescription<JavaBinaryDescription.Args>, VersionRoot<JavaBinaryDescription.Args> {

    private static final Flavor FAT_JAR_INNER_JAR_FLAVOR = ImmutableFlavor.of("inner-jar");

    private final JavacOptions javacOptions;
    private final CxxPlatform cxxPlatform;
    private final JavaOptions javaOptions;
    private final JavaBuckConfig javaBuckConfig;

    public JavaBinaryDescription(JavaOptions javaOptions, JavacOptions javacOptions, CxxPlatform cxxPlatform,
            JavaBuckConfig javaBuckConfig) {
        this.javaOptions = javaOptions;
        this.javacOptions = Preconditions.checkNotNull(javacOptions);
        this.cxxPlatform = Preconditions.checkNotNull(cxxPlatform);
        this.javaBuckConfig = Preconditions.checkNotNull(javaBuckConfig);
    }

    @Override
    public Args createUnpopulatedConstructorArg() {
        return new Args();
    }

    @Override
    public <A extends Args> BuildRule createBuildRule(TargetGraph targetGraph, BuildRuleParams params,
            BuildRuleResolver resolver, A args) throws NoSuchBuildTargetException {

        SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(resolver);
        SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
        ImmutableMap<String, SourcePath> nativeLibraries = JavaLibraryRules.getNativeLibraries(params.getDeps(),
                cxxPlatform);
        BuildRuleParams binaryParams = params;

        // If we're packaging native libraries, we'll build the binary JAR in a separate rule and
        // package it into the final fat JAR, so adjust it's params to use a flavored target.
        if (!nativeLibraries.isEmpty()) {
            binaryParams = params.copyWithChanges(
                    params.getBuildTarget().withAppendedFlavors(FAT_JAR_INNER_JAR_FLAVOR), params.getDeclaredDeps(),
                    params.getExtraDeps());
        }

        // Construct the build rule to build the binary JAR.
        ImmutableSet<JavaLibrary> transitiveClasspathDeps = JavaLibraryClasspathProvider
                .getClasspathDeps(binaryParams.getDeps());
        ImmutableSet<Path> transitiveClasspaths = JavaLibraryClasspathProvider
                .getClasspathsFromLibraries(transitiveClasspathDeps);
        BuildRule rule = new JavaBinary(binaryParams.appendExtraDeps(transitiveClasspathDeps), pathResolver,
                javaOptions.getJavaRuntimeLauncher(), args.mainClass.orElse(null), args.manifestFile.orElse(null),
                args.mergeManifests.orElse(true), args.metaInfDirectory.orElse(null), args.blacklist,
                transitiveClasspathDeps, transitiveClasspaths, javaBuckConfig.shouldCacheBinaries());

        // If we're packaging native libraries, construct the rule to build the fat JAR, which packages
        // up the original binary JAR and any required native libraries.
        if (!nativeLibraries.isEmpty()) {
            BuildRule innerJarRule = rule;
            resolver.addToIndex(innerJarRule);
            SourcePath innerJar = new BuildTargetSourcePath(innerJarRule.getBuildTarget());
            rule = new JarFattener(
                    params.appendExtraDeps(Suppliers.<Iterable<BuildRule>>ofInstance(
                            ruleFinder.filterBuildRuleInputs(ImmutableList.<SourcePath>builder().add(innerJar)
                                    .addAll(nativeLibraries.values()).build()))),
                    pathResolver, ruleFinder, javacOptions, innerJar, nativeLibraries,
                    javaOptions.getJavaRuntimeLauncher());
        }

        return rule;
    }

    @Override
    public Iterable<BuildTarget> findDepsForTargetFromConstructorArgs(BuildTarget buildTarget,
            CellPathResolver cellRoots, Args constructorArg) {
        return CxxPlatforms.getParseTimeDeps(cxxPlatform);
    }

    @Override
    public boolean isVersionRoot(ImmutableSet<Flavor> flavors) {
        return true;
    }

    @SuppressFieldNotInitialized
    public static class Args extends AbstractDescriptionArg implements HasTests {
        public ImmutableSortedSet<BuildTarget> deps = ImmutableSortedSet.of();
        public Optional<String> mainClass;
        public Optional<SourcePath> manifestFile;
        public Optional<Boolean> mergeManifests;
        public Optional<Path> metaInfDirectory;
        public ImmutableSet<Pattern> blacklist = ImmutableSet.of();
        @Hint(isDep = false)
        public ImmutableSortedSet<BuildTarget> tests = ImmutableSortedSet.of();

        @Override
        public ImmutableSortedSet<BuildTarget> getTests() {
            return tests;
        }

    }
}