You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ha...@apache.org on 2015/08/18 17:03:29 UTC
[20/64] [abbrv] incubator-brooklyn git commit: BROOKLYN-162 - apply
org.apache package prefix to utils-common
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/text/StringPredicates.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/text/StringPredicates.java b/utils/common/src/main/java/brooklyn/util/text/StringPredicates.java
deleted file mode 100644
index f83b139..0000000
--- a/utils/common/src/main/java/brooklyn/util/text/StringPredicates.java
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * 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 brooklyn.util.text;
-
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-import 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+")";
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/text/StringShortener.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/text/StringShortener.java b/utils/common/src/main/java/brooklyn/util/text/StringShortener.java
deleted file mode 100644
index 816007a..0000000
--- a/utils/common/src/main/java/brooklyn/util/text/StringShortener.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * 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 brooklyn.util.text;
-
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-/** utility which takes a bunch of segments and applies shortening rules to them */
-public class StringShortener {
-
- protected Map<String,String> wordsByIdInOrder = new LinkedHashMap<String,String>();
- protected String separator = null;
-
- protected interface ShorteningRule {
- /** returns the new list, with the relevant items in the list replaced */
- public int apply(LinkedHashMap<String, String> words, int maxlen, int length);
- }
-
- protected class TruncationRule implements ShorteningRule {
- public TruncationRule(String id, int len) {
- this.id = id;
- this.len = len;
- }
- String id;
- int len;
-
- public int apply(LinkedHashMap<String, String> words, int maxlen, int length) {
- String v = words.get(id);
- if (v!=null && v.length()>len) {
- int charsToRemove = v.length() - len;
- if (length-charsToRemove < maxlen) charsToRemove = length-maxlen;
- words.put(id, v.substring(0, v.length() - charsToRemove));
- length -= charsToRemove;
- if (charsToRemove==v.length() && separator!=null && length>0)
- length -= separator.length();
- }
- return length;
- }
- }
-
- protected class RemovalRule implements ShorteningRule {
- public RemovalRule(String id) {
- this.id = id;
- }
- String id;
-
- public int apply(LinkedHashMap<String, String> words, int maxlen, int length) {
- String v = words.get(id);
- if (v!=null) {
- words.remove(id);
- length -= v.length();
- if (separator!=null && length>0)
- length -= separator.length();
- }
- return length;
- }
- }
-
- private List<ShorteningRule> rules = new ArrayList<StringShortener.ShorteningRule>();
-
-
- public StringShortener separator(String separator) {
- this.separator = separator;
- return this;
- }
-
- public StringShortener append(String id, String text) {
- String old = wordsByIdInOrder.put(id, text);
- if (old!=null) {
- throw new IllegalStateException("Cannot append with id '"+id+"' when id already present");
- }
- // TODO expose a replace or update
- return this;
- }
-
- public StringShortener truncate(String id, int len) {
- String v = wordsByIdInOrder.get(id);
- if (v!=null && v.length()>len) {
- wordsByIdInOrder.put(id, v.substring(0, len));
- }
- return this;
- }
-
- public StringShortener canTruncate(String id, int len) {
- rules.add(new TruncationRule(id, len));
- return this;
- }
-
- public StringShortener canRemove(String id) {
- rules.add(new RemovalRule(id));
- return this;
- }
-
- public String getStringOfMaxLength(int maxlen) {
- LinkedHashMap<String, String> words = new LinkedHashMap<String,String>();
- words.putAll(wordsByIdInOrder);
- int length = 0;
- for (String w: words.values()) {
- if (!Strings.isBlank(w)) {
- length += w.length();
- if (separator!=null)
- length += separator.length();
- }
- }
- if (separator!=null && length>0)
- // remove trailing separator if one had been added
- length -= separator.length();
-
- List<ShorteningRule> rulesLeft = new ArrayList<ShorteningRule>();
- rulesLeft.addAll(rules);
-
- while (length > maxlen && !rulesLeft.isEmpty()) {
- ShorteningRule r = rulesLeft.remove(0);
- length = r.apply(words, maxlen, length);
- }
-
- StringBuilder sb = new StringBuilder();
- for (String w: words.values()) {
- if (!Strings.isBlank(w)) {
- if (separator!=null && sb.length()>0)
- sb.append(separator);
- sb.append(w);
- }
- }
-
- String result = sb.toString();
- if (result.length() > maxlen) result = result.substring(0, maxlen);
-
- return result;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/text/Strings.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/text/Strings.java b/utils/common/src/main/java/brooklyn/util/text/Strings.java
deleted file mode 100644
index 5aa2089..0000000
--- a/utils/common/src/main/java/brooklyn/util/text/Strings.java
+++ /dev/null
@@ -1,945 +0,0 @@
-/*
- * 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 brooklyn.util.text;
-
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.NumberFormat;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import javax.annotation.Nullable;
-
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.time.Time;
-
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Functions;
-import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.Ordering;
-
-public class Strings {
-
- /** The empty {@link String}. */
- public static final String EMPTY = "";
-
- /**
- * Checks if the given string is null or is an empty string.
- * Useful for pre-String.isEmpty. And useful for StringBuilder etc.
- *
- * @param s the String to check
- * @return true if empty or null, false otherwise.
- *
- * @see #isNonEmpty(CharSequence)
- * @see #isBlank(CharSequence)
- * @see #isNonBlank(CharSequence)
- */
- public static boolean isEmpty(CharSequence s) {
- // Note guava has com.google.common.base.Strings.isNullOrEmpty(String),
- // but that is just for String rather than CharSequence
- return s == null || s.length()==0;
- }
-
- /**
- * Checks if the given string is empty or only consists of whitespace.
- *
- * @param s the String to check
- * @return true if blank, empty or null, false otherwise.
- *
- * @see #isEmpty(CharSequence)
- * @see #isNonEmpty(CharSequence)
- * @see #isNonBlank(CharSequence)
- */
- public static boolean isBlank(CharSequence s) {
- return isEmpty(s) || CharMatcher.WHITESPACE.matchesAllOf(s);
- }
-
- /**
- * The inverse of {@link #isEmpty(CharSequence)}.
- *
- * @param s the String to check
- * @return true if non empty, false otherwise.
- *
- * @see #isEmpty(CharSequence)
- * @see #isBlank(CharSequence)
- * @see #isNonBlank(CharSequence)
- */
- public static boolean isNonEmpty(CharSequence s) {
- return !isEmpty(s);
- }
-
- /**
- * The inverse of {@link #isBlank(CharSequence)}.
- *
- * @param s the String to check
- * @return true if non blank, false otherwise.
- *
- * @see #isEmpty(CharSequence)
- * @see #isNonEmpty(CharSequence)
- * @see #isBlank(CharSequence)
- */
- public static boolean isNonBlank(CharSequence s) {
- return !isBlank(s);
- }
-
- /** @return a {@link Maybe} object which is absent if the argument {@link #isBlank(CharSequence)} */
- public static <T extends CharSequence> Maybe<T> maybeNonBlank(T s) {
- if (isNonBlank(s)) return Maybe.of(s);
- return Maybe.absent();
- }
-
- /** throws IllegalArgument if string not empty; cf. guava Preconditions.checkXxxx */
- public static void checkNonEmpty(CharSequence s) {
- if (s==null) throw new IllegalArgumentException("String must not be null");
- if (s.length()==0) throw new IllegalArgumentException("String must not be empty");
- }
- /** throws IllegalArgument if string not empty; cf. guava Preconditions.checkXxxx */
- public static void checkNonEmpty(CharSequence s, String message) {
- if (isEmpty(s)) throw new IllegalArgumentException(message);
- }
-
- /**
- * Removes suffix from the end of the string. Returns string if it does not end with suffix.
- */
- public static String removeFromEnd(String string, String suffix) {
- if (isEmpty(string)) {
- return string;
- } else if (!isEmpty(suffix) && string.endsWith(suffix)) {
- return string.substring(0, string.length() - suffix.length());
- } else {
- return string;
- }
- }
-
- /** removes the first suffix in the list which is present at the end of string
- * and returns that string; ignores subsequent suffixes if a matching one is found;
- * returns the original string if no suffixes are at the end
- * @deprecated since 0.7.0 use {@link #removeFromEnd(String, String)} or {@link #removeAllFromEnd(String, String...)}
- */
- @Deprecated
- public static String removeFromEnd(String string, String ...suffixes) {
- if (isEmpty(string)) return string;
- for (String suffix : suffixes)
- if (suffix!=null && string.endsWith(suffix)) return string.substring(0, string.length() - suffix.length());
- return string;
- }
-
- /**
- * As removeFromEnd, but repeats until all such suffixes are gone
- */
- public static String removeAllFromEnd(String string, String... suffixes) {
- if (isEmpty(string)) return string;
- int index = string.length();
- boolean anotherLoopNeeded = true;
- while (anotherLoopNeeded) {
- if (isEmpty(string)) return string;
- anotherLoopNeeded = false;
- for (String suffix : suffixes)
- if (!isEmpty(suffix) && string.startsWith(suffix, index - suffix.length())) {
- index -= suffix.length();
- anotherLoopNeeded = true;
- break;
- }
- }
- return string.substring(0, index);
- }
-
- /**
- * Removes prefix from the beginning of string. Returns string if it does not begin with prefix.
- */
- public static String removeFromStart(String string, String prefix) {
- if (isEmpty(string)) {
- return string;
- } else if (!isEmpty(prefix) && string.startsWith(prefix)) {
- return string.substring(prefix.length());
- } else {
- return string;
- }
- }
-
- /** removes the first prefix in the list which is present at the start of string
- * and returns that string; ignores subsequent prefixes if a matching one is found;
- * returns the original string if no prefixes match
- * @deprecated since 0.7.0 use {@link #removeFromStart(String, String)}
- */
- @Deprecated
- public static String removeFromStart(String string, String ...prefixes) {
- if (isEmpty(string)) return string;
- for (String prefix : prefixes)
- if (prefix!=null && string.startsWith(prefix)) return string.substring(prefix.length());
- return string;
- }
-
- /**
- * As {@link #removeFromStart(String, String)}, repeating until all such prefixes are gone.
- */
- public static String removeAllFromStart(String string, String... prefixes) {
- int index = 0;
- boolean anotherLoopNeeded = true;
- while (anotherLoopNeeded) {
- if (isEmpty(string)) return string;
- anotherLoopNeeded = false;
- for (String prefix : prefixes) {
- if (!isEmpty(prefix) && string.startsWith(prefix, index)) {
- index += prefix.length();
- anotherLoopNeeded = true;
- break;
- }
- }
- }
- return string.substring(index);
- }
-
- /** convenience for {@link com.google.common.base.Joiner} */
- public static String join(Iterable<? extends Object> list, String separator) {
- if (list==null) return null;
- boolean app = false;
- StringBuilder out = new StringBuilder();
- for (Object s: list) {
- if (app) out.append(separator);
- out.append(s);
- app = true;
- }
- return out.toString();
- }
- /** convenience for {@link com.google.common.base.Joiner} */
- public static String join(Object[] list, String separator) {
- boolean app = false;
- StringBuilder out = new StringBuilder();
- for (Object s: list) {
- if (app) out.append(separator);
- out.append(s);
- app = true;
- }
- return out.toString();
- }
-
- /** convenience for joining lines together */
- public static String lines(String ...lines) {
- return Joiner.on("\n").join(Arrays.asList(lines));
- }
-
- /** NON-REGEX - replaces all key->value entries from the replacement map in source (non-regex) */
- @SuppressWarnings("rawtypes")
- public static String replaceAll(String source, Map replacements) {
- for (Object rr: replacements.entrySet()) {
- Map.Entry r = (Map.Entry)rr;
- source = replaceAllNonRegex(source, ""+r.getKey(), ""+r.getValue());
- }
- return source;
- }
-
- /** NON-REGEX replaceAll - see the better, explicitly named {@link #replaceAllNonRegex(String, String, String)}. */
- public static String replaceAll(String source, String pattern, String replacement) {
- return replaceAllNonRegex(source, pattern, replacement);
- }
-
- /**
- * Replaces all instances in source, of the given pattern, with the given replacement
- * (not interpreting any arguments as regular expressions).
- * <p>
- * This is actually the same as the very ambiguous {@link String#replace(CharSequence, CharSequence)},
- * which does replace all, but not using regex like the similarly ambiguous {@link String#replaceAll(String, String)} as.
- * Alternatively see {@link #replaceAllRegex(String, String, String)}.
- */
- public static String replaceAllNonRegex(String source, String pattern, String replacement) {
- if (source==null) return source;
- StringBuilder result = new StringBuilder(source.length());
- for (int i=0; i<source.length(); ) {
- if (source.substring(i).startsWith(pattern)) {
- result.append(replacement);
- i += pattern.length();
- } else {
- result.append(source.charAt(i));
- i++;
- }
- }
- return result.toString();
- }
-
- /** REGEX replacement -- explicit method name for reabaility, doing same as {@link String#replaceAll(String, String)}. */
- public static String replaceAllRegex(String source, String pattern, String replacement) {
- return source.replaceAll(pattern, replacement);
- }
-
- /** Valid non alphanumeric characters for filenames. */
- public static final String VALID_NON_ALPHANUM_FILE_CHARS = "-_.";
-
- /**
- * Returns a valid filename based on the input.
- *
- * A valid filename starts with the first alphanumeric character, then include
- * all alphanumeric characters plus those in {@link #VALID_NON_ALPHANUM_FILE_CHARS},
- * with any runs of invalid characters being replaced by {@literal _}.
- *
- * @throws NullPointerException if the input string is null.
- * @throws IllegalArgumentException if the input string is blank.
- */
- public static String makeValidFilename(String s) {
- Preconditions.checkNotNull(s, "Cannot make valid filename from null string");
- Preconditions.checkArgument(isNonBlank(s), "Cannot make valid filename from blank string");
- return CharMatcher.anyOf(VALID_NON_ALPHANUM_FILE_CHARS).or(CharMatcher.JAVA_LETTER_OR_DIGIT)
- .negate()
- .trimAndCollapseFrom(s, '_');
- }
-
- /**
- * A {@link CharMatcher} that matches valid Java identifier characters.
- *
- * @see Character#isJavaIdentifierPart(char)
- */
- public static final CharMatcher IS_JAVA_IDENTIFIER_PART = CharMatcher.forPredicate(new Predicate<Character>() {
- @Override
- public boolean apply(@Nullable Character input) {
- return input != null && Character.isJavaIdentifierPart(input);
- }
- });
-
- /**
- * Returns a valid Java identifier name based on the input.
- *
- * Removes certain characterss (like apostrophe), replaces one or more invalid
- * characterss with {@literal _}, and prepends {@literal _} if the first character
- * is only valid as an identifier part (not start).
- * <p>
- * The result is usually unique to s, though this isn't guaranteed, for example if
- * all characters are invalid. For a unique identifier use {@link #makeValidUniqueJavaName(String)}.
- *
- * @see #makeValidUniqueJavaName(String)
- */
- public static String makeValidJavaName(String s) {
- if (s==null) return "__null";
- if (s.length()==0) return "__empty";
- String name = IS_JAVA_IDENTIFIER_PART.negate().collapseFrom(CharMatcher.is('\'').removeFrom(s), '_');
- if (!Character.isJavaIdentifierStart(s.charAt(0))) return "_" + name;
- return name;
- }
-
- /**
- * Returns a unique valid java identifier name based on the input.
- *
- * Translated as per {@link #makeValidJavaName(String)} but with {@link String#hashCode()}
- * appended where necessary to guarantee uniqueness.
- *
- * @see #makeValidJavaName(String)
- */
- public static String makeValidUniqueJavaName(String s) {
- String name = makeValidJavaName(s);
- if (isEmpty(s) || IS_JAVA_IDENTIFIER_PART.matchesAllOf(s) || CharMatcher.is('\'').matchesNoneOf(s)) {
- return name;
- } else {
- return name + "_" + s.hashCode();
- }
- }
-
- /** @see {@link Identifiers#makeRandomId(int)} */
- public static String makeRandomId(int l) {
- return Identifiers.makeRandomId(l);
- }
-
- /** pads the string with 0's at the left up to len; no padding if i longer than len */
- public static String makeZeroPaddedString(int i, int len) {
- return makePaddedString(""+i, len, "0", "");
- }
-
- /** pads the string with "pad" at the left up to len; no padding if base longer than len */
- public static String makePaddedString(String base, int len, String left_pad, String right_pad) {
- String s = ""+(base==null ? "" : base);
- while (s.length()<len) s=left_pad+s+right_pad;
- return s;
- }
-
- public static void trimAll(String[] s) {
- for (int i=0; i<s.length; i++)
- s[i] = (s[i]==null ? "" : s[i].trim());
- }
-
- /** creates a string from a real number, with specified accuracy (more iff it comes for free, ie integer-part);
- * switches to E notation if needed to fit within maxlen; can be padded left up too (not useful)
- * @param x number to use
- * @param maxlen maximum length for the numeric string, if possible (-1 to suppress)
- * @param prec number of digits accuracy desired (more kept for integers)
- * @param leftPadLen will add spaces at left if necessary to make string this long (-1 to suppress) [probably not usef]
- * @return such a string
- */
- public static String makeRealString(double x, int maxlen, int prec, int leftPadLen) {
- return makeRealString(x, maxlen, prec, leftPadLen, 0.00000000001, true);
- }
- /** creates a string from a real number, with specified accuracy (more iff it comes for free, ie integer-part);
- * switches to E notation if needed to fit within maxlen; can be padded left up too (not useful)
- * @param x number to use
- * @param maxlen maximum length for the numeric string, if possible (-1 to suppress)
- * @param prec number of digits accuracy desired (more kept for integers)
- * @param leftPadLen will add spaces at left if necessary to make string this long (-1 to suppress) [probably not usef]
- * @param skipDecimalThreshhold if positive it will not add a decimal part if the fractional part is less than this threshhold
- * (but for a value 3.00001 it would show zeroes, e.g. with 3 precision and positive threshhold <= 0.00001 it would show 3.00);
- * if zero or negative then decimal digits are always shown
- * @param useEForSmallNumbers whether to use E notation for numbers near zero (e.g. 0.001)
- * @return such a string
- */
- public static String makeRealString(double x, int maxlen, int prec, int leftPadLen, double skipDecimalThreshhold, boolean useEForSmallNumbers) {
- if (x<0) return "-"+makeRealString(-x, maxlen, prec, leftPadLen);
- NumberFormat df = DecimalFormat.getInstance();
- //df.setMaximumFractionDigits(maxlen);
- df.setMinimumFractionDigits(0);
- //df.setMaximumIntegerDigits(prec);
- df.setMinimumIntegerDigits(1);
- df.setGroupingUsed(false);
- String s;
- if (x==0) {
- if (skipDecimalThreshhold>0 || prec<=1) s="0";
- else {
- s="0.0";
- while (s.length()<prec+1) s+="0";
- }
- } else {
-// long bits= Double.doubleToLongBits(x);
-// int s = ((bits >> 63) == 0) ? 1 : -1;
-// int e = (int)((bits >> 52) & 0x7ffL);
-// long m = (e == 0) ?
-// (bits & 0xfffffffffffffL) << 1 :
-// (bits & 0xfffffffffffffL) | 0x10000000000000L;
-// //s*m*2^(e-1075);
- int log = (int)Math.floor(Math.log10(x));
- int numFractionDigits = (log>=prec ? 0 : prec-log-1);
- if (numFractionDigits>0) { //need decimal digits
- if (skipDecimalThreshhold>0) {
- int checkFractionDigits = 0;
- double multiplier = 1;
- while (checkFractionDigits < numFractionDigits) {
- if (Math.abs(x - Math.rint(x*multiplier)/multiplier)<skipDecimalThreshhold)
- break;
- checkFractionDigits++;
- multiplier*=10;
- }
- numFractionDigits = checkFractionDigits;
- }
- df.setMinimumFractionDigits(numFractionDigits);
- df.setMaximumFractionDigits(numFractionDigits);
- } else {
- //x = Math.rint(x);
- df.setMaximumFractionDigits(0);
- }
- s = df.format(x);
- if (maxlen>0 && s.length()>maxlen) {
- //too long:
- double signif = x/Math.pow(10,log);
- if (s.indexOf(getDefaultDecimalSeparator())>=0) {
- //have a decimal point; either we are very small 0.000001
- //or prec is larger than maxlen
- if (Math.abs(x)<1 && useEForSmallNumbers) {
- //very small-- use alternate notation
- s = makeRealString(signif, -1, prec, -1) + "E"+log;
- } else {
- //leave it alone, user error or E not wanted
- }
- } else {
- //no decimal point, integer part is too large, use alt notation
- s = makeRealString(signif, -1, prec, -1) + "E"+log;
- }
- }
- }
- if (leftPadLen>s.length())
- return makePaddedString(s, leftPadLen, " ", "");
- else
- return s;
- }
-
- /** creates a string from a real number, with specified accuracy (more iff it comes for free, ie integer-part);
- * switches to E notation if needed to fit within maxlen; can be padded left up too (not useful)
- * @param x number to use
- * @param maxlen maximum length for the numeric string, if possible (-1 to suppress)
- * @param prec number of digits accuracy desired (more kept for integers)
- * @param leftPadLen will add spaces at left if necessary to make string this long (-1 to suppress) [probably not usef]
- * @return such a string
- */
- public static String makeRealStringNearZero(double x, int maxlen, int prec, int leftPadLen) {
- if (Math.abs(x)<0.0000000001) x=0;
- NumberFormat df = DecimalFormat.getInstance();
- //df.setMaximumFractionDigits(maxlen);
- df.setMinimumFractionDigits(0);
- //df.setMaximumIntegerDigits(prec);
- df.setMinimumIntegerDigits(1);
- df.setGroupingUsed(false);
- String s;
- if (x==0) {
- if (prec<=1) s="0";
- else {
- s="0.0";
- while (s.length()<prec+1) s+="0";
- }
- } else {
-// long bits= Double.doubleToLongBits(x);
-// int s = ((bits >> 63) == 0) ? 1 : -1;
-// int e = (int)((bits >> 52) & 0x7ffL);
-// long m = (e == 0) ?
-// (bits & 0xfffffffffffffL) << 1 :
-// (bits & 0xfffffffffffffL) | 0x10000000000000L;
-// //s*m*2^(e-1075);
- int log = (int)Math.floor(Math.log10(x));
- int scale = (log>=prec ? 0 : prec-log-1);
- if (scale>0) { //need decimal digits
- double scale10 = Math.pow(10, scale);
- x = Math.rint(x*scale10)/scale10;
- df.setMinimumFractionDigits(scale);
- df.setMaximumFractionDigits(scale);
- } else {
- //x = Math.rint(x);
- df.setMaximumFractionDigits(0);
- }
- s = df.format(x);
- if (maxlen>0 && s.length()>maxlen) {
- //too long:
- double signif = x/Math.pow(10,log);
- if (s.indexOf('.')>=0) {
- //have a decimal point; either we are very small 0.000001
- //or prec is larger than maxlen
- if (Math.abs(x)<1) {
- //very small-- use alternate notation
- s = makeRealString(signif, -1, prec, -1) + "E"+log;
- } else {
- //leave it alone, user error
- }
- } else {
- //no decimal point, integer part is too large, use alt notation
- s = makeRealString(signif, -1, prec, -1) + "E"+log;
- }
- }
- }
- if (leftPadLen>s.length())
- return makePaddedString(s, leftPadLen, " ", "");
- else
- return s;
- }
-
- /** returns the first word (whitespace delimited text), or null if there is none (input null or all whitespace) */
- public static String getFirstWord(String s) {
- if (s==null) return null;
- int start = 0;
- while (start<s.length()) {
- if (!Character.isWhitespace(s.charAt(start)))
- break;
- start++;
- }
- int end = start;
- if (end >= s.length())
- return null;
- while (end<s.length()) {
- if (Character.isWhitespace(s.charAt(end)))
- break;
- end++;
- }
- return s.substring(start, end);
- }
-
- /** returns the last word (whitespace delimited text), or null if there is none (input null or all whitespace) */
- public static String getLastWord(String s) {
- if (s==null) return null;
- int end = s.length()-1;
- while (end >= 0) {
- if (!Character.isWhitespace(s.charAt(end)))
- break;
- end--;
- }
- int start = end;
- if (start < 0)
- return null;
- while (start >= 0) {
- if (Character.isWhitespace(s.charAt(start)))
- break;
- start--;
- }
- return s.substring(start+1, end+1);
- }
-
- /** returns the first word after the given phrase, or null if no such phrase;
- * if the character immediately after the phrase is not whitespace, the non-whitespace
- * sequence starting with that character will be returned */
- public static String getFirstWordAfter(String context, String phrase) {
- if (context==null || phrase==null) return null;
- int index = context.indexOf(phrase);
- if (index<0) return null;
- return getFirstWord(context.substring(index + phrase.length()));
- }
-
- /**
- * searches in context for the given phrase, and returns the <b>untrimmed</b> remainder of the first line
- * on which the phrase is found
- */
- public static String getRemainderOfLineAfter(String context, String phrase) {
- if (context == null || phrase == null) return null;
- int index = context.indexOf(phrase);
- if (index < 0) return null;
- int lineEndIndex = context.indexOf("\n", index);
- if (lineEndIndex <= 0) {
- return context.substring(index + phrase.length());
- } else {
- return context.substring(index + phrase.length(), lineEndIndex);
- }
- }
-
- /** @deprecated use {@link Time#makeTimeStringRounded(long)} */
- @Deprecated
- public static String makeTimeString(long utcMillis) {
- return Time.makeTimeStringRounded(utcMillis);
- }
-
- /** returns e.g. { "prefix01", ..., "prefix96" };
- * see more functional NumericRangeGlobExpander for "prefix{01-96}"
- */
- public static String[] makeArray(String prefix, int count) {
- String[] result = new String[count];
- int len = (""+count).length();
- for (int i=1; i<=count; i++)
- result[i-1] = prefix + makePaddedString("", len, "0", ""+i);
- return result;
- }
-
- public static String[] combineArrays(String[] ...arrays) {
- int totalLen = 0;
- for (String[] array : arrays) {
- if (array!=null) totalLen += array.length;
- }
- String[] result = new String[totalLen];
- int i=0;
- for (String[] array : arrays) {
- if (array!=null) for (String s : array) {
- result[i++] = s;
- }
- }
- return result;
- }
-
- public static String toInitialCapOnly(String value) {
- if (value==null || value.length()==0) return value;
- return value.substring(0, 1).toUpperCase(Locale.ENGLISH) + value.substring(1).toLowerCase(Locale.ENGLISH);
- }
-
- public static String reverse(String name) {
- return new StringBuffer(name).reverse().toString();
- }
-
- public static boolean isLowerCase(String s) {
- return s.toLowerCase().equals(s);
- }
-
- public static String makeRepeated(char c, int length) {
- StringBuilder result = new StringBuilder(length);
- for (int i = 0; i < length; i++) {
- result.append(c);
- }
- return result.toString();
- }
-
- public static String trim(String s) {
- if (s==null) return null;
- return s.trim();
- }
-
- public static String trimEnd(String s) {
- if (s==null) return null;
- return ("a"+s).trim().substring(1);
- }
-
- /** returns up to maxlen characters from the start of s */
- public static String maxlen(String s, int maxlen) {
- return maxlenWithEllipsis(s, maxlen, "");
- }
-
- /** as {@link #maxlenWithEllipsis(String, int, String) with "..." as the ellipsis */
- public static String maxlenWithEllipsis(String s, int maxlen) {
- return maxlenWithEllipsis(s, maxlen, "...");
- }
- /** as {@link #maxlenWithEllipsis(String, int) but replacing the last few chars with the given ellipsis */
- public static String maxlenWithEllipsis(String s, int maxlen, String ellipsis) {
- if (s==null) return null;
- if (ellipsis==null) ellipsis="";
- if (s.length()<=maxlen) return s;
- return s.substring(0, Math.max(maxlen-ellipsis.length(), 0))+ellipsis;
- }
-
- /** returns toString of the object if it is not null, otherwise null */
- public static String toString(Object o) {
- return toStringWithValueForNull(o, null);
- }
-
- /** returns toString of the object if it is not null, otherwise the given value */
- public static String toStringWithValueForNull(Object o, String valueIfNull) {
- if (o==null) return valueIfNull;
- return o.toString();
- }
-
- public static boolean containsLiteralIgnoreCase(CharSequence input, CharSequence fragment) {
- if (input==null) return false;
- if (isEmpty(fragment)) return true;
- int lastValidStartPos = input.length()-fragment.length();
- char f0u = Character.toUpperCase(fragment.charAt(0));
- char f0l = Character.toLowerCase(fragment.charAt(0));
- i: for (int i=0; i<=lastValidStartPos; i++) {
- char ii = input.charAt(i);
- if (ii==f0l || ii==f0u) {
- for (int j=1; j<fragment.length(); j++) {
- if (Character.toLowerCase(input.charAt(i+j))!=Character.toLowerCase(fragment.charAt(j)))
- continue i;
- }
- return true;
- }
- }
- return false;
- }
-
- public static boolean containsLiteral(CharSequence input, CharSequence fragment) {
- if (input==null) return false;
- if (isEmpty(fragment)) return true;
- int lastValidStartPos = input.length()-fragment.length();
- char f0 = fragment.charAt(0);
- i: for (int i=0; i<=lastValidStartPos; i++) {
- char ii = input.charAt(i);
- if (ii==f0) {
- for (int j=1; j<fragment.length(); j++) {
- if (input.charAt(i+j)!=fragment.charAt(j))
- continue i;
- }
- return true;
- }
- }
- return false;
- }
-
- /** Returns a size string using metric suffixes from {@link ByteSizeStrings#metric()}, e.g. 23.5MB */
- public static String makeSizeString(long sizeInBytes) {
- return ByteSizeStrings.metric().makeSizeString(sizeInBytes);
- }
-
- /** Returns a size string using ISO suffixes from {@link ByteSizeStrings#iso()}, e.g. 23.5MiB */
- public static String makeISOSizeString(long sizeInBytes) {
- return ByteSizeStrings.iso().makeSizeString(sizeInBytes);
- }
-
- /** Returns a size string using Java suffixes from {@link ByteSizeStrings#java()}, e.g. 23m */
- public static String makeJavaSizeString(long sizeInBytes) {
- return ByteSizeStrings.java().makeSizeString(sizeInBytes);
- }
-
- /** returns a configurable shortener */
- public static StringShortener shortener() {
- return new StringShortener();
- }
-
- public static Supplier<String> toStringSupplier(Object src) {
- return Suppliers.compose(Functions.toStringFunction(), Suppliers.ofInstance(src));
- }
-
- /** wraps a call to {@link String#format(String, Object...)} in a toString, i.e. using %s syntax,
- * useful for places where we want deferred evaluation
- * (e.g. as message to {@link Preconditions} to skip concatenation when not needed) */
- public static FormattedString format(String pattern, Object... args) {
- return new FormattedString(pattern, args);
- }
-
- /** returns "s" if the argument is not 1, empty string otherwise; useful when constructing plurals */
- public static String s(int count) {
- return count==1 ? "" : "s";
- }
- /** as {@link #s(int)} based on size of argument */
- public static String s(@Nullable Map<?,?> x) {
- return s(x==null ? 0 : x.size());
- }
- /** as {@link #s(int)} based on size of argument */
- public static String s(Iterable<?> x) {
- if (x==null) return s(0);
- return s(x.iterator());
- }
- /** as {@link #s(int)} based on size of argument */
- public static String s(Iterator<?> x) {
- int count = 0;
- if (x==null || !x.hasNext()) {}
- else {
- x.next(); count++;
- if (x.hasNext()) count++;
- }
- return s(count);
- }
-
- /** returns "ies" if the argument is not 1, "y" otherwise; useful when constructing plurals */
- public static String ies(int count) {
- return count==1 ? "y" : "ies";
- }
- /** as {@link #ies(int)} based on size of argument */
- public static String ies(@Nullable Map<?,?> x) {
- return ies(x==null ? 0 : x.size());
- }
- /** as {@link #ies(int)} based on size of argument */
- public static String ies(Iterable<?> x) {
- if (x==null) return ies(0);
- return ies(x.iterator());
- }
- /** as {@link #ies(int)} based on size of argument */
- public static String ies(Iterator<?> x) {
- int count = 0;
- if (x==null || !x.hasNext()) {}
- else {
- x.next(); count++;
- if (x.hasNext()) count++;
- }
- return ies(count);
- }
-
- /** converts a map of any objects to a map of strings, using the tostring, and returning "null" for nulls
- * @deprecated since 0.7.0 use {@link #toStringMap(Map, String)} to remove ambiguity about how to handle null */
- // NB previously the javadoc here was wrong, said it returned null not "null"
- @Deprecated
- public static Map<String, String> toStringMap(Map<?,?> map) {
- return toStringMap(map, "null");
- }
- /** converts a map of any objects to a map of strings, using {@link Object#toString()},
- * with the second argument used where a value (or key) is null */
- public static Map<String, String> toStringMap(Map<?,?> map, String valueIfNull) {
- if (map==null) return null;
- Map<String,String> result = MutableMap.<String, String>of();
- for (Map.Entry<?,?> e: map.entrySet()) {
- result.put(toStringWithValueForNull(e.getKey(), valueIfNull), toStringWithValueForNull(e.getValue(), valueIfNull));
- }
- return result;
- }
-
- /** converts a list of any objects to a list of strings, using {@link Object#toString()},
- * with the second argument used where an entry is null */
- public static List<String> toStringList(List<?> list, String valueIfNull) {
- if (list==null) return null;
- List<String> result = MutableList.of();
- for (Object v: list) result.add(toStringWithValueForNull(v, valueIfNull));
- return result;
- }
-
- /** returns base repeated count times */
- public static String repeat(String base, int count) {
- if (base==null) return null;
- StringBuilder result = new StringBuilder();
- for (int i=0; i<count; i++)
- result.append(base);
- return result.toString();
- }
-
- /** returns comparator which compares based on length, with shorter ones first (and null before that);
- * in event of a tie, it uses the toString order */
- public static Ordering<String> lengthComparator() {
- return Ordering.<Integer>natural().onResultOf(StringFunctions.length()).compound(Ordering.<String>natural()).nullsFirst();
- }
-
- public static boolean isMultiLine(String s) {
- if (s==null) return false;
- if (s.indexOf('\n')>=0 || s.indexOf('\r')>=0) return true;
- return false;
- }
- public static String getFirstLine(String s) {
- int idx = s.indexOf('\n');
- if (idx==-1) return s;
- return s.substring(0, idx);
- }
-
- /** looks for first section of text in following the prefix and, if present, before the suffix;
- * null if the prefix is not present in the string, and everything after the prefix if suffix is not present in the string;
- * if either prefix or suffix is null, it is treated as the start/end of the string */
- public static String getFragmentBetween(String input, String prefix, String suffix) {
- if (input==null) return null;
- int index;
- if (prefix!=null) {
- index = input.indexOf(prefix);
- if (index==-1) return null;
- input = input.substring(index + prefix.length());
- }
- if (suffix!=null) {
- index = input.indexOf(suffix);
- if (index>=0) input = input.substring(0, index);
- }
- return input;
- }
-
- public static int getWordCount(String phrase, boolean respectQuotes) {
- if (phrase==null) return 0;
- phrase = phrase.trim();
- if (respectQuotes)
- return new QuotedStringTokenizer(phrase).remainderAsList().size();
- else
- return Collections.list(new StringTokenizer(phrase)).size();
- }
-
- public static char getDecimalSeparator(Locale locale) {
- DecimalFormatSymbols dfs = new DecimalFormatSymbols(locale);
- return dfs.getDecimalSeparator();
- }
-
- public static char getDefaultDecimalSeparator() {
- return getDecimalSeparator(Locale.getDefault());
- }
-
- /** replaces each sequence of whitespace in the first string with the replacement in the second string */
- public static String collapseWhitespace(String x, String whitespaceReplacement) {
- if (x==null) return null;
- return replaceAllRegex(x, "\\s+", whitespaceReplacement);
- }
-
- public static String toLowerCase(String value) {
- if (value==null || value.length()==0) return value;
- return value.toLowerCase(Locale.ENGLISH);
- }
-
- /**
- * @return null if var is null or empty string, otherwise return var
- */
- public static String emptyToNull(String var) {
- if (isNonEmpty(var)) {
- return var;
- } else {
- return null;
- }
- }
-
- /** Returns canonicalized string from the given object, made "unique" by:
- * <li> putting sets into the toString order
- * <li> appending a hash code if it's longer than the max (and the max is bigger than 0) */
- public static String toUniqueString(Object x, int optionalMax) {
- if (x instanceof Iterable && !(x instanceof List)) {
- // unsorted collections should have a canonical order imposed
- MutableList<String> result = MutableList.of();
- for (Object xi: (Iterable<?>)x) {
- result.add(toUniqueString(xi, optionalMax));
- }
- Collections.sort(result);
- x = result.toString();
- }
- if (x==null) return "{null}";
- String xs = x.toString();
- if (xs.length()<=optionalMax || optionalMax<=0) return xs;
- return maxlenWithEllipsis(xs, optionalMax-8)+"/"+Integer.toHexString(xs.hashCode());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/text/WildcardGlobs.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/text/WildcardGlobs.java b/utils/common/src/main/java/brooklyn/util/text/WildcardGlobs.java
deleted file mode 100644
index e26848b..0000000
--- a/utils/common/src/main/java/brooklyn/util/text/WildcardGlobs.java
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * 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 brooklyn.util.text;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.google.common.base.Throwables;
-
-public class WildcardGlobs {
-
- /** returns true iff the target matches the given pattern,
- * under simplified bash rules -- viz permitting * and ? and comma delimited patterns inside curly braces
- * @throws InvalidPatternException */
- public static boolean isGlobMatched(String globPattern, String targetText) throws InvalidPatternException {
- List<String> patterns = getGlobsAfterBraceExpansion(globPattern);
- for (String p : patterns) {
- if (isNoBraceGlobMatched(p, targetText))
- return true;
- }
- return false;
- }
-
- /** whether a glob-ish string without braces (e.g. containing just ? and * chars) matches;
- * can be used directly, also used implicitly by isGlobMatched after glob expansion */
- public static boolean isNoBraceGlobMatched(String globPattern, String target) {
- int pi=0, ti=0;
- while (pi<globPattern.length() && ti<target.length()) {
- char pc = globPattern.charAt(pi);
- char tc = target.charAt(pi);
- if (pc=='?') {
- pi++; ti++;
- continue;
- }
- if (pc!='*') {
- if (pc!=tc) return false;
- pi++; ti++;
- continue;
- }
- //match 0 or more chars
- String prest = globPattern.substring(pi+1);
- while (ti<=target.length()) {
- if (isNoBraceGlobMatched(prest, target.substring(ti)))
- return true;
- ti++;
- }
- return false;
- }
- while (pi<globPattern.length() && globPattern.charAt(pi)=='*')
- pi++;
- return (pi==globPattern.length() && ti==target.length());
- }
-
- /** returns a list with no curly braces in any entries,
- * and guaranteeing order such that any {..,X,..,Y,..} will result in X being before Y in the resulting list;
- * e.g. given a{,b,c} gives a ab and ac; no special treatment of numeric ranges, quotes, or parentheses
- * (see SpecialistGlobExpander for that) */
- public static List<String> getGlobsAfterBraceExpansion(String pattern) throws InvalidPatternException {
- return getGlobsAfterBraceExpansion(pattern, false, PhraseTreatment.NOT_A_SPECIAL_CHAR, PhraseTreatment.NOT_A_SPECIAL_CHAR);
- }
-
- /** if a string contains a demarcated phrase, e.g. between open and close parentheses, or inside unescaped quotes
- * this argument determines how that phrase is treated with regards to brace expansion */
- public enum PhraseTreatment {
- /** the region is treated like any other region */
- NOT_A_SPECIAL_CHAR,
- /** the interior will be expanded if there is a {x,y} expression _entirely_ inside the phrase, but otherwise commas inside it will be ignored;
- * it will be an error if there is a { char inside the phrase, or if the phrase is not internally well-formed with regards to the phrase characters,
- * (e.g. if quotes are interior expandable and parens are anything but not_a_special_char (e.g. interior expandable or interior not expandable)
- * then any expression inside a quoted phrase must have matching parentheses) */
- INTERIOR_EXPANDABLE,
- /** the interior will not be expanded at all, not if there's a comma inside, and not even if there is a {x,y} expression entirely inside; the braces will be left;
- * interior of parenthetical phrases must have matching parentheses (to determine the right end parenthesis),
- * apart from parentheses inside any quoted phrases when quotes are interior_not_expandable which will be ignored;
- * quotes inside not_expandable paren phrases will be ignored */
- INTERIOR_NOT_EXPANDABLE
- };
-
- protected static class ExpressionToExpand {
- String resultSoFar;
- String todo;
- String operatorStack;
- public ExpressionToExpand(String resultSoFar, String todo, String operatorStack) {
- super();
- this.resultSoFar = resultSoFar;
- this.todo = todo;
- this.operatorStack = operatorStack;
- }
- @Override
- public String toString() {
- return "ExpressionToExpand["+todo+":"+resultSoFar+"/"+operatorStack+"]";
- }
- }
- /** returns a list with no curly braces in any entries; e.g. given a{,b} gives a and ab;
- * quotes and parentheses are kept, but their contents may be excluded from expansion or otherwise treated specially as per the flag.
- * with allowNumericRanges, "{1-3}" is permitted for {1,2,3}. */
- public static List<String> getGlobsAfterBraceExpansion(String pattern, boolean allowNumericRanges, PhraseTreatment quoteTreatment, PhraseTreatment parenthesesTreatment) throws InvalidPatternException {
- List<ExpressionToExpand> patterns = new ArrayList<ExpressionToExpand>();
- List<String> result = new ArrayList<String>();
- patterns.add(new ExpressionToExpand("", pattern, ""));
- while (!patterns.isEmpty()) {
- ExpressionToExpand cs = patterns.remove(0);
- StringBuffer resultSoFar = new StringBuffer(cs.resultSoFar);
- String operatorStack = cs.operatorStack;
- boolean inQuote = operatorStack.contains("\"");
- boolean expanded = false;
- for (int i=0; i<cs.todo.length(); i++) {
- assert !expanded;
- char c = cs.todo.charAt(i);
- boolean inParen = operatorStack.contains("(") &&
- (!inQuote || operatorStack.lastIndexOf('\"')<operatorStack.lastIndexOf('('));
- if (inQuote && !(inParen && parenthesesTreatment.equals(PhraseTreatment.INTERIOR_NOT_EXPANDABLE))) {
- if (c=='"') {
- if (i>0 && cs.todo.charAt(i-1)=='\\') {
- //this escaped quote, keep
- resultSoFar.append(c);
- continue;
- }
- //unquote
- resultSoFar.append(c);
- inQuote = false;
- if (operatorStack.charAt(operatorStack.length()-1)!='\"')
- throw new InvalidPatternException("Quoted string contents not valid, after parsing "+resultSoFar);
- operatorStack = operatorStack.substring(0, operatorStack.length()-1);
- continue;
- }
- if (quoteTreatment.equals(PhraseTreatment.INTERIOR_NOT_EXPANDABLE)) {
- resultSoFar.append(c);
- continue;
- }
- //interior is expandable, continue parsing as usual below
- }
- if (inParen) {
- if (c==')') {
- //unparen
- resultSoFar.append(c);
- if (operatorStack.charAt(operatorStack.length()-1)!='(')
- throw new InvalidPatternException("Parenthetical contents not valid, after parsing "+resultSoFar);
- operatorStack = operatorStack.substring(0, operatorStack.length()-1);
- continue;
- }
- if (parenthesesTreatment.equals(PhraseTreatment.INTERIOR_NOT_EXPANDABLE)) {
- resultSoFar.append(c);
- if (c=='(')
- operatorStack+="(";
- continue;
- }
- //interior is expandable, continue parsing as usual below
- }
-
- if (c=='"' && !quoteTreatment.equals(PhraseTreatment.NOT_A_SPECIAL_CHAR)) {
- resultSoFar.append(c);
- inQuote = true;
- operatorStack += "\"";
- continue;
- }
- if (c=='(' && !parenthesesTreatment.equals(PhraseTreatment.NOT_A_SPECIAL_CHAR)) {
- resultSoFar.append(c);
- operatorStack += "(";
- continue;
- }
-
- if (c!='{') {
- resultSoFar.append(c);
- continue;
- }
-
- //brace.. we will need to expand
- expanded = true;
- String operatorStackBeforeExpansion = operatorStack;
- int braceStartIndex = i;
- int tokenStartIndex = i+1;
-
- //find matching close brace
- List<String> tokens = new ArrayList<String>();
- operatorStack += "{";
- while (true) {
- if (++i>=cs.todo.length()) {
- throw new InvalidPatternException("Curly brace not closed, parsing '"+cs.todo.substring(braceStartIndex)+"' after "+resultSoFar);
- }
- c = cs.todo.charAt(i);
- inParen = operatorStack.contains("(") &&
- (!inQuote || operatorStack.lastIndexOf('\"')<operatorStack.lastIndexOf('('));
- if (inQuote && !(inParen && parenthesesTreatment.equals(PhraseTreatment.INTERIOR_NOT_EXPANDABLE))) {
- if (c=='"') {
- if (i>0 && cs.todo.charAt(i-1)=='\\') {
- //this is escaped quote, doesn't affect status
- continue;
- }
- //unquote
- inQuote = false;
- if (operatorStack.charAt(operatorStack.length()-1)!='\"')
- throw new InvalidPatternException("Quoted string contents not valid, after parsing "+resultSoFar+cs.todo.substring(braceStartIndex, i));
- operatorStack = operatorStack.substring(0, operatorStack.length()-1);
- continue;
- }
- if (quoteTreatment.equals(PhraseTreatment.INTERIOR_NOT_EXPANDABLE)) {
- continue;
- }
- //interior is expandable, continue parsing as usual below
- }
- if (inParen) {
- if (c==')') {
- //unparen
- if (operatorStack.charAt(operatorStack.length()-1)!='(')
- throw new InvalidPatternException("Parenthetical contents not valid, after parsing "+resultSoFar+cs.todo.substring(braceStartIndex, i));
- operatorStack = operatorStack.substring(0, operatorStack.length()-1);
- continue;
- }
- if (parenthesesTreatment.equals(PhraseTreatment.INTERIOR_NOT_EXPANDABLE)) {
- if (c=='(')
- operatorStack+="(";
- continue;
- }
- //interior is expandable, continue parsing as usual below
- }
-
- if (c=='"' && !quoteTreatment.equals(PhraseTreatment.NOT_A_SPECIAL_CHAR)) {
- inQuote = true;
- operatorStack += "\"";
- continue;
- }
- if (c=='(' && !parenthesesTreatment.equals(PhraseTreatment.NOT_A_SPECIAL_CHAR)) {
- operatorStack += "(";
- continue;
- }
-
- if (c=='}') {
- if (operatorStack.charAt(operatorStack.length()-1)!='{')
- throw new InvalidPatternException("Brace contents not valid, mismatched operators "+operatorStack+" after parsing "+resultSoFar+cs.todo.substring(braceStartIndex, i));
- operatorStack = operatorStack.substring(0, operatorStack.length()-1);
- if (operatorStack.equals(operatorStackBeforeExpansion)) {
- tokens.add(cs.todo.substring(tokenStartIndex, i));
- break;
- }
- continue;
- }
-
- if (c==',') {
- if (operatorStack.length()==operatorStackBeforeExpansion.length()+1) {
- tokens.add(cs.todo.substring(tokenStartIndex, i));
- tokenStartIndex = i+1;
- continue;
- }
- continue;
- }
-
- if (c=='{') {
- operatorStack += c;
- continue;
- }
-
- //any other char is irrelevant
- continue;
- }
-
- assert operatorStack.equals(operatorStackBeforeExpansion);
- assert cs.todo.charAt(i)=='}';
- assert !tokens.isEmpty();
-
- String suffix = cs.todo.substring(i+1);
-
- List<ExpressionToExpand> newPatterns = new ArrayList<ExpressionToExpand>();
- for (String token : tokens) {
- //System.out.println("adding: "+pre+token+post);
- if (allowNumericRanges && token.matches("\\s*[0-9]+\\s*-\\s*[0-9]+\\s*")) {
- int dashIndex = token.indexOf('-');
- String startS = token.substring(0, dashIndex).trim();
- String endS = token.substring(dashIndex+1).trim();
-
- int start = Integer.parseInt(startS);
- int end = Integer.parseInt(endS);
-
- if (startS.startsWith("-")) startS=startS.substring(1).trim();
- if (endS.startsWith("-")) endS=endS.substring(1).trim();
- int minLen = Math.min(startS.length(), endS.length());
-
- for (int ti=start; ti<=end; ti++) {
- //partial support for negative numbers, but of course they cannot (yet) be specified in the regex above so it is moot
- String tokenI = ""+Math.abs(ti);
- while (tokenI.length()<minLen) tokenI = "0"+tokenI;
- if (ti<0) tokenI = "-"+tokenI;
- newPatterns.add(new ExpressionToExpand(resultSoFar.toString(), tokenI+suffix, operatorStackBeforeExpansion));
- }
- } else {
- newPatterns.add(new ExpressionToExpand(resultSoFar.toString(), token+suffix, operatorStackBeforeExpansion));
- }
- }
- // insert new patterns at the start, so we continue to expand them next
- patterns.addAll(0, newPatterns);
-
- break;
- }
- if (!expanded) {
- if (operatorStack.length()>0) {
- throw new InvalidPatternException("Unclosed operators "+operatorStack+" parsing "+resultSoFar);
- }
- result.add(resultSoFar.toString());
- }
- }
- assert !result.isEmpty();
- return result;
- }
-
- public static class InvalidPatternException extends RuntimeException {
- private static final long serialVersionUID = -1969068264338310749L;
- public InvalidPatternException(String msg) {
- super(msg);
- }
- }
-
-
- /** expands globs as per #getGlobsAfterBraceExpansion,
- * but also handles numeric ranges,
- * and optionally allows customized treatment of quoted regions and/or parentheses.
- * <p>
- * simple example: machine-{0-3}-{a,b} returns 8 values,
- * machine-0-a machine-0-b machine-1-a ... machine-3-b;
- * NB leading zeroes are meaningful, so {00-03} expands as 00, 01, 02, 03
- * <p>
- * quote INTERIOR_NOT_EXPANDABLE example: a{b,"c,d"} return ab ac,d
- * <p>
- * for more detail on special treatment of quote and parentheses see PhraseTreatment and WildcardGlobsTest
- */
- public static class SpecialistGlobExpander {
-
- private boolean expandNumericRanges;
- private PhraseTreatment quoteTreatment;
- private PhraseTreatment parenthesesTreatment;
-
- public SpecialistGlobExpander(boolean expandNumericRanges, PhraseTreatment quoteTreatment, PhraseTreatment parenthesesTreatment) {
- this.expandNumericRanges = expandNumericRanges;
- this.quoteTreatment = quoteTreatment;
- this.parenthesesTreatment = parenthesesTreatment;
- }
- /** expands glob, including custom syntax for numeric part */
- public List<String> expand(String glob) throws InvalidPatternException {
- return getGlobsAfterBraceExpansion(glob, expandNumericRanges, quoteTreatment, parenthesesTreatment);
- }
-
- /** returns true iff the target matches the given pattern,
- * under simplified bash rules -- viz permitting * and ? and comma delimited patterns inside curly braces,
- * as well as things like {1,2,5-10} (and also {01,02,05-10} to keep leading 0)
- * @throws InvalidPatternException */
- public boolean isGlobMatchedNumeric(String globPattern, String targetText) throws InvalidPatternException {
- List<String> patterns = expand(globPattern);
- for (String p : patterns) {
- if (isNoBraceGlobMatched(p, targetText))
- return true;
- }
- return false;
- }
-
- /** expands glob, including custom syntax for numeric part, but to an array, and re-throwing the checked exception as a runtime exception */
- public String[] expandToArrayUnchecked(String glob) {
- try {
- return expand(glob).toArray(new String[0]);
- } catch (InvalidPatternException e) {
- throw Throwables.propagate(e);
- }
- }
-
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/time/CountdownTimer.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/time/CountdownTimer.java b/utils/common/src/main/java/brooklyn/util/time/CountdownTimer.java
deleted file mode 100644
index 0a5aaec..0000000
--- a/utils/common/src/main/java/brooklyn/util/time/CountdownTimer.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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 brooklyn.util.time;
-
-import java.util.concurrent.TimeUnit;
-
-import brooklyn.util.exceptions.Exceptions;
-
-import com.google.common.base.Stopwatch;
-
-public class CountdownTimer {
-
- Stopwatch stopwatch = Stopwatch.createUnstarted();
- Duration limit;
-
- private CountdownTimer(Duration limit) {
- this.limit = limit;
- }
-
- /** starts the timer, either initially or if {@link #pause()}d; no-op if already running */
- public synchronized CountdownTimer start() {
- if (!stopwatch.isRunning()) stopwatch.start();
- return this;
- }
-
- /** pauses the timer, if running; no-op if not running */
- public synchronized CountdownTimer pause() {
- if (stopwatch.isRunning()) stopwatch.stop();
- return this;
- }
-
- /** returns underlying stopwatch, which caller can inspect for more details or modify */
- public Stopwatch getStopwatch() {
- return stopwatch;
- }
-
- /** how much total time this timer should run for */
- public Duration getLimit() {
- return limit;
- }
-
- /** return how long the timer has been running (longer than limit if {@link #isExpired()}) */
- public Duration getDurationElapsed() {
- return Duration.nanos(stopwatch.elapsed(TimeUnit.NANOSECONDS));
- }
-
- /** returns how much time is left (negative if {@link #isExpired()}) */
- public Duration getDurationRemaining() {
- return Duration.millis(limit.toMilliseconds() - stopwatch.elapsed(TimeUnit.MILLISECONDS));
- }
-
- /** true iff the timer has been running for the duration specified at creation time */
- public boolean isExpired() {
- return stopwatch.elapsed(TimeUnit.MILLISECONDS) > limit.toMilliseconds();
- }
-
- /** true iff timer is running (even if it is expired) */
- public boolean isRunning() {
- return stopwatch.isRunning();
- }
-
- // --- constructor methods
-
- public static CountdownTimer newInstanceStarted(Duration duration) {
- return new CountdownTimer(duration).start();
- }
-
- public static CountdownTimer newInstancePaused(Duration duration) {
- return new CountdownTimer(duration).pause();
- }
-
- /** block (on this object) until completed
- * @throws InterruptedException */
- public synchronized void waitForExpiry() throws InterruptedException {
- while (waitOnForExpiry(this)) {};
- }
-
- /** as {@link #waitForExpiry()} but catches and wraps InterruptedException as unchecked RuntimeInterruptedExcedption */
- public synchronized void waitForExpiryUnchecked() {
- waitOnForExpiryUnchecked(this);
- }
-
- /** block on the given argument until the timer is completed or the object receives a notified;
- * callers must be synchronized on the waitTarget
- * @return true if the object is notified (or receives a spurious wake), false if the duration is expired
- * @throws InterruptedException */
- public boolean waitOnForExpiry(Object waitTarget) throws InterruptedException {
- Duration remainder = getDurationRemaining();
- if (remainder.toMilliseconds() <= 0)
- return false;
- waitTarget.wait(remainder.toMilliseconds());
- return true;
- }
- /** as {@link #waitOnForExpiry(Object)} but catches and wraps InterruptedException as unchecked RuntimeInterruptedExcedption */
- public boolean waitOnForExpiryUnchecked(Object waitTarget) {
- try {
- return waitOnForExpiry(waitTarget);
- } catch (InterruptedException e) {
- throw Exceptions.propagate(e);
- }
- }
-
-}