| /* |
| * Copyright 2012-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.rules; |
| |
| import com.facebook.buck.model.BuildTarget; |
| import com.facebook.buck.model.BuildTargetPattern; |
| import com.google.common.annotations.VisibleForTesting; |
| import com.google.common.base.Function; |
| import com.google.common.base.Preconditions; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.ImmutableSortedSet; |
| import com.google.common.collect.Iterables; |
| import com.google.common.util.concurrent.Futures; |
| import com.google.common.util.concurrent.ListenableFuture; |
| |
| import java.io.File; |
| import java.io.IOException; |
| |
| import javax.annotation.Nullable; |
| |
| /** |
| * InputRule is a no-op BuildRule that encapsulates an input file. This encapsulation allows the |
| * entire dependency graph to deal with BuildRules, rather than having leaves of a different type. |
| */ |
| public class InputRule implements BuildRule { |
| |
| private static final BuildRuleSuccess.Type SUCCESS_TYPE = BuildRuleSuccess.Type.BY_DEFINITION; |
| |
| private final File inputFile; |
| private final BuildTarget buildTarget; |
| private final ListenableFuture<BuildRuleSuccess> buildOutput; |
| @Nullable private RuleKey ruleKey; |
| |
| /** |
| * It is imperative that {@code inputFile} be properly relativized, so use |
| * {@link #inputPathAsInputRule(String, Function)} to create an {@link InputRule}. The only reason |
| * this method is {@code protected} rather than {@code private} is so that fakes can be created |
| * for testing. |
| */ |
| @VisibleForTesting |
| protected InputRule(File inputFile, String relativePath) { |
| this.inputFile = Preconditions.checkNotNull(inputFile); |
| this.buildTarget = BuildTarget.createBuildTargetForInputFile(inputFile, relativePath); |
| this.buildOutput = Futures.immediateFuture(new BuildRuleSuccess(this, SUCCESS_TYPE)); |
| } |
| |
| public static InputRule inputPathAsInputRule(String relativePath, |
| Function<String, String> pathRelativizer) { |
| return Iterables.getOnlyElement( |
| inputPathsAsInputRules(ImmutableList.of(relativePath), pathRelativizer)); |
| } |
| |
| /** |
| * Convert a set of input file paths to InputRules. |
| */ |
| public static ImmutableSortedSet<InputRule> inputPathsAsInputRules(Iterable<String> paths, |
| Function<String, String> pathRelativizer) { |
| ImmutableSortedSet.Builder<InputRule> builder = ImmutableSortedSet.naturalOrder(); |
| for (String path : paths) { |
| builder.add(new InputRule(new File(pathRelativizer.apply(path)), path)); |
| } |
| return builder.build(); |
| } |
| |
| @Override |
| public BuildRuleSuccess.Type getBuildResultType() { |
| return SUCCESS_TYPE; |
| } |
| |
| @Nullable |
| @Override |
| public Buildable getBuildable() { |
| return null; |
| } |
| |
| @Override |
| public BuildTarget getBuildTarget() { |
| return buildTarget; |
| } |
| |
| @Override |
| public String getFullyQualifiedName() { |
| return buildTarget.getFullyQualifiedName(); |
| } |
| |
| @Override |
| public BuildRuleType getType() { |
| return BuildRuleType.INPUT; |
| } |
| |
| @Override |
| public BuildableProperties getProperties() { |
| return BuildableProperties.NONE; |
| } |
| |
| @Override |
| public ImmutableSortedSet<BuildRule> getDeps() { |
| return ImmutableSortedSet.of(); |
| } |
| |
| @Override |
| public ImmutableSet<BuildTargetPattern> getVisibilityPatterns() { |
| return ImmutableSet.of(BuildTargetPattern.MATCH_ALL); |
| } |
| |
| @Override |
| public boolean isVisibleTo(BuildTarget target) { |
| return true; |
| } |
| |
| @Override |
| public Iterable<InputRule> getInputs() { |
| return ImmutableList.of(); |
| } |
| |
| @Override |
| public ListenableFuture<BuildRuleSuccess> build(BuildContext context) { |
| return buildOutput; |
| } |
| |
| @Override |
| public boolean getExportDeps() { |
| return false; |
| } |
| |
| @Override |
| public RuleKey getRuleKey() throws IOException { |
| if (this.ruleKey == null) { |
| ruleKey = RuleKey.builder(this).set("inputFile", inputFile).build(); |
| } |
| return ruleKey; |
| } |
| |
| @Override |
| public int hashCode() { |
| return getFullyQualifiedName().hashCode(); |
| } |
| |
| @Override |
| public boolean equals(Object other) { |
| if (this == other) { |
| return true; |
| } |
| if (other == null || getClass() != other.getClass()) { |
| return false; |
| } |
| return (compareTo((InputRule) other) == 0); |
| } |
| |
| @Override |
| public int compareTo(BuildRule buildRule) { |
| return getFullyQualifiedName().compareTo(buildRule.getFullyQualifiedName()); |
| } |
| |
| @Override |
| public String toString() { |
| return getFullyQualifiedName(); |
| } |
| |
| @Override |
| public RuleKey getRuleKeyWithoutDeps() throws IOException { |
| throw new UnsupportedOperationException(); |
| } |
| } |