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:37 UTC
[28/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/test/Asserts.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/test/Asserts.java b/utils/common/src/main/java/brooklyn/test/Asserts.java
deleted file mode 100644
index b3c1e01..0000000
--- a/utils/common/src/main/java/brooklyn/test/Asserts.java
+++ /dev/null
@@ -1,499 +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.test;
-
-import groovy.lang.Closure;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.util.collections.MutableSet;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.time.Duration;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-/**
- * TODO should move this to new package brooklyn.util.assertions
- * and TODO should add a repeating() method which returns an AssertingRepeater extending Repeater
- * and:
- * <li> adds support for requireAllIterationsTrue
- * <li> convenience run methods equivalent to succeedsEventually and succeedsContinually
- */
-@Beta
-public class Asserts {
-
- /**
- * The default timeout for assertions. Alter in individual tests by giving a
- * "timeout" entry in method flags.
- */
- public static final Duration DEFAULT_TIMEOUT = Duration.THIRTY_SECONDS;
-
- private static final Logger log = LoggerFactory.getLogger(Asserts.class);
-
- private Asserts() {}
-
- // --- selected routines from testng.Assert for visibility without needing that package
-
- /**
- * Asserts that a condition is true. If it isn't,
- * an AssertionError, with the given message, is thrown.
- * @param condition the condition to evaluate
- * @param message the assertion error message
- */
- public static void assertTrue(boolean condition, String message) {
- if (!condition) fail(message);
- }
-
- /**
- * Asserts that a condition is false. If it isn't,
- * an AssertionError, with the given message, is thrown.
- * @param condition the condition to evaluate
- * @param message the assertion error message
- */
- public static void assertFalse(boolean condition, String message) {
- if (condition) fail(message);
- }
-
- /**
- * Fails a test with the given message.
- * @param message the assertion error message
- */
- public static AssertionError fail(String message) {
- throw new AssertionError(message);
- }
-
- public static void assertEqualsIgnoringOrder(Iterable<?> actual, Iterable<?> expected) {
- assertEqualsIgnoringOrder(actual, expected, false, null);
- }
-
- public static void assertEqualsIgnoringOrder(Iterable<?> actual, Iterable<?> expected, boolean logDuplicates, String errmsg) {
- Set<?> actualSet = Sets.newLinkedHashSet(actual);
- Set<?> expectedSet = Sets.newLinkedHashSet(expected);
- Set<?> extras = Sets.difference(actualSet, expectedSet);
- Set<?> missing = Sets.difference(expectedSet, actualSet);
- List<Object> duplicates = Lists.newArrayList(actual);
- for (Object a : actualSet) {
- duplicates.remove(a);
- }
- String fullErrmsg = "extras="+extras+"; missing="+missing
- + (logDuplicates ? "; duplicates="+MutableSet.copyOf(duplicates) : "")
- +"; actualSize="+Iterables.size(actual)+"; expectedSize="+Iterables.size(expected)
- +"; actual="+actual+"; expected="+expected+"; "+errmsg;
- assertTrue(extras.isEmpty(), fullErrmsg);
- assertTrue(missing.isEmpty(), fullErrmsg);
- assertTrue(Iterables.size(actual) == Iterables.size(expected), fullErrmsg);
- assertTrue(actualSet.equals(expectedSet), fullErrmsg); // should be covered by extras/missing/size test
- }
-
- // --- new routines
-
- public static <T> void eventually(Supplier<? extends T> supplier, Predicate<T> predicate) {
- eventually(ImmutableMap.<String,Object>of(), supplier, predicate);
- }
-
- public static <T> void eventually(Map<String,?> flags, Supplier<? extends T> supplier, Predicate<T> predicate) {
- eventually(flags, supplier, predicate, (String)null);
- }
-
- public static <T> void eventually(Map<String,?> flags, Supplier<? extends T> supplier, Predicate<T> predicate, String errMsg) {
- Duration timeout = toDuration(flags.get("timeout"), Duration.ONE_SECOND);
- Duration period = toDuration(flags.get("period"), Duration.millis(10));
- long periodMs = period.toMilliseconds();
- long startTime = System.currentTimeMillis();
- long expireTime = startTime+timeout.toMilliseconds();
-
- boolean first = true;
- T supplied = supplier.get();
- while (first || System.currentTimeMillis() <= expireTime) {
- supplied = supplier.get();
- if (predicate.apply(supplied)) {
- return;
- }
- first = false;
- if (periodMs > 0) sleep(periodMs);
- }
- fail("supplied="+supplied+"; predicate="+predicate+(errMsg!=null?"; "+errMsg:""));
- }
-
- // TODO improve here -- these methods aren't very useful without timeouts
- public static <T> void continually(Supplier<? extends T> supplier, Predicate<T> predicate) {
- continually(ImmutableMap.<String,Object>of(), supplier, predicate);
- }
-
- public static <T> void continually(Map<String,?> flags, Supplier<? extends T> supplier, Predicate<? super T> predicate) {
- continually(flags, supplier, predicate, (String)null);
- }
-
- public static <T> void continually(Map<String,?> flags, Supplier<? extends T> supplier, Predicate<T> predicate, String errMsg) {
- Duration duration = toDuration(flags.get("timeout"), Duration.ONE_SECOND);
- Duration period = toDuration(flags.get("period"), Duration.millis(10));
- long periodMs = period.toMilliseconds();
- long startTime = System.currentTimeMillis();
- long expireTime = startTime+duration.toMilliseconds();
-
- boolean first = true;
- while (first || System.currentTimeMillis() <= expireTime) {
- assertTrue(predicate.apply(supplier.get()), "supplied="+supplier.get()+"; predicate="+predicate+(errMsg!=null?"; "+errMsg:""));
- if (periodMs > 0) sleep(periodMs);
- first = false;
- }
- }
-
-
- /**
- * Asserts given runnable succeeds in default duration.
- * @see #DEFAULT_TIMEOUT
- */
- public static void succeedsEventually(Runnable r) {
- succeedsEventually(ImmutableMap.<String,Object>of(), r);
- }
-
- public static void succeedsEventually(Map<String,?> flags, Runnable r) {
- succeedsEventually(flags, toCallable(r));
- }
-
- /**
- * Asserts given callable succeeds (runs without failure) in default duration.
- * @see #DEFAULT_TIMEOUT
- */
- public static <T> T succeedsEventually(Callable<T> c) {
- return succeedsEventually(ImmutableMap.<String,Object>of(), c);
- }
-
- // FIXME duplication with TestUtils.BooleanWithMessage
- public static class BooleanWithMessage {
- boolean value; String message;
- public BooleanWithMessage(boolean value, String message) {
- this.value = value; this.message = message;
- }
- public boolean asBoolean() {
- return value;
- }
- public String toString() {
- return message;
- }
- }
-
- /**
- * Convenience method for cases where we need to test until something is true.
- *
- * The runnable will be invoked periodically until it succesfully concludes.
- * <p>
- * The following flags are supported:
- * <ul>
- * <li>abortOnError (boolean, default true)
- * <li>abortOnException - (boolean, default false)
- * <li>timeout - (a Duration or an integer in millis, defaults to 30*SECONDS)
- * <li>period - (a Duration or an integer in millis, for fixed retry time; if not set, defaults to exponentially increasing from 1 to 500ms)
- * <li>minPeriod - (a Duration or an integer in millis; only used if period not explicitly set; the minimum period when exponentially increasing; defaults to 1ms)
- * <li>maxPeriod - (a Duration or an integer in millis; only used if period not explicitly set; the maximum period when exponentially increasing; defaults to 500ms)
- * <li>maxAttempts - (integer, Integer.MAX_VALUE)
- * </ul>
- *
- * The following flags are deprecated:
- * <ul>
- * <li>useGroovyTruth - (defaults to false; any result code apart from 'false' will be treated as success including null; ignored for Runnables which aren't Callables)
- * </ul>
- *
- * @param flags, accepts the flags listed above
- * @param r
- * @param finallyBlock
- */
- public static <T> T succeedsEventually(Map<String,?> flags, Callable<T> c) {
- boolean abortOnException = get(flags, "abortOnException", false);
- boolean abortOnError = get(flags, "abortOnError", false);
- boolean useGroovyTruth = get(flags, "useGroovyTruth", false);
- boolean logException = get(flags, "logException", true);
-
- // To speed up tests, default is for the period to start small and increase...
- Duration duration = toDuration(flags.get("timeout"), DEFAULT_TIMEOUT);
- Duration fixedPeriod = toDuration(flags.get("period"), null);
- Duration minPeriod = (fixedPeriod != null) ? fixedPeriod : toDuration(flags.get("minPeriod"), Duration.millis(1));
- Duration maxPeriod = (fixedPeriod != null) ? fixedPeriod : toDuration(flags.get("maxPeriod"), Duration.millis(500));
- int maxAttempts = get(flags, "maxAttempts", Integer.MAX_VALUE);
- int attempt = 0;
- long startTime = System.currentTimeMillis();
- try {
- Throwable lastException = null;
- T result = null;
- long lastAttemptTime = 0;
- long expireTime = startTime+duration.toMilliseconds();
- long sleepTimeBetweenAttempts = minPeriod.toMilliseconds();
-
- while (attempt < maxAttempts && lastAttemptTime < expireTime) {
- try {
- attempt++;
- lastAttemptTime = System.currentTimeMillis();
- result = c.call();
- if (log.isTraceEnabled()) log.trace("Attempt {} after {} ms: {}", new Object[] {attempt, System.currentTimeMillis() - startTime, result});
- if (useGroovyTruth) {
- if (groovyTruth(result)) return result;
- } else if (Boolean.FALSE.equals(result)) {
- if (result instanceof BooleanWithMessage)
- log.warn("Test returned an instance of BooleanWithMessage but useGroovyTruth is not set! " +
- "The result of this probably isn't what you intended.");
- // FIXME surprising behaviour, "false" result here is acceptable
- return result;
- } else {
- return result;
- }
- lastException = null;
- } catch(Throwable e) {
- lastException = e;
- if (log.isTraceEnabled()) log.trace("Attempt {} after {} ms: {}", new Object[] {attempt, System.currentTimeMillis() - startTime, e.getMessage()});
- if (abortOnException) throw e;
- if (abortOnError && e instanceof Error) throw e;
- }
- long sleepTime = Math.min(sleepTimeBetweenAttempts, expireTime-System.currentTimeMillis());
- if (sleepTime > 0) Thread.sleep(sleepTime);
- sleepTimeBetweenAttempts = Math.min(sleepTimeBetweenAttempts*2, maxPeriod.toMilliseconds());
- }
-
- log.info("succeedsEventually exceeded max attempts or timeout - {} attempts lasting {} ms, for {}", new Object[] {attempt, System.currentTimeMillis()-startTime, c});
- if (lastException != null)
- throw lastException;
- throw fail("invalid result: "+result);
- } catch (Throwable t) {
- if (logException) log.info("failed succeeds-eventually, "+attempt+" attempts, "+
- (System.currentTimeMillis()-startTime)+"ms elapsed "+
- "(rethrowing): "+t);
- throw propagate(t);
- }
- }
-
- public static <T> void succeedsContinually(Runnable r) {
- succeedsContinually(ImmutableMap.<String,Object>of(), r);
- }
-
- public static <T> void succeedsContinually(Map<?,?> flags, Runnable r) {
- succeedsContinually(flags, toCallable(r));
- }
-
- public static <T> T succeedsContinually(Callable<T> c) {
- return succeedsContinually(ImmutableMap.<String,Object>of(), c);
- }
-
- public static <T> T succeedsContinually(Map<?,?> flags, Callable<T> job) {
- Duration duration = toDuration(flags.get("timeout"), Duration.ONE_SECOND);
- Duration period = toDuration(flags.get("period"), Duration.millis(10));
- long periodMs = period.toMilliseconds();
- long startTime = System.currentTimeMillis();
- long expireTime = startTime+duration.toMilliseconds();
- int attempt = 0;
-
- boolean first = true;
- T result = null;
- while (first || System.currentTimeMillis() <= expireTime) {
- attempt++;
- try {
- result = job.call();
- } catch (Exception e) {
- log.info("succeedsContinually failed - {} attempts lasting {} ms, for {} (rethrowing)", new Object[] {attempt, System.currentTimeMillis()-startTime, job});
- throw propagate(e);
- }
- if (periodMs > 0) sleep(periodMs);
- first = false;
- }
- return result;
- }
-
- private static Duration toDuration(Object duration, Duration defaultVal) {
- if (duration == null)
- return defaultVal;
- else
- return Duration.of(duration);
- }
-
- public static void assertFails(Runnable r) {
- assertFailsWith(toCallable(r), Predicates.alwaysTrue());
- }
-
- public static void assertFails(Callable<?> c) {
- assertFailsWith(c, Predicates.alwaysTrue());
- }
-
- public static void assertFailsWith(Callable<?> c, final Closure<Boolean> exceptionChecker) {
- assertFailsWith(c, new Predicate<Throwable>() {
- public boolean apply(Throwable input) {
- return exceptionChecker.call(input);
- }
- });
- }
-
- public static void assertFailsWith(Runnable c, final Class<? extends Throwable> validException, final Class<? extends Throwable> ...otherValidExceptions) {
- final List<Class<?>> validExceptions = ImmutableList.<Class<?>>builder()
- .add(validException)
- .addAll(ImmutableList.copyOf(otherValidExceptions))
- .build();
-
- assertFailsWith(c, new Predicate<Throwable>() {
- public boolean apply(Throwable e) {
- for (Class<?> validException: validExceptions) {
- if (validException.isInstance(e)) return true;
- }
- fail("Test threw exception of unexpected type "+e.getClass()+"; expecting "+validExceptions);
- return false;
- }
- });
- }
-
- public static void assertFailsWith(Runnable r, Predicate<? super Throwable> exceptionChecker) {
- assertFailsWith(toCallable(r), exceptionChecker);
- }
-
- public static void assertFailsWith(Callable<?> c, Predicate<? super Throwable> exceptionChecker) {
- boolean failed = false;
- try {
- c.call();
- } catch (Throwable e) {
- failed = true;
- if (!exceptionChecker.apply(e)) {
- log.debug("Test threw invalid exception (failing)", e);
- fail("Test threw invalid exception: "+e);
- }
- log.debug("Test for exception successful ("+e+")");
- }
- if (!failed) fail("Test code should have thrown exception but did not");
- }
-
- public static void assertReturnsEventually(final Runnable r, Duration timeout) throws InterruptedException, ExecutionException, TimeoutException {
- final AtomicReference<Throwable> throwable = new AtomicReference<Throwable>();
- Runnable wrappedR = new Runnable() {
- @Override public void run() {
- try {
- r.run();
- } catch (Throwable t) {
- throwable.set(t);
- throw Exceptions.propagate(t);
- }
- }
- };
- Thread thread = new Thread(wrappedR, "assertReturnsEventually("+r+")");
- try {
- thread.start();
- thread.join(timeout.toMilliseconds());
- if (thread.isAlive()) {
- throw new TimeoutException("Still running: r="+r+"; thread="+Arrays.toString(thread.getStackTrace()));
- }
- } catch (InterruptedException e) {
- throw Exceptions.propagate(e);
- } finally {
- thread.interrupt();
- }
-
- if (throwable.get() != null) {
- throw new ExecutionException(throwable.get());
- }
- }
-
- public static <T> void assertThat(T object, Predicate<T> condition) {
- if (condition.apply(object)) return;
- fail("Failed "+condition+": "+object);
- }
-
- @SuppressWarnings("rawtypes")
- private static boolean groovyTruth(Object o) {
- // TODO Doesn't handle matchers (see http://docs.codehaus.org/display/GROOVY/Groovy+Truth)
- if (o == null) {
- return false;
- } else if (o instanceof Boolean) {
- return (Boolean)o;
- } else if (o instanceof String) {
- return !((String)o).isEmpty();
- } else if (o instanceof Collection) {
- return !((Collection)o).isEmpty();
- } else if (o instanceof Map) {
- return !((Map)o).isEmpty();
- } else if (o instanceof Iterator) {
- return ((Iterator)o).hasNext();
- } else if (o instanceof Enumeration) {
- return ((Enumeration)o).hasMoreElements();
- } else {
- return true;
- }
- }
-
- @SuppressWarnings("unchecked")
- private static <T> T get(Map<String,?> map, String key, T defaultVal) {
- Object val = map.get(key);
- return (T) ((val == null) ? defaultVal : val);
- }
-
- private static Callable<?> toCallable(Runnable r) {
- return (r instanceof Callable) ? (Callable<?>)r : new RunnableAdapter<Void>(r, null);
- }
-
- /** Same as {@link java.util.concurrent.Executors#callable(Runnable)}, except includes toString() */
- static final class RunnableAdapter<T> implements Callable<T> {
- final Runnable task;
- final T result;
- RunnableAdapter(Runnable task, T result) {
- this.task = task;
- this.result = result;
- }
- public T call() {
- task.run();
- return result;
- }
- @Override
- public String toString() {
- return "RunnableAdapter("+task+")";
- }
- }
-
- private static void sleep(long periodMs) {
- if (periodMs > 0) {
- try {
- Thread.sleep(periodMs);
- } catch (InterruptedException e) {
- throw propagate(e);
- }
- }
- }
-
- private static RuntimeException propagate(Throwable t) {
- if (t instanceof InterruptedException) {
- Thread.currentThread().interrupt();
- }
- if (t instanceof RuntimeException) throw (RuntimeException)t;
- if (t instanceof Error) throw (Error)t;
- throw new RuntimeException(t);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/CommandLineUtil.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/CommandLineUtil.java b/utils/common/src/main/java/brooklyn/util/CommandLineUtil.java
deleted file mode 100644
index 6ccdc2f..0000000
--- a/utils/common/src/main/java/brooklyn/util/CommandLineUtil.java
+++ /dev/null
@@ -1,53 +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;
-
-import java.util.List;
-
-// FIXME move to brooklyn.util.cli.CommandLineArgs, and change get to "remove"
-public class CommandLineUtil {
-
- public static String getCommandLineOption (List<String> args, String param){
- return getCommandLineOption(args, param, null);
- }
-
- /** given a list of args, e.g. --name Foo --parent Bob
- * will return "Foo" as param name, and remove those entries from the args list
- */
- public static String getCommandLineOption(List<String> args, String param, String defaultValue) {
- int i = args.indexOf(param);
- if (i >= 0) {
- String result = args.get(i + 1);
- args.remove(i + 1);
- args.remove(i);
- return result;
- } else {
- return defaultValue;
- }
- }
-
- public static int getCommandLineOptionInt(List<String> args, String param, int defaultValue) {
- String s = getCommandLineOption(args, param,null);
- if (s == null) return defaultValue;
- return Integer.parseInt(s);
- }
-
- //we don't want instances.
- private CommandLineUtil(){}
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/JavaGroovyEquivalents.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/JavaGroovyEquivalents.java b/utils/common/src/main/java/brooklyn/util/JavaGroovyEquivalents.java
deleted file mode 100644
index 293cd7b..0000000
--- a/utils/common/src/main/java/brooklyn/util/JavaGroovyEquivalents.java
+++ /dev/null
@@ -1,181 +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;
-
-import groovy.lang.Closure;
-import groovy.lang.GString;
-import groovy.time.TimeDuration;
-
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.Executors;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.util.time.Duration;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-
-// FIXME move to brooklyn.util.groovy
-public class JavaGroovyEquivalents {
-
- private static final Logger log = LoggerFactory.getLogger(JavaGroovyEquivalents.class);
-
- public static String join(Collection<?> collection, String separator) {
- StringBuffer result = new StringBuffer();
- Iterator<?> ci = collection.iterator();
- if (ci.hasNext()) result.append(asNonnullString(ci.next()));
- while (ci.hasNext()) {
- result.append(separator);
- result.append(asNonnullString(ci.next()));
- }
- return result.toString();
- }
-
- /** simple elvislike operators; uses groovy truth */
- @SuppressWarnings("unchecked")
- public static <T> Collection<T> elvis(Collection<T> preferred, Collection<?> fallback) {
- // TODO Would be nice to not cast, but this is groovy equivalent! Let's fix generics in stage 2
- return groovyTruth(preferred) ? preferred : (Collection<T>) fallback;
- }
- public static String elvis(String preferred, String fallback) {
- return groovyTruth(preferred) ? preferred : fallback;
- }
- public static String elvisString(Object preferred, Object fallback) {
- return elvis(asString(preferred), asString(fallback));
- }
- public static <T> T elvis(T preferred, T fallback) {
- return groovyTruth(preferred) ? preferred : fallback;
- }
- public static <T> T elvis(Iterable<?> preferences) {
- return elvis(Iterables.toArray(preferences, Object.class));
- }
- public static <T> T elvis(Object... preferences) {
- if (preferences.length == 0) throw new IllegalArgumentException("preferences must not be empty for elvis");
- for (Object contender : preferences) {
- if (groovyTruth(contender)) return (T) fix(contender);
- }
- return (T) fix(preferences[preferences.length-1]);
- }
-
- public static Object fix(Object o) {
- if (o instanceof GString) return (o.toString());
- return o;
- }
-
- public static String asString(Object o) {
- if (o==null) return null;
- return o.toString();
- }
- public static String asNonnullString(Object o) {
- if (o==null) return "null";
- return o.toString();
- }
-
- public static boolean groovyTruth(Collection<?> c) {
- return c != null && !c.isEmpty();
- }
- public static boolean groovyTruth(String s) {
- return s != null && !s.isEmpty();
- }
- public static boolean groovyTruth(Object o) {
- // TODO Doesn't handle matchers (see http://docs.codehaus.org/display/GROOVY/Groovy+Truth)
- if (o == null) {
- return false;
- } else if (o instanceof Boolean) {
- return (Boolean)o;
- } else if (o instanceof String) {
- return !((String)o).isEmpty();
- } else if (o instanceof Collection) {
- return !((Collection)o).isEmpty();
- } else if (o instanceof Map) {
- return !((Map)o).isEmpty();
- } else if (o instanceof Iterator) {
- return ((Iterator)o).hasNext();
- } else if (o instanceof Enumeration) {
- return ((Enumeration)o).hasMoreElements();
- } else {
- return true;
- }
- }
-
- public static <T> Predicate<T> groovyTruthPredicate() {
- return new Predicate<T>() {
- @Override public boolean apply(T val) {
- return groovyTruth(val);
- }
- };
- }
-
- public static Function<Object,Boolean> groovyTruthFunction() {
- return new Function<Object, Boolean>() {
- @Override public Boolean apply(Object input) {
- return groovyTruth(input);
- }
- };
- }
-
- public static <K,V> Map<K,V> mapOf(K key1, V val1) {
- Map<K,V> result = Maps.newLinkedHashMap();
- result.put(key1, val1);
- return result;
- }
-
- /** @deprecated since 0.6.0 use {@link Duration#of(Object)} */
- @Deprecated
- public static TimeDuration toTimeDuration(Object duration) {
- // TODO Lazy coding here for large number values; but refactoring away from groovy anyway...
-
- if (duration == null) {
- return null;
- } else if (duration instanceof TimeDuration) {
- return (TimeDuration) duration;
- } else if (duration instanceof Number) {
- long d = ((Number)duration).longValue();
- if (d <= Integer.MAX_VALUE && d >= Integer.MIN_VALUE) {
- return new TimeDuration(0,0,0,(int)d);
- } else {
- log.warn("Number "+d+" too large to convert to TimeDuration; using Integer.MAX_VALUE instead");
- return new TimeDuration(0,0,0,Integer.MAX_VALUE);
- }
- } else {
- throw new IllegalArgumentException("Cannot convert "+duration+" of type "+duration.getClass().getName()+" to a TimeDuration");
- }
- }
-
- public static <T> Predicate<T> toPredicate(final Closure<Boolean> c) {
- return new Predicate<T>() {
- @Override public boolean apply(T input) {
- return c.call(input);
- }
- };
- }
-
- @SuppressWarnings("unchecked")
- public static <T> Callable<T> toCallable(final Runnable job) {
- return (Callable<T>) ((job instanceof Callable) ? (Callable<T>)job : Executors.callable(job));
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/ShellUtils.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/ShellUtils.java b/utils/common/src/main/java/brooklyn/util/ShellUtils.java
deleted file mode 100644
index 2c53f93..0000000
--- a/utils/common/src/main/java/brooklyn/util/ShellUtils.java
+++ /dev/null
@@ -1,181 +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;
-
-import groovy.io.GroovyPrintStream;
-import groovy.time.TimeDuration;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.slf4j.Logger;
-
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.stream.StreamGobbler;
-import brooklyn.util.stream.Streams;
-import brooklyn.util.text.Strings;
-
-import com.google.common.collect.Maps;
-import com.google.common.io.Closer;
-
-/**
- * @deprecated since 0.7; does not return exit status, stderr, etc, so utility is of very limited use; and is not used in core brooklyn at all!;
- * use ProcessTool or SystemProcessTaskFactory.
- */
-@Deprecated
-public class ShellUtils {
-
- public static long TIMEOUT = 60*1000;
-
- /**
- * Executes the given command.
- * <p>
- * Uses {@code bash -l -c cmd} (to have a good PATH set), and defaults for other fields.
- * <p>
- * requires a logger and a context object (whose toString is used in the logger and in error messages)
- * optionally takes a string to use as input to the command
- *
- * @see {@link #exec(String, String, Logger, Object)}
- */
- public static String[] exec(String cmd, Logger log, Object context) {
- return exec(cmd, null, log, context);
- }
- /** @see {@link #exec(String[], String[], File, String, Logger, Object)} */
- public static String[] exec(String cmd, String input, Logger log, Object context) {
- return exec(new String[] { "bash", "-l", "-c", cmd }, null, null, input, log, context);
- }
- /** @see {@link #exec(Map, String[], String[], File, String, Logger, Object)} */
- public static String[] exec(Map flags, String cmd, Logger log, Object context) {
- return exec(flags, new String[] { "bash", "-l", "-c", cmd }, null, null, null, log, context);
- }
- /** @see {@link #exec(Map, String[], String[], File, String, Logger, Object)} */
- public static String[] exec(Map flags, String cmd, String input, Logger log, Object context) {
- return exec(flags, new String[] { "bash", "-l", "-c", cmd }, null, null, input, log, context);
- }
- /** @see {@link #exec(Map, String[], String[], File, String, Logger, Object)} */
- public static String[] exec(String[] cmd, String[] envp, File dir, String input, Logger log, Object context) {
- return exec(Maps.newLinkedHashMap(), cmd, envp, dir, input, log, context);
- }
-
- private static long getTimeoutMs(Map flags) {
- long timeout = TIMEOUT;
-
- Object tf = flags.get("timeout");
-
- if (tf instanceof Number) {
- timeout = ((Number) tf).longValue();
- } else if (tf instanceof TimeDuration) {
- timeout = ((TimeDuration) tf).toMilliseconds();
- }
-
- //if (tf != null) timeout = tf;
-
- return timeout;
- }
-
- /**
- * Executes the given command.
- * <p>
- * Uses the given environmnet (inherited if null) and cwd ({@literal .} if null),
- * feeding it the given input stream (if not null) and logging I/O at debug (if not null).
- * <p>
- * flags: timeout (Duration), 0 for forever; default 60 seconds
- *
- * @throws IllegalStateException if return code non-zero
- * @return lines from stdout.
- */
- public static String[] exec(Map flags, final String[] cmd, String[] envp, File dir, String input, final Logger log, final Object context) {
- if (log.isDebugEnabled()) {
- log.debug("Running local command: {}% {}", context, Strings.join(cmd, " "));
- }
- Closer closer = Closer.create();
- try {
- final Process proc = Runtime.getRuntime().exec(cmd, envp, dir); // Call *execute* on the string
- ByteArrayOutputStream stdoutB = new ByteArrayOutputStream();
- ByteArrayOutputStream stderrB = new ByteArrayOutputStream();
- PrintStream stdoutP = new GroovyPrintStream(stdoutB);
- PrintStream stderrP = new GroovyPrintStream(stderrB);
- @SuppressWarnings("resource")
- StreamGobbler stdoutG = new StreamGobbler(proc.getInputStream(), stdoutP, log).setLogPrefix("["+context+":stdout] ");
- stdoutG.start();
- closer.register(stdoutG);
- @SuppressWarnings("resource")
- StreamGobbler stderrG = new StreamGobbler(proc.getErrorStream(), stderrP, log).setLogPrefix("["+context+":stderr] ");
- stderrG.start();
- closer.register(stderrG);
- if (input!=null && input.length()>0) {
- proc.getOutputStream().write(input.getBytes());
- proc.getOutputStream().flush();
- }
-
- final long timeout = getTimeoutMs(flags);
- final AtomicBoolean ended = new AtomicBoolean(false);
- final AtomicBoolean killed = new AtomicBoolean(false);
-
- //if a timeout was specified, this thread will kill the process. This is a work around because the process.waitFor'
- //doesn't accept a timeout.
- Thread timeoutThread = new Thread(new Runnable() {
- public void run() {
- if (timeout <= 0) return;
- try {
- Thread.sleep(timeout);
- if (!ended.get()) {
- if (log.isDebugEnabled()) {
- log.debug("Timeout exceeded for "+context+"% "+Strings.join(cmd, " "));
- }
- proc.destroy();
- killed.set(true);
- }
- } catch (Exception e) { }
- }
- });
- if (timeout > 0) timeoutThread.start();
- int exitCode = proc.waitFor();
- ended.set(true);
- if (timeout > 0) timeoutThread.interrupt();
-
- stdoutG.blockUntilFinished();
- stderrG.blockUntilFinished();
- if (exitCode!=0 || killed.get()) {
- String message = killed.get() ? "terminated after timeout" : "exit code "+exitCode;
- if (log.isDebugEnabled()) {
- log.debug("Completed local command (problem, throwing): "+context+"% "+Strings.join(cmd, " ")+" - "+message);
- }
- String e = "Command failed ("+message+"): "+Strings.join(cmd, " ");
- log.warn(e+"\n"+stdoutB+(stderrB.size()>0 ? "\n--\n"+stderrB : ""));
- throw new IllegalStateException(e+" (details logged)");
- }
- if (log.isDebugEnabled()) {
- log.debug("Completed local command: "+context+"% "+Strings.join(cmd, " ")+" - exit code 0");
- }
- return stdoutB.toString().split("\n");
- } catch (IOException e) {
- throw Exceptions.propagate(e);
- } catch (InterruptedException e) {
- throw Exceptions.propagate(e);
- } finally {
- Streams.closeQuietly(closer);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/collections/CollectionFunctionals.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/collections/CollectionFunctionals.java b/utils/common/src/main/java/brooklyn/util/collections/CollectionFunctionals.java
deleted file mode 100644
index 2d08bd2..0000000
--- a/utils/common/src/main/java/brooklyn/util/collections/CollectionFunctionals.java
+++ /dev/null
@@ -1,242 +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.collections;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-import brooklyn.util.collections.QuorumCheck.QuorumChecks;
-
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.base.Supplier;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-
-/** things which it seems should be in guava, but i can't find
- * @author alex */
-public class CollectionFunctionals {
-
- private static final class EqualsSetPredicate implements Predicate<Iterable<?>> {
- private final Iterable<?> target;
-
- private EqualsSetPredicate(Iterable<?> target) {
- this.target = target;
- }
-
- @Override
- public boolean apply(@Nullable Iterable<?> input) {
- if (input==null) return false;
- return Sets.newHashSet(target).equals(Sets.newHashSet(input));
- }
- }
-
- private static final class KeysOfMapFunction<K> implements Function<Map<K, ?>, Set<K>> {
- @Override
- public Set<K> apply(Map<K, ?> input) {
- if (input==null) return null;
- return input.keySet();
- }
-
- @Override public String toString() { return "keys"; }
- }
-
- private static final class SizeSupplier implements Supplier<Integer> {
- private final Iterable<?> collection;
-
- private SizeSupplier(Iterable<?> collection) {
- this.collection = collection;
- }
-
- @Override
- public Integer get() {
- return Iterables.size(collection);
- }
-
- @Override public String toString() { return "sizeSupplier("+collection+")"; }
- }
-
- public static final class SizeFunction implements Function<Iterable<?>, Integer> {
- private final Integer valueIfInputNull;
-
- private SizeFunction(Integer valueIfInputNull) {
- this.valueIfInputNull = valueIfInputNull;
- }
-
- @Override
- public Integer apply(Iterable<?> input) {
- if (input==null) return valueIfInputNull;
- return Iterables.size(input);
- }
-
- @Override public String toString() { return "sizeFunction"; }
- }
-
- public static Supplier<Integer> sizeSupplier(final Iterable<?> collection) {
- return new SizeSupplier(collection);
- }
-
- public static Function<Iterable<?>, Integer> sizeFunction() { return sizeFunction(null); }
-
- public static Function<Iterable<?>, Integer> sizeFunction(final Integer valueIfInputNull) {
- return new SizeFunction(valueIfInputNull);
- }
-
- public static final class FirstElementFunction<T> implements Function<Iterable<? extends T>, T> {
- private FirstElementFunction() {
- }
-
- @Override
- public T apply(Iterable<? extends T> input) {
- if (input==null) return null;
- return Iterables.get(input, 0);
- }
-
- @Override public String toString() { return "firstElementFunction"; }
- }
-
- public static <T> Function<Iterable<? extends T>, T> firstElement() {
- return new FirstElementFunction<T>();
- }
-
- public static <K> Function<Map<K,?>,Set<K>> keys() {
- return new KeysOfMapFunction<K>();
- }
-
- public static <K> Function<Map<K, ?>, Integer> mapSize() {
- return mapSize(null);
- }
-
- public static <K> Function<Map<K, ?>, Integer> mapSize(Integer valueIfNull) {
- return Functions.compose(CollectionFunctionals.sizeFunction(valueIfNull), CollectionFunctionals.<K>keys());
- }
-
- /** default guava Equals predicate will reflect order of target, and will fail when matching against a list;
- * this treats them both as sets */
- public static Predicate<Iterable<?>> equalsSetOf(Object... target) {
- return equalsSet(Arrays.asList(target));
- }
- public static Predicate<Iterable<?>> equalsSet(final Iterable<?> target) {
- return new EqualsSetPredicate(target);
- }
-
- public static Predicate<Iterable<?>> sizeEquals(int targetSize) {
- return Predicates.compose(Predicates.equalTo(targetSize), CollectionFunctionals.sizeFunction());
- }
-
- public static Predicate<Iterable<?>> empty() {
- return sizeEquals(0);
- }
-
- public static Predicate<Iterable<?>> notEmpty() {
- return Predicates.not(empty());
- }
-
- public static <K> Predicate<Map<K,?>> mapSizeEquals(int targetSize) {
- return Predicates.compose(Predicates.equalTo(targetSize), CollectionFunctionals.<K>mapSize());
- }
-
- public static <T,I extends Iterable<T>> Function<I, List<T>> limit(final int max) {
- return new LimitFunction<T,I>(max);
- }
-
- private static final class LimitFunction<T, I extends Iterable<T>> implements Function<I, List<T>> {
- private final int max;
- private LimitFunction(int max) {
- this.max = max;
- }
- @Override
- public List<T> apply(I input) {
- if (input==null) return null;
- MutableList<T> result = MutableList.of();
- for (T i: input) {
- result.add(i);
- if (result.size()>=max)
- return result;
- }
- return result;
- }
- }
-
- // ---------
- public static <I,T extends Collection<I>> Predicate<T> contains(I item) {
- return new CollectionContains<I,T>(item);
- }
-
- private static final class CollectionContains<I,T extends Collection<I>> implements Predicate<T> {
- private final I item;
- private CollectionContains(I item) {
- this.item = item;
- }
- @Override
- public boolean apply(T input) {
- if (input==null) return false;
- return input.contains(item);
- }
- @Override
- public String toString() {
- return "contains("+item+")";
- }
- }
-
- // ---------
-
- public static <T,TT extends Iterable<T>> Predicate<TT> all(Predicate<T> attributeSatisfies) {
- return quorum(QuorumChecks.all(), attributeSatisfies);
- }
-
- public static <T,TT extends Iterable<T>> Predicate<TT> quorum(QuorumCheck quorumCheck, Predicate<T> attributeSatisfies) {
- return new QuorumSatisfies<T, TT>(quorumCheck, attributeSatisfies);
- }
-
-
- private static final class QuorumSatisfies<I,T extends Iterable<I>> implements Predicate<T> {
- private final Predicate<I> itemCheck;
- private final QuorumCheck quorumCheck;
- private QuorumSatisfies(QuorumCheck quorumCheck, Predicate<I> itemCheck) {
- this.itemCheck = Preconditions.checkNotNull(itemCheck, "itemCheck");
- this.quorumCheck = Preconditions.checkNotNull(quorumCheck, "quorumCheck");
- }
- @Override
- public boolean apply(T input) {
- if (input==null) return false;
- int sizeHealthy = 0, totalSize = 0;
- for (I item: input) {
- totalSize++;
- if (itemCheck.apply(item)) sizeHealthy++;
- }
- return quorumCheck.isQuorate(sizeHealthy, totalSize);
- }
- @Override
- public String toString() {
- return quorumCheck.toString()+"("+itemCheck+")";
- }
- }
-
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/collections/Jsonya.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/collections/Jsonya.java b/utils/common/src/main/java/brooklyn/util/collections/Jsonya.java
deleted file mode 100644
index c917bd0..0000000
--- a/utils/common/src/main/java/brooklyn/util/collections/Jsonya.java
+++ /dev/null
@@ -1,581 +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.collections;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-
-import javax.annotation.Nonnull;
-
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.text.StringEscapes.JavaStringEscapes;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Throwables;
-import com.google.common.primitives.Primitives;
-
-/** Jsonya = JSON-yet-another (tool)
- * <p>
- * provides conveniences for working with maps and lists containing maps and lists,
- * and other datatypes too, easily convertible to json.
- * <p>
- * see {@link JsonyaTest} for examples
- *
- * @since 0.6.0
- **/
-@Beta
-public class Jsonya {
-
- private Jsonya() {}
-
- /** creates a {@link Navigator} backed by the given map (focussed at the root) */
- public static <T extends Map<?,?>> Navigator<T> of(T map) {
- return new Navigator<T>(map, MutableMap.class);
- }
-
- /** creates a {@link Navigator} backed by the map at the focus of the given navigator */
- public static <T extends Map<?,?>> Navigator<T> of(Navigator<T> navigator) {
- return new Navigator<T>(navigator.getFocusMap(), MutableMap.class);
- }
-
- /** creates a {@link Navigator} backed by a newly created map;
- * the map can be accessed by {@link Navigator#getMap()} */
- public static Navigator<MutableMap<Object,Object>> newInstance() {
- return new Navigator<MutableMap<Object,Object>>(new MutableMap<Object,Object>(), MutableMap.class);
- }
- /** convenience for {@link Navigator#at(Object, Object...)} on a {@link #newInstance()} */
- public static Navigator<MutableMap<Object,Object>> at(Object ...pathSegments) {
- return newInstance().atArray(pathSegments);
- }
-
- /** as {@link #newInstance()} but using the given translator to massage objects inserted into the Jsonya structure */
- public static Navigator<MutableMap<Object,Object>> newInstanceTranslating(Function<Object,Object> translator) {
- return newInstance().useTranslator(translator);
- }
-
- /** as {@link #newInstanceTranslating(Function)} using an identity function
- * (functionally equivalent to {@link #newInstance()} but explicit about it */
- public static Navigator<MutableMap<Object,Object>> newInstanceLiteral() {
- return newInstanceTranslating(Functions.identity());
- }
-
- /** as {@link #newInstanceTranslating(Function)} using a function which only supports JSON primitives:
- * maps and collections are traversed, strings and primitives are inserted, and everything else has toString applied.
- * see {@link JsonPrimitiveDeepTranslator} */
- public static Navigator<MutableMap<Object,Object>> newInstancePrimitive() {
- return newInstanceTranslating(new JsonPrimitiveDeepTranslator());
- }
-
- /** convenience for converting an object x to something which consists only of json primitives, doing
- * {@link #toString()} on anything which is not recognised. see {@link JsonPrimitiveDeepTranslator} */
- public static Object convertToJsonPrimitive(Object x) {
- if (x==null) return null;
- if (x instanceof Map) return newInstancePrimitive().put((Map<?,?>)x).getRootMap();
- return newInstancePrimitive().put("data", x).getRootMap().get("data");
- }
-
- /** tells whether {@link #convertToJsonPrimitive(Object)} returns an object which is identical to
- * the equivalent literal json structure. this is typically equivalent to saying serializing to json then
- * deserializing will produce something where the result is equal to the input,
- * modulo a few edge cases such as longs becoming ints.
- * note that the converse (input equal to output) may not be the case,
- * e.g. if the input contains special subclasses of collections of maps who care about type preservation. */
- public static boolean isJsonPrimitiveCompatible(Object x) {
- if (x==null) return true;
- return convertToJsonPrimitive(x).equals(x);
- }
-
- @SuppressWarnings({"rawtypes","unchecked"})
- public static class Navigator<T extends Map<?,?>> {
-
- protected final Object root;
- protected final Class<? extends Map> mapType;
- protected Object focus;
- protected Stack<Object> focusStack = new Stack<Object>();
- protected Function<Object,Void> creationInPreviousFocus;
- protected Function<Object,Object> translator;
-
- public Navigator(Object backingStore, Class<? extends Map> mapType) {
- this.root = Preconditions.checkNotNull(backingStore);
- this.focus = backingStore;
- this.mapType = mapType;
- }
-
- // -------------- access and configuration
-
- /** returns the object at the focus, or null if none */
- public Object get() {
- return focus;
- }
-
- /** as {@link #get()} but always wrapped in a {@link Maybe}, absent if null */
- public @Nonnull Maybe<Object> getMaybe() {
- return Maybe.fromNullable(focus);
- }
-
- /** returns the object at the focus, casted to the given type, null if none
- * @throws ClassCastException if object exists here but of the wrong type */
- public <V> V get(Class<V> type) {
- return (V)focus;
- }
-
- /** as {@link #get(Class)} but always wrapped in a {@link Maybe}, absent if null
- * @throws ClassCastException if object exists here but of the wrong type */
- public @Nonnull <V> Maybe<V> getMaybe(Class<V> type) {
- return Maybe.fromNullable(get(type));
- }
-
- /** gets the object at the indicated path from the current focus
- * (without changing the path to that focus; use {@link #at(Object, Object...)} to change focus) */
- // Jun 2014, semantics changed so that focus does not change, which is more natural
- public Object get(Object pathSegment, Object ...furtherPathSegments) {
- push();
- at(pathSegment, furtherPathSegments);
- Object result = get();
- pop();
- return result;
- }
-
- public Navigator<T> root() {
- focus = root;
- return this;
- }
-
- /** returns the object at the root */
- public Object getRoot() {
- return root;
- }
-
- /** returns the {@link Map} at the root, throwing if root is not a map */
- public T getRootMap() {
- return (T) root;
- }
-
- /** returns a {@link Map} at the given focus, creating if needed (so never null),
- * throwing if it exists already and is not a map */
- public T getFocusMap() {
- map();
- return (T)focus;
- }
-
- /** as {@link #getFocusMap()} but always wrapped in a {@link Maybe}, absent if null
- * @throws ClassCastException if object exists here but of the wrong type */
- public @Nonnull Maybe<T> getFocusMapMaybe() {
- return Maybe.fromNullable(getFocusMap());
- }
-
- /** specifies a translator function to use when new data is added;
- * by default everything is added as a literal (ie {@link Functions#identity()}),
- * but if you want to do translation on the way in,
- * set a translation function
- * <p>
- * note that translation should be idempotent as implementation may apply it multiple times in certain cases
- */
- public Navigator<T> useTranslator(Function<Object,Object> translator) {
- this.translator = translator;
- return this;
- }
-
- protected Object translate(Object x) {
- if (translator==null) return x;
- return translator.apply(x);
- }
-
- protected Object translateKey(Object x) {
- if (translator==null) return x;
- // this could return the toString to make it strict json
- // but json libraries seem to do that so not strictly necessary
- return translator.apply(x);
- }
-
- // ------------- navigation (map mainly)
-
- /** pushes the current focus to a stack, so that this location will be restored on the corresponding {@link #pop()} */
- public Navigator<T> push() {
- focusStack.push(focus);
- return this;
- }
-
- /** pops the most recently pushed focus, so that it returns to the last location {@link #push()}ed */
- public Navigator<T> pop() {
- focus = focusStack.pop();
- return this;
- }
-
- /** returns the navigator moved to focus at the indicated key sequence in the given map */
- public Navigator<T> at(Object pathSegment, Object ...furtherPathSegments) {
- down(pathSegment);
- return atArray(furtherPathSegments);
- }
- public Navigator<T> atArray(Object[] furtherPathSegments) {
- for (Object p: furtherPathSegments)
- down(p);
- return this;
- }
-
- /** ensures the given focus is a map, creating if needed (and creating inside the list if it is in a list) */
- public Navigator<T> map() {
- if (focus==null) {
- focus = newMap();
- creationInPreviousFocus.apply(focus);
- }
- if (focus instanceof List) {
- Map m = newMap();
- ((List)focus).add(translate(m));
- focus = m;
- return this;
- }
- if (!(focus instanceof Map))
- throw new IllegalStateException("focus here is "+focus+"; expected a map");
- return this;
- }
-
- /** puts the given key-value pair at the current focus (or multiple such),
- * creating a map if needed, replacing any values stored against keys supplied here;
- * if you wish to merge deep maps, see {@link #add(Object, Object...)} */
- public Navigator<T> put(Object k1, Object v1, Object ...kvOthers) {
- map();
- putInternal((Map)focus, k1, v1, kvOthers);
- return this;
- }
-
- public Navigator<T> putIfNotNull(Object k1, Object v1) {
- if (v1!=null) {
- map();
- putInternal((Map)focus, k1, v1);
- }
- return this;
- }
-
- protected void putInternal(Map target, Object k1, Object v1, Object ...kvOthers) {
- assert (kvOthers.length % 2) == 0 : "even number of arguments required for put";
- target.put(translateKey(k1), translate(v1));
- for (int i=0; i<kvOthers.length; ) {
- target.put(translateKey(kvOthers[i++]), translate(kvOthers[i++]));
- }
- }
-
- /** as {@link #put(Object, Object, Object...)} for the kv-pairs in the given map; ignores null for convenience */
- public Navigator<T> put(Map map) {
- map();
- if (map==null) return this;
- ((Map)focus).putAll((Map)translate(map));
- return this;
- }
-
- protected Map newMap() {
- try {
- return mapType.newInstance();
- } catch (Exception e) {
- throw Throwables.propagate(e);
- }
- }
-
- /** utility for {@link #at(Object, Object...)}, taking one argument at a time */
- protected Navigator<T> down(final Object pathSegment) {
- if (focus instanceof List) {
- return downList(pathSegment);
- }
- if ((focus instanceof Map) || focus==null) {
- return downMap(pathSegment);
- }
- throw new IllegalStateException("focus here is "+focus+"; cannot descend to '"+pathSegment+"'");
- }
-
- protected Navigator<T> downMap(Object pathSegmentO) {
- final Object pathSegment = translateKey(pathSegmentO);
- final Map givenParentMap = (Map)focus;
- if (givenParentMap!=null) {
- creationInPreviousFocus = null;
- focus = givenParentMap.get(pathSegment);
- }
- if (focus==null) {
- final Function<Object, Void> previousCreation = creationInPreviousFocus;
- creationInPreviousFocus = new Function<Object, Void>() {
- public Void apply(Object input) {
- creationInPreviousFocus = null;
- Map parentMap = givenParentMap;
- if (parentMap==null) {
- parentMap = newMap();
- previousCreation.apply(parentMap);
- }
- parentMap.put(pathSegment, translate(input));
- return null;
- }
- };
- }
- return this;
- }
-
- protected Navigator<T> downList(final Object pathSegment) {
- if (!(pathSegment instanceof Integer))
- throw new IllegalStateException("focus here is a list ("+focus+"); cannot descend to '"+pathSegment+"'");
- final List givenParentList = (List)focus;
- // previous focus always non-null
- creationInPreviousFocus = null;
- focus = givenParentList.get((Integer)pathSegment);
- if (focus==null) {
- // don't need to worry about creation here; we don't create list entries simply by navigating
- // TODO a nicer architecture would create a new object with focus for each traversal
- // in that case we could create, filling other positions with null; but is there a need?
- creationInPreviousFocus = new Function<Object, Void>() {
- public Void apply(Object input) {
- throw new IllegalStateException("cannot create "+input+" here because we are at a non-existent position in a list");
- }
- };
- }
- return this;
- }
-
- // ------------- navigation (list mainly)
-
- /** ensures the given focus is a list */
- public Navigator<T> list() {
- if (focus==null) {
- focus = newList();
- creationInPreviousFocus.apply(focus);
- }
- if (!(focus instanceof List))
- throw new IllegalStateException("focus here is "+focus+"; expected a list");
- return this;
- }
-
- protected List newList() {
- return new ArrayList();
- }
-
- /** adds the given items to the focus, whether a list or a map,
- * creating the focus as a map if it doesn't already exist.
- * to add items to a list which might not exist, precede by a call to {@link #list()}.
- * <p>
- * when adding items to a list, iterable and array arguments are flattened because
- * that makes the most sense when working with deep maps (adding one map to another where both contain lists, for example);
- * to prevent flattening use {@link #addUnflattened(Object, Object...)}
- * <p>
- * when adding to a map, arguments will be treated as things to put into the map,
- * accepting either multiple arguments, as key1, value1, key2, value2, ...
- * (and must be an event number); or a single argument which must be a map,
- * in which case the value for each key in the supplied map is added to any existing value against that key in the target map
- * (in other words, it will do a "deep put", where nested maps are effectively merged)
- * <p>
- * this implementation will currently throw if you attempt to add a non-map to anything present which is not a list;
- * auto-conversion to a list may be added in a future version
- * */
- public Navigator<T> add(Object o1, Object ...others) {
- if (focus==null) map();
- addInternal(focus, focus, o1, others);
- return this;
- }
-
- /** adds the given arguments to a list at this point (will not descend into maps, and will not flatten lists) */
- public Navigator<T> addUnflattened(Object o1, Object ...others) {
- ((Collection)focus).add(translate(o1));
- for (Object oi: others) ((Collection)focus).add(translate(oi));
- return this;
- }
-
- protected void addInternal(Object initialFocus, Object currentFocus, Object o1, Object ...others) {
- if (currentFocus instanceof Map) {
- Map target = (Map)currentFocus;
- Map source;
- if (others.length==0) {
- // add as a map
- if (o1==null)
- // ignore if null
- return ;
- if (!(o1 instanceof Map))
- throw new IllegalStateException("cannot add: focus here is "+currentFocus+" (in "+initialFocus+"); expected a collection, or a map (with a map being added, not "+o1+")");
- source = (Map)translate(o1);
- } else {
- // build a source map from the arguments as key-value pairs
- if ((others.length % 2)==0)
- throw new IllegalArgumentException("cannot add an odd number of arguments to a map" +
- " ("+o1+" then "+Arrays.toString(others)+" in "+currentFocus+" in "+initialFocus+")");
- source = MutableMap.of(translateKey(o1), translate(others[0]));
- for (int i=1; i<others.length; )
- source.put(translateKey(others[i++]), translate(others[i++]));
- }
- // and add the source map to the target
- for (Object entry : source.entrySet()) {
- Object key = ((Map.Entry)entry).getKey();
- Object sv = ((Map.Entry)entry).getValue();
- Object tv = target.get(key);
- if (!target.containsKey(key)) {
- target.put(key, sv);
- } else {
- addInternal(initialFocus, tv, sv);
- }
- }
- return;
- }
- // lists are easy to add to, but remember we have to flatten
- if (!(currentFocus instanceof Collection))
- // TODO a nicer architecture might replace the current target with a list (also above where single non-map argument is supplied)
- throw new IllegalStateException("cannot add: focus here is "+currentFocus+"; expected a collection");
- addFlattened((Collection)currentFocus, o1);
- for (Object oi: others) addFlattened((Collection)currentFocus, oi);
- }
-
- protected void addFlattened(Collection target, Object item) {
- if (item instanceof Iterable) {
- for (Object i: (Iterable)item)
- addFlattened(target, i);
- return;
- }
- if (item.getClass().isArray()) {
- for (Object i: ((Object[])item))
- addFlattened(target, i);
- return;
- }
- // nothing to flatten
- target.add(translate(item));
- }
-
- /** Returns JSON serialized output for given focus in the given jsonya;
- * applies a naive toString for specialized types */
- @Override
- public String toString() {
- return render(get());
- }
- }
-
- public static String render(Object focus) {
- if (focus instanceof Map) {
- StringBuilder sb = new StringBuilder();
- sb.append("{");
- boolean first = true;
- for (Object entry: ((Map<?,?>)focus).entrySet()) {
- if (!first) sb.append(",");
- else first = false;
- sb.append(" ");
- sb.append( render(((Map.Entry<?,?>)entry).getKey()) );
- sb.append(": ");
- sb.append( render(((Map.Entry<?,?>)entry).getValue()) );
- }
- sb.append(" }");
- return sb.toString();
- }
- if (focus instanceof Collection) {
- StringBuilder sb = new StringBuilder();
- sb.append("[");
- boolean first = true;
- for (Object entry: (Collection<?>)focus) {
- if (!first) sb.append(",");
- else first = false;
- sb.append( render(entry) );
- }
- sb.append(" ]");
- return sb.toString();
- }
- if (focus instanceof String) {
- return JavaStringEscapes.wrapJavaString((String)focus);
- }
- if (focus == null || focus instanceof Number || focus instanceof Boolean)
- return ""+focus;
-
- return render(""+focus);
- }
-
- /** Converts an object to one which uses standard JSON objects where possible
- * (strings, numbers, booleans, maps, lists), and uses toString elsewhere */
- public static class JsonPrimitiveDeepTranslator implements Function<Object,Object> {
- public static JsonPrimitiveDeepTranslator INSTANCE = new JsonPrimitiveDeepTranslator();
-
- /** No need to instantiate except when subclassing. Use static {@link #INSTANCE}. */
- protected JsonPrimitiveDeepTranslator() {}
-
- @Override
- public Object apply(Object input) {
- return apply(input, new HashSet<Object>());
- }
-
- protected Object apply(Object input, Set<Object> stack) {
- if (input==null) return applyNull(stack);
-
- if (isPrimitiveOrBoxer(input.getClass()))
- return applyPrimitiveOrBoxer(input, stack);
-
- if (input instanceof String)
- return applyString((String)input, stack);
-
- stack = new HashSet<Object>(stack);
- if (!stack.add(input))
- // fail if object is self-recursive; don't even try toString as that is dangerous
- // (extra measure of safety, since maps and lists generally fail elsewhere with recursive entries,
- // eg in hashcode or toString)
- return "[REF_ANCESTOR:"+stack.getClass()+"]";
-
- if (input instanceof Collection<?>)
- return applyCollection( (Collection<?>)input, stack );
-
- if (input instanceof Map<?,?>)
- return applyMap( (Map<?,?>)input, stack );
-
- return applyOther(input, stack);
- }
-
- protected Object applyNull(Set<Object> stack) {
- return null;
- }
-
- protected Object applyPrimitiveOrBoxer(Object input, Set<Object> stack) {
- return input;
- }
-
- protected Object applyString(String input, Set<Object> stack) {
- return input.toString();
- }
-
- protected Object applyCollection(Collection<?> input, Set<Object> stack) {
- MutableList<Object> result = MutableList.of();
-
- for (Object xi: input)
- result.add(apply(xi, stack));
-
- return result;
- }
-
- protected Object applyMap(Map<?, ?> input, Set<Object> stack) {
- MutableMap<Object, Object> result = MutableMap.of();
-
- for (Map.Entry<?,?> xi: input.entrySet())
- result.put(apply(xi.getKey(), stack), apply(xi.getValue(), stack));
-
- return result;
- }
-
- protected Object applyOther(Object input, Set<Object> stack) {
- return input.toString();
- }
-
- public static boolean isPrimitiveOrBoxer(Class<?> type) {
- return Primitives.allPrimitiveTypes().contains(type) || Primitives.allWrapperTypes().contains(type);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/collections/MutableList.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/collections/MutableList.java b/utils/common/src/main/java/brooklyn/util/collections/MutableList.java
deleted file mode 100644
index c5cab8d..0000000
--- a/utils/common/src/main/java/brooklyn/util/collections/MutableList.java
+++ /dev/null
@@ -1,252 +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.collections;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.annotation.Nullable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.util.exceptions.Exceptions;
-
-import com.google.common.collect.ImmutableList;
-
-public class MutableList<V> extends ArrayList<V> {
- private static final long serialVersionUID = -5533940507175152491L;
-
- private static final Logger log = LoggerFactory.getLogger(MutableList.class);
-
- public static <V> MutableList<V> of() {
- return new MutableList<V>();
- }
-
- public static <V> MutableList<V> of(V v1) {
- MutableList<V> result = new MutableList<V>();
- result.add(v1);
- return result;
- }
-
- public static <V> MutableList<V> of(V v1, V v2, V ...vv) {
- MutableList<V> result = new MutableList<V>();
- result.add(v1);
- result.add(v2);
- for (V v: vv) result.add(v);
- return result;
- }
-
- public static <V> MutableList<V> copyOf(@Nullable Iterable<? extends V> orig) {
- return (orig instanceof Collection)
- ? new MutableList<V>((Collection<? extends V>)orig)
- : orig!=null ? new MutableList<V>(orig) : new MutableList<V>();
- }
-
- public static <E> MutableList<E> copyOf(Iterator<? extends E> elements) {
- if (!elements.hasNext()) {
- return of();
- }
- return new MutableList.Builder<E>().addAll(elements).build();
- }
-
- public MutableList() {
- }
-
- public MutableList(Collection<? extends V> source) {
- super(source);
- }
-
- public MutableList(Iterable<? extends V> source) {
- for (V s : source) {
- add(s);
- }
- }
-
- /** @deprecated since 0.7.0, use {@link #asImmutableCopy()}, or {@link #asUnmodifiable()} / {@link #asUnmodifiableCopy()} */ @Deprecated
- public ImmutableList<V> toImmutable() {
- return ImmutableList.copyOf(this);
- }
- /** creates an {@link ImmutableList} which is a copy of this list. note that the list should not contain nulls. */
- public List<V> asImmutableCopy() {
- try {
- return ImmutableList.copyOf(this);
- } catch (Exception e) {
- Exceptions.propagateIfFatal(e);
- log.warn("Error converting list to Immutable, using unmodifiable instead: "+e, e);
- return asUnmodifiableCopy();
- }
- }
- /** creates a {@link Collections#unmodifiableList(List)} wrapper around this list. the method is efficient,
- * as there is no copying, but the returned view might change if the list here is changed. */
- public List<V> asUnmodifiable() {
- return Collections.unmodifiableList(this);
- }
- /** creates a {@link Collections#unmodifiableList(List)} of a copy of this list.
- * the returned item is immutable, but unlike {@link #asImmutableCopy()} nulls are permitted. */
- public List<V> asUnmodifiableCopy() {
- return Collections.unmodifiableList(MutableList.copyOf(this));
- }
-
- public static <V> Builder<V> builder() {
- return new Builder<V>();
- }
-
- /**
- * @see guava's ImMutableList.Builder
- */
- public static class Builder<V> {
- final MutableList<V> result = new MutableList<V>();
-
- public Builder() {}
-
- public Builder<V> add(V value) {
- result.add(value);
- return this;
- }
-
- public Builder<V> add(V value1, V value2, V ...values) {
- result.add(value1);
- result.add(value2);
- for (V v: values) result.add(v);
- return this;
- }
-
- public Builder<V> remove(V val) {
- result.remove(val);
- return this;
- }
-
- public Builder<V> addAll(Iterable<? extends V> iterable) {
- if (iterable instanceof Collection) {
- result.addAll((Collection<? extends V>) iterable);
- } else {
- for (V v : iterable) {
- result.add(v);
- }
- }
- return this;
- }
-
- public Builder<V> addAll(Iterator<? extends V> iter) {
- while (iter.hasNext()) {
- add(iter.next());
- }
- return this;
- }
-
- public Builder<V> addAll(V[] vals) {
- for (V v : vals) {
- result.add(v);
- }
- return this;
- }
-
- public Builder<V> removeAll(Iterable<? extends V> iterable) {
- if (iterable instanceof Collection) {
- result.removeAll((Collection<? extends V>) iterable);
- } else {
- for (V v : iterable) {
- result.remove(v);
- }
- }
- return this;
- }
-
- public MutableList<V> build() {
- return new MutableList<V>(result);
- }
-
- public ImmutableList<V> buildImmutable() {
- return ImmutableList.copyOf(result);
- }
-
- public Builder<V> addLists(Iterable<? extends V> ...items) {
- for (Iterable<? extends V> item: items) {
- addAll(item);
- }
- return this;
- }
- }
-
- /** as {@link List#add(Object)} but fluent style */
- public MutableList<V> append(V item) {
- add(item);
- return this;
- }
-
- /** as {@link List#add(Object)} but excluding nulls, and fluent style */
- public MutableList<V> appendIfNotNull(V item) {
- if (item!=null) add(item);
- return this;
- }
-
- /** as {@link List#add(Object)} but accepting multiple, and fluent style */
- public MutableList<V> append(V item1, V item2, V ...items) {
- add(item1);
- add(item2);
- for (V item: items) add(item);
- return this;
- }
-
- /** as {@link List#add(Object)} but excluding nulls, accepting multiple, and fluent style */
- public MutableList<V> appendIfNotNull(V item1, V item2, V ...items) {
- if (item1!=null) add(item1);
- if (item2!=null) add(item2);
- for (V item: items)
- if (item!=null) add(item);
- return this;
- }
-
- /** as {@link List#addAll(Collection)} but fluent style */
- public MutableList<V> appendAll(Iterable<? extends V> items) {
- if (items!=null)
- for (V item: items) add(item);
- return this;
- }
- /** as {@link List#addAll(Collection)} but fluent style */
- public MutableList<V> appendAll(Iterator<? extends V> items) {
- addAll(items);
- return this;
- }
-
- public boolean addAll(Iterable<? extends V> setToAdd) {
- // copy of parent, but accepting Iterable and null
- if (setToAdd==null) return false;
- return addAll(setToAdd.iterator());
- }
- public boolean addAll(Iterator<? extends V> setToAdd) {
- if (setToAdd==null) return false;
- boolean modified = false;
- while (setToAdd.hasNext()) {
- if (add(setToAdd.next()))
- modified = true;
- }
- return modified;
- }
-
- public boolean removeIfNotNull(V item) {
- if (item==null) return false;
- return remove(item);
- }
-
-}