/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.brooklyn.util.text; import java.io.Serializable; import java.util.Arrays; import java.util.List; import java.util.Set; import javax.annotation.Nullable; import org.apache.brooklyn.util.collections.MutableSet; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; public class StringPredicates { /** predicate form of {@link Strings#isBlank(CharSequence)} */ public static <T extends CharSequence> Predicate<T> isBlank() { return new IsBlank<T>(); } private static final class IsBlank<T extends CharSequence> implements Predicate<T> { @Override public boolean apply(@Nullable CharSequence input) { return Strings.isBlank(input); } @Override public String toString() { return "isBlank()"; } } /** @deprecated since 0.7.0 kept only to allow conversion of anonymous inner classes */ @SuppressWarnings("unused") @Deprecated private static Predicate<CharSequence> isBlankOld() { return new Predicate<CharSequence>() { @Override public boolean apply(@Nullable CharSequence input) { return Strings.isBlank(input); } @Override public String toString() { return "isBlank"; } }; } /** Tests if object is non-null and not a blank string. * <p> * Predicate form of {@link Strings#isNonBlank(CharSequence)} also accepting objects non-null, for convenience */ public static <T> Predicate<T> isNonBlank() { return new IsNonBlank<T>(); } private static final class IsNonBlank<T> implements Predicate<T> { @Override public boolean apply(@Nullable Object input) { if (input==null) return false; if (!(input instanceof CharSequence)) return true; return Strings.isNonBlank((CharSequence)input); } @Override public String toString() { return "isNonBlank()"; } } // ----------------- public static <T extends CharSequence> Predicate<T> containsLiteralIgnoreCase(final String fragment) { return new ContainsLiteralIgnoreCase<T>(fragment); } private static final class ContainsLiteralIgnoreCase<T extends CharSequence> implements Predicate<T> { private final String fragment; private ContainsLiteralIgnoreCase(String fragment) { this.fragment = fragment; } @Override public boolean apply(@Nullable CharSequence input) { return Strings.containsLiteralIgnoreCase(input, fragment); } @Override public String toString() { return "containsLiteralCaseInsensitive("+fragment+")"; } } public static <T extends CharSequence> Predicate<T> containsLiteral(final String fragment) { return new ContainsLiteral<T>(fragment); } private static final class ContainsLiteral<T extends CharSequence> implements Predicate<T> { private final String fragment; private ContainsLiteral(String fragment) { this.fragment = fragment; } @Override public boolean apply(@Nullable CharSequence input) { return Strings.containsLiteral(input, fragment); } @Override public String toString() { return "containsLiteral("+fragment+")"; } } /** @deprecated since 0.7.0 kept only to allow conversion of anonymous inner classes */ @SuppressWarnings("unused") @Deprecated private static Predicate<CharSequence> containsLiteralCaseInsensitiveOld(final String fragment) { return new Predicate<CharSequence>() { @Override public boolean apply(@Nullable CharSequence input) { return Strings.containsLiteralIgnoreCase(input, fragment); } @Override public String toString() { return "containsLiteralCaseInsensitive("+fragment+")"; } }; } /** @deprecated since 0.7.0 kept only to allow conversion of anonymous inner classes */ @SuppressWarnings("unused") @Deprecated private static Predicate<CharSequence> containsLiteralOld(final String fragment) { return new Predicate<CharSequence>() { @Override public boolean apply(@Nullable CharSequence input) { return Strings.containsLiteral(input, fragment); } @Override public String toString() { return "containsLiteral("+fragment+")"; } }; } // ----------------- public static <T extends CharSequence> Predicate<T> containsAllLiterals(final String... fragments) { List<Predicate<CharSequence>> fragmentPredicates = Lists.newArrayList(); for (String fragment : fragments) { fragmentPredicates.add(containsLiteral(fragment)); } return Predicates.and(fragmentPredicates); } /** @deprecated since 0.7.0 kept only to allow conversion of anonymous inner classes */ @SuppressWarnings("unused") @Deprecated private static Predicate<CharSequence> containsAllLiteralsOld(final String... fragments) { return Predicates.and(Iterables.transform(Arrays.asList(fragments), new Function<String,Predicate<CharSequence>>() { @Override public Predicate<CharSequence> apply(String input) { return containsLiteral(input); } })); } // ----------------- public static Predicate<CharSequence> containsRegex(final String regex) { // "Pattern" ... what a bad name :) return Predicates.containsPattern(regex); } // ----------------- public static <T extends CharSequence> Predicate<T> startsWith(final String prefix) { return new StartsWith<T>(prefix); } private static final class StartsWith<T extends CharSequence> implements Predicate<T> { private final String prefix; private StartsWith(String prefix) { this.prefix = prefix; } @Override public boolean apply(CharSequence input) { return (input != null) && input.toString().startsWith(prefix); } @Override public String toString() { return "startsWith("+prefix+")"; } } /** @deprecated since 0.7.0 kept only to allow conversion of anonymous inner classes */ @SuppressWarnings("unused") @Deprecated private static Predicate<CharSequence> startsWithOld(final String prefix) { return new Predicate<CharSequence>() { @Override public boolean apply(CharSequence input) { return (input != null) && input.toString().startsWith(prefix); } }; } // ----------------- /** true if the object *is* a {@link CharSequence} starting with the given prefix */ public static Predicate<Object> isStringStartingWith(final String prefix) { return Predicates.<Object>and(Predicates.instanceOf(CharSequence.class), Predicates.compose(startsWith(prefix), StringFunctions.toStringFunction())); } /** @deprecated since 0.7.0 kept only to allow conversion of anonymous inner classes */ @SuppressWarnings("unused") @Deprecated private static Predicate<Object> isStringStartingWithOld(final String prefix) { return new Predicate<Object>() { @Override public boolean apply(Object input) { return (input instanceof CharSequence) && input.toString().startsWith(prefix); } }; } // --------------- public static <T> Predicate<T> equalToAny(Iterable<T> vals) { return new EqualToAny<T>(vals); } private static class EqualToAny<T> implements Predicate<T>, Serializable { private static final long serialVersionUID = 6209304291945204422L; private final Set<T> vals; public EqualToAny(Iterable<? extends T> vals) { this.vals = MutableSet.copyOf(vals); // so allows nulls } @Override public boolean apply(T input) { return vals.contains(input); } @Override public String toString() { return "equalToAny("+vals+")"; } } // ----------- public static <T extends CharSequence> Predicate<T> matchesRegex(final String regex) { return new MatchesRegex<T>(regex); } protected static class MatchesRegex<T extends CharSequence> implements Predicate<T> { protected final String regex; protected MatchesRegex(String regex) { this.regex = regex; } @Override public boolean apply(CharSequence input) { return (input != null) && input.toString().matches(regex); } @Override public String toString() { return "matchesRegex("+regex+")"; } } public static <T extends CharSequence> Predicate<T> matchesGlob(final String glob) { return new MatchesGlob<T>(glob); } protected static class MatchesGlob<T extends CharSequence> implements Predicate<T> { protected final String glob; protected MatchesGlob(String glob) { this.glob = glob; } @Override public boolean apply(CharSequence input) { return (input != null) && WildcardGlobs.isGlobMatched(glob, input.toString()); } @Override public String toString() { return "matchesGlob("+glob+")"; } } }