/* * Copyright 2016-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.query; import com.facebook.buck.model.BuildTarget; import com.facebook.buck.rules.BuildTargetSourcePath; import com.facebook.buck.rules.PathSourcePath; import com.facebook.buck.rules.SourcePath; import com.facebook.buck.rules.TargetNode; import com.facebook.buck.rules.coercer.CoercedTypeCache; import com.facebook.buck.rules.coercer.DefaultTypeCoercerFactory; import com.facebook.buck.rules.coercer.ParamInfo; import com.facebook.buck.rules.coercer.TypeCoercerFactory; import com.facebook.buck.util.HumanReadableException; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import java.nio.file.Path; public class QueryTargetAccessor { private static final TypeCoercerFactory typeCoercerFactory = new DefaultTypeCoercerFactory(); private QueryTargetAccessor() {} public static <T> ImmutableSet<QueryTarget> getTargetsInAttribute( TargetNode<T, ?> node, String attribute) { Class<?> constructorArgClass = node.getConstructorArg().getClass(); ParamInfo info = CoercedTypeCache.INSTANCE .getAllParamInfo(typeCoercerFactory, constructorArgClass) .get(attribute); if (info == null) { // Ignore if the field does not exist in this rule. return ImmutableSet.of(); } final ImmutableSet.Builder<QueryTarget> builder = ImmutableSortedSet.naturalOrder(); info.traverse( value -> { if (value instanceof Path) { builder.add(QueryFileTarget.of((Path) value)); } else if (value instanceof SourcePath) { builder.add(extractSourcePath((SourcePath) value)); } else if (value instanceof BuildTarget) { builder.add(extractBuildTargetContainer((BuildTarget) value)); } }, node.getConstructorArg()); return builder.build(); } /** Filters the objects in the given attribute that satisfy the given predicate. */ public static <T> ImmutableSet<Object> filterAttributeContents( TargetNode<T, ?> node, String attribute, final Predicate<Object> predicate) { Class<?> constructorArgClass = node.getConstructorArg().getClass(); ParamInfo info = CoercedTypeCache.INSTANCE .getAllParamInfo(typeCoercerFactory, constructorArgClass) .get(attribute); if (info == null) { // Ignore if the field does not exist in this rule. return ImmutableSet.of(); } final ImmutableSet.Builder<Object> builder = ImmutableSet.builder(); info.traverse( value -> { if (predicate.apply(value)) { builder.add(value); } }, node.getConstructorArg()); return builder.build(); } public static QueryTarget extractSourcePath(SourcePath sourcePath) { if (sourcePath instanceof PathSourcePath) { return QueryFileTarget.of(((PathSourcePath) sourcePath).getRelativePath()); } else if (sourcePath instanceof BuildTargetSourcePath) { return QueryBuildTarget.of(((BuildTargetSourcePath) sourcePath).getTarget()); } throw new HumanReadableException("Unsupported source path type: %s", sourcePath.getClass()); } public static QueryTarget extractBuildTargetContainer(BuildTarget buildTargetContainer) { return QueryBuildTarget.of(buildTargetContainer); } }