diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/util/FileType.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/util/FileType.java | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/util/FileType.java b/src/main/java/com/google/devtools/build/lib/util/FileType.java new file mode 100644 index 0000000000..c91b17b60b --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/util/FileType.java @@ -0,0 +1,278 @@ +// Copyright 2014 Google Inc. 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.util; + +import com.google.common.base.Preconditions; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.PathFragment; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.annotation.concurrent.Immutable; + +/** + * A base class for FileType matchers. + */ +@Immutable +public abstract class FileType implements Predicate<String> { + // A special file type + public static final FileType NO_EXTENSION = new FileType() { + @Override + public boolean apply(String filename) { + return filename.lastIndexOf('.') == -1; + } + }; + + public static FileType of(final String ext) { + return new FileType() { + @Override + public boolean apply(String filename) { + return filename.endsWith(ext); + } + @Override + public List<String> getExtensions() { + return ImmutableList.of(ext); + } + }; + } + + public static FileType of(final Iterable<String> extensions) { + return new FileType() { + @Override + public boolean apply(String filename) { + for (String ext : extensions) { + if (filename.endsWith(ext)) { + return true; + } + } + return false; + } + @Override + public List<String> getExtensions() { + return ImmutableList.copyOf(extensions); + } + }; + } + + public static FileType of(final String... extensions) { + return of(Arrays.asList(extensions)); + } + + @Override + public String toString() { + return getExtensions().toString(); + } + + /** + * Returns true if the the filename matches. The filename should be a basename (the filename + * component without a path) for performance reasons. + */ + @Override + public abstract boolean apply(String filename); + + /** + * Get a list of filename extensions this matcher handles. The first entry in the list (if + * available) is the primary extension that code can use to construct output file names. + * The list can be empty for some matchers. + * + * @return a list of filename extensions + */ + public List<String> getExtensions() { + return ImmutableList.of(); + } + + /** Return true if a file name is matched by the FileType */ + public boolean matches(String filename) { + int slashIndex = filename.lastIndexOf('/'); + if (slashIndex != -1) { + filename = filename.substring(slashIndex + 1); + } + return apply(filename); + } + + /** Return true if a file referred by path is matched by the FileType */ + public boolean matches(Path path) { + return apply(path.getBaseName()); + } + + /** Return true if a file referred by fragment is matched by the FileType */ + public boolean matches(PathFragment fragment) { + return apply(fragment.getBaseName()); + } + + // Check FileTypes + + /** + * An interface for entities that have a filename. + */ + public interface HasFilename { + /** + * Returns the filename of this entity. + */ + String getFilename(); + } + + /** + * Checks whether an Iterable<? extends HasFileType> contains any of the specified file types. + * + * <p>At least one FileType must be specified. + */ + public static <T extends HasFilename> boolean contains(final Iterable<T> items, + FileType... fileTypes) { + Preconditions.checkState(fileTypes.length > 0, "Must specify at least one file type"); + final FileTypeSet fileTypeSet = FileTypeSet.of(fileTypes); + for (T item : items) { + if (fileTypeSet.matches(item.getFilename())) { + return true; + } + } + return false; + } + + /** + * Checks whether a HasFileType is any of the specified file types. + * + * <p>At least one FileType must be specified. + */ + public static <T extends HasFilename> boolean contains(T item, FileType... fileTypes) { + return FileTypeSet.of(fileTypes).matches(item.getFilename()); + } + + + private static <T extends HasFilename> Predicate<T> typeMatchingPredicateFor( + final FileType matchingType) { + return new Predicate<T>() { + @Override + public boolean apply(T item) { + return matchingType.matches(item.getFilename()); + } + }; + } + + private static <T extends HasFilename> Predicate<T> typeMatchingPredicateFor( + final FileTypeSet matchingTypes) { + return new Predicate<T>() { + @Override + public boolean apply(T item) { + return matchingTypes.matches(item.getFilename()); + } + }; + } + + private static <T extends HasFilename> Predicate<T> typeMatchingPredicateFrom( + final Predicate<String> fileTypePredicate) { + return new Predicate<T>() { + @Override + public boolean apply(T item) { + return fileTypePredicate.apply(item.getFilename()); + } + }; + } + + /** + * A filter for Iterable<? extends HasFileType> that returns only those whose FileType matches the + * specified Predicate. + */ + public static <T extends HasFilename> Iterable<T> filter(final Iterable<T> items, + final Predicate<String> predicate) { + return Iterables.filter(items, typeMatchingPredicateFrom(predicate)); + } + + /** + * A filter for Iterable<? extends HasFileType> that returns only those of the specified file + * types. + */ + public static <T extends HasFilename> Iterable<T> filter(final Iterable<T> items, + FileType... fileTypes) { + return filter(items, FileTypeSet.of(fileTypes)); + } + + /** + * A filter for Iterable<? extends HasFileType> that returns only those of the specified file + * types. + */ + public static <T extends HasFilename> Iterable<T> filter(final Iterable<T> items, + FileTypeSet fileTypes) { + return Iterables.filter(items, typeMatchingPredicateFor(fileTypes)); + } + + /** + * A filter for Iterable<? extends HasFileType> that returns only those of the specified file + * type. + */ + public static <T extends HasFilename> Iterable<T> filter(final Iterable<T> items, + FileType fileType) { + return Iterables.filter(items, typeMatchingPredicateFor(fileType)); + } + + /** + * A filter for Iterable<? extends HasFileType> that returns everything except the specified file + * type. + */ + public static <T extends HasFilename> Iterable<T> except(final Iterable<T> items, + FileType fileType) { + return Iterables.filter(items, Predicates.not(typeMatchingPredicateFor(fileType))); + } + + + /** + * A filter for List<? extends HasFileType> that returns only those of the specified file types. + * The result is a mutable list, computed eagerly; see {@link #filter} for a lazy variant. + */ + public static <T extends HasFilename> List<T> filterList(final Iterable<T> items, + FileType... fileTypes) { + if (fileTypes.length > 0) { + return filterList(items, FileTypeSet.of(fileTypes)); + } else { + return new ArrayList<>(); + } + } + + /** + * A filter for List<? extends HasFileType> that returns only those of the specified file type. + * The result is a mutable list, computed eagerly. + */ + public static <T extends HasFilename> List<T> filterList(final Iterable<T> items, + final FileType fileType) { + List<T> result = new ArrayList<>(); + for (T item : items) { + if (fileType.matches(item.getFilename())) { + result.add(item); + } + } + return result; + } + + /** + * A filter for List<? extends HasFileType> that returns only those of the specified file types. + * The result is a mutable list, computed eagerly. + */ + public static <T extends HasFilename> List<T> filterList(final Iterable<T> items, + final FileTypeSet fileTypeSet) { + List<T> result = new ArrayList<>(); + for (T item : items) { + if (fileTypeSet.matches(item.getFilename())) { + result.add(item); + } + } + return result; + } +} |