http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/collections/BoundedQueue.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/com/twitter/common/collections/BoundedQueue.java b/commons/src/main/java/com/twitter/common/collections/BoundedQueue.java deleted file mode 100644 index 5c37f1c..0000000 --- a/commons/src/main/java/com/twitter/common/collections/BoundedQueue.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.twitter.common.collections; - -import java.util.Iterator; -import java.util.concurrent.LinkedBlockingDeque; - -/** - * A limited implementation of a bounded queue. Values can be added and iterated over, and will - * automatically expire when the queue exceeds capacity. - * - * @param <T> The type that this queue contains. - * - * @author William Farner -*/ -public class BoundedQueue<T> implements Iterable<T> { - private final LinkedBlockingDeque<T> values; - - /** - * Creates a new bounded queue. - * - * @param limit Maximum number of items that can be in the queue at any time. - */ - public BoundedQueue(int limit) { - values = new LinkedBlockingDeque<T>(limit); - } - - /** - * Adds a value to head of the queue, evicting the oldest item if the queue is at capacity. - * - * @param value Value to add. - */ - public synchronized void add(T value) { - if (values.remainingCapacity() == 0) { - values.removeFirst(); - } - values.addLast(value); - } - - /** - * Removes all values from the queue. - */ - public synchronized void clear() { - values.clear(); - } - - /** - * Returns the size of the queue. - * - * @return The current queue length. - */ - public synchronized int size() { - return values.size(); - } - - @Override - public synchronized Iterator<T> iterator() { - return values.iterator(); - } - - @Override - public synchronized String toString() { - return values.toString(); - } -}
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/collections/Iterables2.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/com/twitter/common/collections/Iterables2.java b/commons/src/main/java/com/twitter/common/collections/Iterables2.java deleted file mode 100644 index 7f80c8e..0000000 --- a/commons/src/main/java/com/twitter/common/collections/Iterables2.java +++ /dev/null @@ -1,148 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.twitter.common.collections; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -import com.google.common.base.Function; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; - -/** - * Utility functions for dealing with iterables. - * - * @author William Farner - */ -public final class Iterables2 { - - private Iterables2() { - // Utility class. - } - - /** - * An iterator that zips multiple iterables into a single list iterator, filling missing values - * with a provided default. - * - * @param <T> The value type for the iterator. - */ - private static class ZippingIterator<T> implements Iterator<List<T>> { - - private final Iterable<Iterable<T>> iterables; - private final T defaultValue; - - private List<Iterator<T>> iterators = null; - private final LoadingCache<Iterator<T>, Boolean> overflowing = CacheBuilder.newBuilder().build( - new CacheLoader<Iterator<T>, Boolean>() { - @Override public Boolean load(Iterator<T> iterator) { - return false; - } - }); - - ZippingIterator(Iterable<Iterable<T>> iterables, T defaultValue) { - this.iterables = iterables; - this.defaultValue = defaultValue; - } - - private void init() { - if (iterators == null) { - // Iterables -> Iterators. - iterators = ImmutableList.copyOf(Iterables.transform(iterables, - new Function<Iterable<T>, Iterator<T>>() { - @Override public Iterator<T> apply(Iterable<T> it) { return it.iterator(); } - })); - } - } - - @Override public boolean hasNext() { - init(); - for (Iterator<T> it : iterators) { - if (it.hasNext()) { - return true; - } - } - - return false; - } - - @Override public List<T> next() { - init(); - List<T> data = new ArrayList<T>(iterators.size()); - - for (Iterator<T> it : iterators) { - if (it.hasNext()) { - data.add(it.next()); - } else { - overflowing.asMap().put(it, true); - data.add(defaultValue); - } - } - - return data; - } - - @Override public void remove() { - init(); - for (Iterator<T> it : iterators) { - if (!overflowing.getUnchecked(it)) { - it.remove(); - } - } - } - - @Override public String toString() { - return Lists.newArrayList(iterables).toString(); - } - } - - /** - * Zips multiple iterables into one iterable that will return iterators to step over - * rows of the input iterators (columns). The order of the returned values within each row will - * match the ordering of the input iterables. The iterators will iterate the length of the longest - * input iterable, filling other columns with {@code defaultValue}. - * The returned iterator is lazy, in that 'rows' are constructed as they are requested. - * - * @param iterables Columns to iterate over. - * @param defaultValue Default fill value when an input iterable is exhausted. - * @param <T> Type of value being iterated over. - * @return An iterator that iterates over rows of the input iterables. - */ - public static <T> Iterable<List<T>> zip(final Iterable<Iterable<T>> iterables, - final T defaultValue) { - - return new Iterable<List<T>>() { - @Override public Iterator<List<T>> iterator() { - return new ZippingIterator<T>(iterables, defaultValue); - } - }; - } - - /** - * Varargs convenience function to call {@link #zip(Iterable, Object)}. - * - * @param defaultValue Default fill value when an input iterable is exhausted. - * @param iterables Columns to iterate over. - * @param <T> Type of value being iterated over. - * @return An iterator that iterates over rows of the input iterables. - */ - public static <T> Iterable<List<T>> zip(T defaultValue, Iterable<T>... iterables) { - return zip(Arrays.asList(iterables), defaultValue); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/collections/Multimaps.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/com/twitter/common/collections/Multimaps.java b/commons/src/main/java/com/twitter/common/collections/Multimaps.java deleted file mode 100644 index d09cc07..0000000 --- a/commons/src/main/java/com/twitter/common/collections/Multimaps.java +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.twitter.common.collections; - -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; -import com.google.common.collect.Multiset; -import com.google.common.collect.Ordering; -import com.google.common.collect.Sets; - -/** - * Utility class for functions related to Multimaps in the java collections library. - * - * @author William Farner - */ -public final class Multimaps { - - private Multimaps() { - // Utility. - } - - /** - * Prunes a multimap based on a predicate, returning the pruned values. The input map will be - * modified. - * - * @param map The multimap to prune. - * @param filterRule The pruning rule. When the predicate returns {@code false} for an entry, it - * will be pruned, otherwise it will be retained. - * @param <K> The key type in the multimap. - * @param <V> The value type in the multimap. - * @return A new multimap, containing the pruned keys/values. - */ - public static <K, V> Multimap<K, V> prune(Multimap<K, V> map, - Predicate<? super Collection<V>> filterRule) { - Preconditions.checkNotNull(map); - Preconditions.checkNotNull(filterRule); - Multimap<K, V> pruned = ArrayListMultimap.create(); - Iterator<Map.Entry<K, Collection<V>>> asMapItr = map.asMap().entrySet().iterator(); - while (asMapItr.hasNext()) { - Map.Entry<K, Collection<V>> asMapEntry = asMapItr.next(); - if (!filterRule.apply(asMapEntry.getValue())) { - pruned.putAll(asMapEntry.getKey(), asMapEntry.getValue()); - asMapItr.remove(); - } - } - - return pruned; - } - - private static final class AtLeastSize implements Predicate<Collection<?>> { - private final int minSize; - - AtLeastSize(int minSize) { - Preconditions.checkArgument(minSize >= 0); - this.minSize = minSize; - } - - @Override - public boolean apply(Collection<?> c) { - return c.size() >= minSize; - } - } - - /** - * Convenience method to prune key/values pairs where the size of the value collection is below a - * threshold. - * - * @param map The multimap to prune. - * @param minSize The minimum size for retained value collections. - * @param <K> The key type in the multimap. - * @param <V> The value type in the multimap. - * @return A new multimap, containing the pruned keys/values. - * @throws IllegalArgumentException if minSize < 0 - */ - public static <K, V> Multimap<K, V> prune(Multimap<K, V> map, int minSize) { - return prune(map, new AtLeastSize(minSize)); - } - - /** - * Returns the set of keys associated with groups of a size greater than or equal to a given size. - * - * @param map The multimap to search. - * @param minSize The minimum size to return associated keys for. - * @param <K> The key type for the multimap. - * @return The keys associated with groups of size greater than or equal to {@code minSize}. - * @throws IllegalArgumentException if minSize < 0 - */ - public static <K> Set<K> getLargeGroups(Multimap<K, ?> map, int minSize) { - return Sets.newHashSet( - Maps.filterValues(map.asMap(), new AtLeastSize(minSize)).keySet()); - } - - /** - * Returns the set of keys associated with the largest values in the multimap. - * - * @param map The multimap to search. - * @param topValues Number of groupings to find the keys for. - * @return The keys associated with the largest groups, of maximum size {@code topValues}. - */ - public static <K> Set<K> getLargestGroups(Multimap<K, ?> map, int topValues) { - Ordering<Multiset.Entry<K>> groupOrdering = new Ordering<Multiset.Entry<K>>() { - @Override - public int compare(Multiset.Entry<K> entry1, Multiset.Entry<K> entry2) { - return entry1.getCount() - entry2.getCount(); - // overflow-safe, since sizes are nonnegative - } - }; - Set<K> topKeys = Sets.newHashSetWithExpectedSize(topValues); - for (Multiset.Entry<K> entry - : groupOrdering.greatestOf(map.keys().entrySet(), topValues)) { - topKeys.add(entry.getElement()); - } - return topKeys; - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/collections/Pair.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/com/twitter/common/collections/Pair.java b/commons/src/main/java/com/twitter/common/collections/Pair.java deleted file mode 100644 index 3de6d26..0000000 --- a/commons/src/main/java/com/twitter/common/collections/Pair.java +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.twitter.common.collections; - -import javax.annotation.Nullable; - -import com.google.common.base.Function; - -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; - - -/** - * An immutable 2-tuple with value-equals semantics. - * - * @param <A> The type of the 1st item in the pair. - * @param <B> The type of the 2nd item in the pair. - * - * @author William Farner - */ -public class Pair<A, B> { - - @Nullable - private final A first; - @Nullable - private final B second; - - /** - * Creates a new pair. - * - * @param first The first value. - * @param second The second value. - */ - public Pair(@Nullable A first, @Nullable B second) { - this.first = first; - this.second = second; - } - - @Nullable - public A getFirst() { - return first; - } - - @Nullable - public B getSecond() { - return second; - } - - @Override - public boolean equals(Object o) { - if (o == this) { return true; } - if (!(o instanceof Pair)) { return false; } - - Pair<?, ?> that = (Pair<?, ?>) o; - return new EqualsBuilder() - .append(this.first, that.first) - .append(this.second, that.second) - .isEquals(); - } - - @Override - public String toString() { - return String.format("(%s, %s)", getFirst(), getSecond()); - } - - @Override - public int hashCode() { - return new HashCodeBuilder() - .append(first) - .append(second) - .toHashCode(); - } - - /** - * Creates a function that can extract the first item of pairs of the given type parametrization. - * - * @param <S> The type of the 1st item in the pair. - * @param <T> The type of the 2nd item in the pair. - * @return A function that will extract the 1st item in a pair. - */ - public static <S, T> Function<Pair<S, T>, S> first() { - return new Function<Pair<S, T>, S>() { - @Override public S apply(Pair<S, T> pair) { - return pair.first; - } - }; - } - - /** - * Creates a function that can extract the second item of pairs of the given type parametrization. - * - * @param <S> The type of the 1st item in the pair. - * @param <T> The type of the 2nd item in the pair. - * @return A function that will extract the 2nd item in a pair. - */ - public static <S, T> Function<Pair<S, T>, T> second() { - return new Function<Pair<S, T>, T>() { - @Override public T apply(Pair<S, T> pair) { - return pair.second; - } - }; - } - - /** - * Convenience method to create a pair. - * - * @param a The first value. - * @param b The second value. - * @param <A> The type of the 1st item in the pair. - * @param <B> The type of the 2nd item in the pair. - * @return A new pair of [a, b]. - */ - public static <A, B> Pair<A, B> of(@Nullable A a, @Nullable B b) { - return new Pair<A, B>(a, b); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/inject/Bindings.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/com/twitter/common/inject/Bindings.java b/commons/src/main/java/com/twitter/common/inject/Bindings.java deleted file mode 100644 index 57654de..0000000 --- a/commons/src/main/java/com/twitter/common/inject/Bindings.java +++ /dev/null @@ -1,316 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.twitter.common.inject; - -import java.lang.annotation.Annotation; - -import javax.inject.Qualifier; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.inject.AbstractModule; -import com.google.inject.Binder; -import com.google.inject.BindingAnnotation; -import com.google.inject.Key; -import com.google.inject.Module; -import com.google.inject.PrivateModule; -import com.google.inject.TypeLiteral; -import com.google.inject.binder.LinkedBindingBuilder; -import com.google.inject.multibindings.Multibinder; -import com.google.inject.name.Names; - -/** - * A utility that helps with guice bindings. - * - * @author John Sirois - */ -public final class Bindings { - - - private Bindings() { - // utility - } - - /** - * Equivalent to calling {@code requireBinding(binder, Key.get(required, Names.named(namedKey)))}. - */ - public static void requireNamedBinding(Binder binder, Class<?> required, String namedKey) { - requireBinding(binder, Key.get(Preconditions.checkNotNull(required), - Names.named(Preconditions.checkNotNull(namedKey)))); - } - - /** - * Equivalent to calling {@code requireBinding(binder, Key.get(required))}. - */ - public static void requireBinding(Binder binder, Class<?> required) { - requireBinding(binder, Key.get(Preconditions.checkNotNull(required))); - } - - /** - * Registers {@code required} as non-optional dependency in the {@link com.google.inject.Injector} - * associated with {@code binder}. - * - * @param binder A binder to require bindings against. - * @param required The dependency that is required. - */ - public static void requireBinding(Binder binder, final Key<?> required) { - Preconditions.checkNotNull(binder); - Preconditions.checkNotNull(required); - - binder.install(new AbstractModule() { - @Override protected void configure() { - requireBinding(required); - } - }); - } - - /** - * A convenient version of {@link #exposing(Iterable, com.google.inject.Module)} when you just - * want to expose a single binding. - */ - public static Module exposing(Key<?> key, Module module) { - return exposing(ImmutableList.of(key), module); - } - - /** - * Creates a module that hides all the given module's bindings and only exposes bindings for - * the given key. - * - * @param keys The keys of the bindings to expose. - * @param module The module to hide most bindings for. - * @return A limited visibility module. - */ - public static Module exposing(final Iterable<? extends Key<?>> keys, final Module module) { - Preconditions.checkNotNull(keys); - Preconditions.checkNotNull(module); - - return new PrivateModule() { - @Override protected void configure() { - install(module); - for (Key<?> key : keys) { - expose(key); - } - } - }; - } - - /** - * A guice binding helper that allows for any combination of Class, TypeLiteral or Key binding - * without forcing guiced implementation to provide all the overloaded binding methods they would - * otherwise have to. - * - * @param <T> The type this helper can be used to bind implementations for. - */ - public interface BindHelper<T> { - - /** - * Associates this BindHelper with an Injector instance. - * - * @param binder The binder for the injector implementations will be bound in. - * @return A binding builder that can be used to bind an implementation with. - */ - LinkedBindingBuilder<T> with(Binder binder); - } - - /** - * Creates a BindHelper for the given binding key that can be used to bind a single instance. - * - * @param key The binding key the returned BindHelper can be use to bind implementations for. - * @param <T> The type the returned BindHelper can be used to bind implementations for. - * @return A BindHelper that can be used to bind an implementation with. - */ - public static <T> BindHelper<T> binderFor(final Key<T> key) { - return new BindHelper<T>() { - public LinkedBindingBuilder<T> with(Binder binder) { - return binder.bind(key); - } - }; - } - - /** - * Creates a BindHelper for the given type that can be used to add a binding of to a set. - * - * @param type The type the returned BindHelper can be use to bind implementations for. - * @param <T> The type the returned BindHelper can be used to bind implementations for. - * @return A BindHelper that can be used to bind an implementation with. - */ - public static <T> BindHelper<T> multiBinderFor(final Class<T> type) { - return new BindHelper<T>() { - public LinkedBindingBuilder<T> with(Binder binder) { - return Multibinder.newSetBinder(binder, type).addBinding(); - } - }; - } - - /** - * Checks that the given annotation instance is a {@link BindingAnnotation @BindingAnnotation}. - * - * @param annotation The annotation instance to check. - * @param <T> The type of the binding annotation. - * @return The checked binding annotation. - * @throws NullPointerException If the given {@code annotation} is null. - * @throws IllegalArgumentException If the given {@code annotation} is not a - * {@literal @BindingAnnotation}. - */ - public static <T extends Annotation> T checkBindingAnnotation(T annotation) { - Preconditions.checkNotNull(annotation); - checkBindingAnnotation(annotation.annotationType()); - return annotation; - } - - /** - * Checks that the given annotation type is a {@link BindingAnnotation @BindingAnnotation}. - * - * @param annotationType The annotation type to check. - * @param <T> The type of the binding annotation. - * @return The checked binding annotation type. - * @throws NullPointerException If the given {@code annotationType} is null. - * @throws IllegalArgumentException If the given {@code annotationType} is not a - * {@literal @BindingAnnotation}. - */ - public static <T extends Annotation> Class<T> checkBindingAnnotation(Class<T> annotationType) { - Preconditions.checkNotNull(annotationType); - boolean bindingAnnotation = annotationType.isAnnotationPresent(BindingAnnotation.class); - boolean qualifier = annotationType.isAnnotationPresent(Qualifier.class); - Preconditions.checkArgument(bindingAnnotation || qualifier, - "%s is not a @BindingAnnotation or @Qualifier", annotationType); - return annotationType; - } - - /** - * A factory for binding {@link Key keys}. - */ - public interface KeyFactory { - - /** - * Creates plain un-annotated keys. - */ - KeyFactory PLAIN = new KeyFactory() { - @Override public <T> Key<T> create(Class<T> type) { - return Key.get(type); - } - @Override public <T> Key<T> create(TypeLiteral<T> type) { - return Key.get(type); - } - }; - - /** - * Creates a key for the given type. - * - * @param type The type to create a key for. - * @param <T> The keyed type. - * @return A key. - */ - <T> Key<T> create(Class<T> type); - - /** - * Creates a key for the given type. - * - * @param type The type to create a key for. - * @param <T> The keyed type. - * @return A key. - */ - <T> Key<T> create(TypeLiteral<T> type); - } - - /** - * Creates a key factory that produces keys for a given annotation instance. - * - * @param annotation The annotation instance to apply to all keys. - * @return A key factory that creates annotated keys. - */ - public static KeyFactory annotatedKeyFactory(final Annotation annotation) { - checkBindingAnnotation(annotation); - return new KeyFactory() { - @Override public <T> Key<T> create(Class<T> type) { - return Key.get(type, annotation); - } - @Override public <T> Key<T> create(TypeLiteral<T> type) { - return Key.get(type, annotation); - } - }; - } - - /** - * Creates a key factory that produces keys for a given annotation type. - * - * @param annotationType The annotation type to apply to all keys. - * @return A key factory that creates annotated keys. - */ - public static KeyFactory annotatedKeyFactory(final Class<? extends Annotation> annotationType) { - checkBindingAnnotation(annotationType); - return new KeyFactory() { - @Override public <T> Key<T> create(Class<T> type) { - return Key.get(type, annotationType); - } - @Override public <T> Key<T> create(TypeLiteral<T> type) { - return Key.get(type, annotationType); - } - }; - } - - /** - * A utility that helps rebind keys. - */ - public static final class Rebinder { - private final Binder binder; - private final KeyFactory bindToFactory; - - /** - * Creates a Rebinder that links bindings to keys from the given {@code bindToFactory}. - * - * @param binder A binder to rebind keys in. - * @param bindToFactory A factory for the rebinding key. - */ - public Rebinder(Binder binder, KeyFactory bindToFactory) { - this.binder = Preconditions.checkNotNull(binder); - this.bindToFactory = Preconditions.checkNotNull(bindToFactory); - } - - /** - * Rebinds the given key to another, linking bindings. - * - * @param fromKey The source key to rebind. - * @return The key that {@code key} was rebound to. - */ - public <T> Key<T> rebind(Key<T> fromKey) { - Key<T> toKey = bindToFactory.create(fromKey.getTypeLiteral()); - binder.bind(toKey).to(fromKey); - requireBinding(binder, fromKey); - return toKey; - } - } - - /** - * Creates a Rebinder that rebinds keys to the given annotation instance. - * - * @param binder A binder to rebind keys in. - * @param annotation The annotation instance to rebind keys to. - * @return A Rebinder targeting the given {@code annotationType}. - */ - public static Rebinder rebinder(Binder binder, Annotation annotation) { - return new Rebinder(binder, annotatedKeyFactory(annotation)); - } - - /** - * Creates a Rebinder that rebinds keys to the given annotation type. - * - * @param binder A binder to rebind keys in. - * @param annotationType The annotation type to rebind keys to. - * @return A Rebinder targeting the given {@code annotationType}. - */ - public static Rebinder rebinder(Binder binder, Class<? extends Annotation> annotationType) { - return new Rebinder(binder, annotatedKeyFactory(annotationType)); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/inject/DefaultProvider.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/com/twitter/common/inject/DefaultProvider.java b/commons/src/main/java/com/twitter/common/inject/DefaultProvider.java deleted file mode 100644 index 446a9ba..0000000 --- a/commons/src/main/java/com/twitter/common/inject/DefaultProvider.java +++ /dev/null @@ -1,166 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.twitter.common.inject; - -import com.google.common.base.Preconditions; -import com.google.inject.AbstractModule; -import com.google.inject.Binder; -import com.google.inject.Inject; -import com.google.inject.Injector; -import com.google.inject.Key; -import com.google.inject.Provider; -import com.google.inject.TypeLiteral; -import com.google.inject.name.Named; -import com.google.inject.name.Names; - -/** - * Provider that has a default value which can be overridden. - * - * The intended use of this class is: - * <pre> - * Default installer: - * bind(DefaultProvider.makeDefaultKey(Runnable.class, "mykey").toInstance(defaultRunnable); - * DefaultProvider.bindOrElse(Runnable.class, "mykey", binder()); - * - * Custom override: - * bind(DefaultProvider.makeCustomKey(Runnable.class, "mykey")).toInstance(myCustomRunnable); - * - * Injection: - * {@literal Inject} Named("myKey") Runnable runnable; - * - * </pre> - * - * @param <T> the type of object this provides - * - * @author William Farner - * @author John Sirois - */ -public class DefaultProvider<T> implements Provider<T> { - private static final String DEFAULT_BINDING_KEY_SUFFIX = "_default"; - private static final String CUSTOM_BINDING_KEY_SUFFIX = "_custom"; - - private final Key<T> defaultProviderKey; - private final Key<T> customProviderKey; - - private Injector injector; - - public DefaultProvider(Key<T> defaultProviderKey, Key<T> customProviderKey) { - this.defaultProviderKey = Preconditions.checkNotNull(defaultProviderKey); - this.customProviderKey = Preconditions.checkNotNull(customProviderKey); - Preconditions.checkArgument(!defaultProviderKey.equals(customProviderKey)); - } - - @Inject - public void setInjector(Injector injector) { - this.injector = injector; - } - - @Override - public T get() { - Preconditions.checkNotNull(injector); - return injector.getBindings().containsKey(customProviderKey) - ? injector.getInstance(customProviderKey) - : injector.getInstance(defaultProviderKey); - } - - /** - * Creates a DefaultProvider and installs a new module to {@code binder}, which will serve as - * an indirection layer for swapping the default binding with a custom one. - * - * @param customBinding The custom binding key. - * @param defaultBinding The default binding key. - * @param exposedBinding The exposed binding key. - * @param binder The binder to install bindings to. - * @param <T> The type of binding to make. - */ - public static <T> void bindOrElse(final Key<T> customBinding, final Key<T> defaultBinding, - final Key<T> exposedBinding, Binder binder) { - Preconditions.checkNotNull(customBinding); - Preconditions.checkNotNull(defaultBinding); - Preconditions.checkNotNull(exposedBinding); - Preconditions.checkArgument(!customBinding.equals(defaultBinding) - && !customBinding.equals(exposedBinding)); - - binder.install(new AbstractModule() { - @Override protected void configure() { - Provider<T> defaultProvider = new DefaultProvider<T>(defaultBinding, customBinding); - requestInjection(defaultProvider); - bind(exposedBinding).toProvider(defaultProvider); - } - }); - } - - /** - * Convenience function for creating and installing a DefaultProvider. This will use internal - * suffixes to create names for the custom and default bindings. When bound this way, callers - * should use one of the functions such as {@link #makeDefaultBindingKey(String)} to set default - * and custom bindings. - * - * @param type The type of object to bind. - * @param exposedKey The exposed key. - * @param binder The binder to install to. - * @param <T> The type of binding to make. - */ - public static <T> void bindOrElse(TypeLiteral<T> type, String exposedKey, Binder binder) { - bindOrElse(Key.get(type, Names.named(makeCustomBindingKey(exposedKey))), - Key.get(type, Names.named(makeDefaultBindingKey(exposedKey))), - Key.get(type, Names.named(exposedKey)), - binder); - } - - /** - * Convenience method for calls to {@link #bindOrElse(TypeLiteral, String, Binder)}, that are not - * binding a parameterized type. - * - * @param type The class of the object to bind. - * @param exposedKey The exposed key. - * @param binder The binder to install to. - * @param <T> The type of binding to make. - */ - public static <T> void bindOrElse(Class<T> type, String exposedKey, Binder binder) { - bindOrElse(TypeLiteral.get(type), exposedKey, binder); - } - - public static String makeDefaultBindingKey(String rootKey) { - return rootKey + DEFAULT_BINDING_KEY_SUFFIX; - } - - public static Named makeDefaultBindingName(String rootKey) { - return Names.named(makeDefaultBindingKey(rootKey)); - } - - public static <T> Key<T> makeDefaultKey(TypeLiteral<T> type, String rootKey) { - return Key.get(type, makeDefaultBindingName(rootKey)); - } - - public static <T> Key<T> makeDefaultKey(Class<T> type, String rootKey) { - return makeDefaultKey(TypeLiteral.get(type), rootKey); - } - - public static String makeCustomBindingKey(String rootKey) { - return rootKey + CUSTOM_BINDING_KEY_SUFFIX; - } - - public static Named makeCustomBindingName(String rootKey) { - return Names.named(makeCustomBindingKey(rootKey)); - } - - public static <T> Key<T> makeCustomKey(Class<T> type, String rootKey) { - return Key.get(type, makeCustomBindingName(rootKey)); - } - - public static <T> Key<T> makeCustomKey(TypeLiteral<T> type, String rootKey) { - return Key.get(type, makeCustomBindingName(rootKey)); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/inject/ProviderMethodModule.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/com/twitter/common/inject/ProviderMethodModule.java b/commons/src/main/java/com/twitter/common/inject/ProviderMethodModule.java deleted file mode 100644 index 8406631..0000000 --- a/commons/src/main/java/com/twitter/common/inject/ProviderMethodModule.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.twitter.common.inject; - -import com.google.inject.AbstractModule; - -/** - * A convenience base class for modules that do all their binding via provider methods. - * - * @author John Sirois - */ -public abstract class ProviderMethodModule extends AbstractModule { - - /** - * Does no binding; subclasses should implement provider methods. - */ - @Override - protected final void configure() { - // noop - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/inject/TimedInterceptor.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/com/twitter/common/inject/TimedInterceptor.java b/commons/src/main/java/com/twitter/common/inject/TimedInterceptor.java deleted file mode 100644 index 94b2551..0000000 --- a/commons/src/main/java/com/twitter/common/inject/TimedInterceptor.java +++ /dev/null @@ -1,106 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.twitter.common.inject; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Method; - -import com.google.common.base.Preconditions; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.inject.Binder; -import com.google.inject.matcher.Matchers; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; -import org.apache.commons.lang.StringUtils; - -import com.twitter.common.stats.SlidingStats; -import com.twitter.common.stats.TimeSeriesRepository; - -/** - * A method interceptor that exports timing information for methods annotated with - * {@literal @Timed}. - * - * @author John Sirois - */ -public final class TimedInterceptor implements MethodInterceptor { - - /** - * Marks a method as a target for timing. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - public @interface Timed { - - /** - * The base name to export timing data with; empty to use the annotated method's name. - */ - String value() default ""; - } - - private final LoadingCache<Method, SlidingStats> stats = - CacheBuilder.newBuilder().build(new CacheLoader<Method, SlidingStats>() { - @Override public SlidingStats load(Method method) { - return createStats(method); - } - }); - - private TimedInterceptor() { - // preserve for guice - } - - private SlidingStats createStats(Method method) { - Timed timed = method.getAnnotation(Timed.class); - Preconditions.checkArgument(timed != null, - "TimedInterceptor can only be applied to @Timed methods"); - - String name = timed.value(); - String statName = !StringUtils.isEmpty(name) ? name : method.getName(); - return new SlidingStats(statName, "nanos"); - } - - @Override - public Object invoke(MethodInvocation methodInvocation) throws Throwable { - // TODO(John Sirois): consider including a SlidingRate tracking thrown exceptions - SlidingStats stat = stats.get(methodInvocation.getMethod()); - long start = System.nanoTime(); - try { - return methodInvocation.proceed(); - } finally { - stat.accumulate(System.nanoTime() - start); - } - } - - /** - * Installs an interceptor in a guice {@link com.google.inject.Injector}, enabling - * {@literal @Timed} method interception in guice-provided instances. Requires that a - * {@link TimeSeriesRepository} is bound elsewhere. - * - * @param binder a guice binder to require bindings against - */ - public static void bind(Binder binder) { - Preconditions.checkNotNull(binder); - - Bindings.requireBinding(binder, TimeSeriesRepository.class); - - TimedInterceptor interceptor = new TimedInterceptor(); - binder.requestInjection(interceptor); - binder.bindInterceptor(Matchers.any(), Matchers.annotatedWith(Timed.class), interceptor); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/io/Base64ZlibCodec.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/com/twitter/common/io/Base64ZlibCodec.java b/commons/src/main/java/com/twitter/common/io/Base64ZlibCodec.java deleted file mode 100644 index ef31735..0000000 --- a/commons/src/main/java/com/twitter/common/io/Base64ZlibCodec.java +++ /dev/null @@ -1,169 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.twitter.common.io; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; -import java.io.Writer; -import java.nio.charset.Charset; -import java.util.zip.DeflaterOutputStream; -import java.util.zip.GZIPInputStream; -import java.util.zip.InflaterInputStream; - -import com.google.common.base.Preconditions; -import com.google.common.base.Throwables; -import com.google.common.io.ByteStreams; - -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.codec.binary.Base64OutputStream; - -/** - * Utility class providing encoding and decoding methods to and from a string to a utf-8 encoded, - * zlib compressed, Base64 encoded representation of the string. For wider compatibility, the - * decoder can also automatically recognize GZIP (instead of plain zlib) compressed data too and - * decode it accordingly. - * - * @author Attila Szegedi - */ -public final class Base64ZlibCodec { - /** - * Thrown to indicate invalid data while decoding or unzipping. - * - * @author Attila Szegedi - */ - public static class InvalidDataException extends Exception { - private static final long serialVersionUID = 1L; - - public InvalidDataException(String message) { - super(message); - } - - public InvalidDataException(String message, Throwable cause) { - super(message, cause); - } - } - - /** - * Text encoding used by the Base64 output stream. - */ - public static final String BASE64_TEXT_ENCODING = "ASCII"; - private static final int ESTIMATED_PLAINTEXT_TO_ENCODED_RATIO = 4; - - // Prefix all Base64-encoded, zlib compressed data must have - private static final byte[] ZLIB_HEADER_PREFIX = new byte[] { 120 }; - // Prefix all Base64-encoded, GZIP compressed data must have - private static final byte[] GZIP_HEADER_PREFIX = new byte[] {31, -117, 8, 0, 0, 0, 0, 0, 0 }; - private static final int DIAGNOSTIC_PREFIX_LENGTH = 16; - // Text encoding for char-to-byte transformation before compressing a stack trace - private static final Charset TEXT_ENCODING = com.google.common.base.Charsets.UTF_8; - - private Base64ZlibCodec() { - // Utility class - } - - /** - * Decodes a string. In addition to zlib, it also automatically detects GZIP compressed data and - * adjusts accordingly. - * - * @param encoded the encoded string, represented as a byte array of ASCII-encoded characters - * @return the decoded string - * @throws InvalidDataException if the string can not be decoded. - */ - public static byte[] decode(String encoded) throws InvalidDataException { - Preconditions.checkNotNull(encoded); - return decompress(new Base64().decode(encoded)); - } - - private static byte[] decompress(byte[] compressed) throws InvalidDataException { - byte[] bytes; - try { - final InputStream bin = new ByteArrayInputStream(compressed); - final InputStream zin; - if (startsWith(compressed, GZIP_HEADER_PREFIX)) { - zin = new GZIPInputStream(bin); - } else if (startsWith(compressed, ZLIB_HEADER_PREFIX)) { - zin = new InflaterInputStream(bin); - } else { - throw new Base64ZlibCodec.InvalidDataException("Value doesn't start with either GZIP or zlib header"); - } - try { - bytes = ByteStreams.toByteArray(zin); - } finally { - zin.close(); - } - } catch (IOException e) { - throw new Base64ZlibCodec.InvalidDataException("zlib/GZIP decoding error", e); - } - return bytes; - } - - private static boolean startsWith(byte[] value, byte[] prefix) { - final int pl = prefix.length; - if (value.length < pl) { - return false; - } - for (int i = 0; i < pl; ++i) { - if (value[i] != prefix[i]) { - return false; - } - } - return true; - } - - /** - * Encodes a set of bytes. - * - * @param plain the non-encoded bytes - * @return the encoded string - */ - public static String encode(byte[] plain) { - final ByteArrayOutputStream out = new ByteArrayOutputStream(plain.length - / ESTIMATED_PLAINTEXT_TO_ENCODED_RATIO); - final OutputStream w = getDeflatingEncodingStream(out); - try { - w.write(plain); - w.close(); - return out.toString(BASE64_TEXT_ENCODING); - } catch (UnsupportedEncodingException e) { - throw reportUnsupportedEncoding(); - } catch (IOException e) { - throw Throwables.propagate(e); - } - } - - private static OutputStream getDeflatingEncodingStream(OutputStream out) { - return new DeflaterOutputStream(new Base64OutputStream(out, true, - Integer.MAX_VALUE, null)); - } - - /** - * Returns a writer that writes through to the specified output stream, utf-8 encoding, - * zlib compressing, and Base64 encoding its input along the way. - * - * @param out the output stream that receives the final output - * @return a writer for the input - */ - public static Writer getEncodingWriter(OutputStream out) { - return new OutputStreamWriter(getDeflatingEncodingStream(out), TEXT_ENCODING); - } - - private static AssertionError reportUnsupportedEncoding() { - return new AssertionError(String.format("JVM doesn't support the %s encoding", TEXT_ENCODING)); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/io/Codec.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/com/twitter/common/io/Codec.java b/commons/src/main/java/com/twitter/common/io/Codec.java deleted file mode 100644 index c9d5882..0000000 --- a/commons/src/main/java/com/twitter/common/io/Codec.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.twitter.common.io; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * A Codec represents a reversible encoding for a given type. Codecs are able to both - * {@link #deserialize(java.io.InputStream) read} items from streams and - * {@link #serialize(Object, java.io.OutputStream) write} items to streams. - * - * <p> TODO(John Sirois): consider whether this interface should optionally support null items to be - * read and written. - * - * @param <T> The type of object the Codec can handle. - * - * @author John Sirois - */ -public interface Codec<T> { - - /** - * Writes a representation of {@code item} to the {@code sink} that can be read back by - * {@link #deserialize(java.io.InputStream)}. - * - * @param item the item to serialize - * @param sink the stream to write the item out to - * @throws IOException if there is a problem serializing the item - */ - void serialize(T item, OutputStream sink) throws IOException; - - /** - * Reads an item from the {@code source} stream that was written by - * {@link #serialize(Object, java.io.OutputStream)}. - * - * @param source the stream to read an item from - * @return the deserialized item - * @throws IOException if there is a problem reading an item - */ - T deserialize(InputStream source) throws IOException; -} http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/io/CompatibilityCodec.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/com/twitter/common/io/CompatibilityCodec.java b/commons/src/main/java/com/twitter/common/io/CompatibilityCodec.java deleted file mode 100644 index 878d35d..0000000 --- a/commons/src/main/java/com/twitter/common/io/CompatibilityCodec.java +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.twitter.common.io; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PushbackInputStream; - -import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; - -/** - * A codec that composes two codecs: a primary and a compatibility codec. It always serializes with - * the primary codec, but can make a decision on deserialization based on the first few bytes of the - * serialized format whether to use the compatibility codec. This allows for easier transition - * between storage formats as the codec remains able to read the old serialized format. - * - * @author Attila Szegedi - * - * @param <T> the type of objects this codec is for. - */ -public class CompatibilityCodec<T> implements Codec<T> { - private final Codec<T> primaryCodec; - private final Codec<T> secondaryCodec; - private final int prefixLength; - private final Predicate<byte[]> discriminator; - - private CompatibilityCodec(Codec<T> primaryCodec, Codec<T> secondaryCodec, int prefixLength, - Predicate<byte[]> discriminator) { - Preconditions.checkNotNull(primaryCodec); - Preconditions.checkNotNull(secondaryCodec); - this.primaryCodec = primaryCodec; - this.secondaryCodec = secondaryCodec; - this.prefixLength = prefixLength; - this.discriminator = discriminator; - } - - /** - * Creates a new compatibility codec instance. - * - * @param primaryCodec the codec used to serialize objects, as well as deserialize them when the - * first byte of the serialized format matches the discriminator. - * @param secondaryCodec the codec used to deserialize objects when the first byte of the - * serialized format does not match the discriminator. - * @param prefixLength the length, in bytes, of the prefix of the message that is inspected for - * determining the format. - * @param discriminator a predicate that will receive an array of at most prefixLength bytes - * (it can receive less if the serialized format is shorter) and has to return true - * if the primary codec should be used for deserialization, otherwise false. - */ - public static <T> CompatibilityCodec<T> create(Codec<T> primaryCodec, Codec<T> secondaryCodec, - int prefixLength, Predicate<byte[]> discriminator) { - return new CompatibilityCodec<T>(primaryCodec, secondaryCodec, prefixLength, discriminator); - } - - @Override - public T deserialize(InputStream source) throws IOException { - final PushbackInputStream in = new PushbackInputStream(source, prefixLength); - final byte[] prefix = readAtMostPrefix(in); - in.unread(prefix); - return (discriminator.apply(prefix) ? primaryCodec : secondaryCodec).deserialize(in); - } - - private byte[] readAtMostPrefix(InputStream in) throws IOException { - final byte[] prefix = new byte[prefixLength]; - int read = 0; - do { - final int readNow = in.read(prefix, read, prefixLength - read); - if (readNow == -1) { - byte[] newprefix = new byte[read]; - System.arraycopy(prefix, 0, newprefix, 0, read); - return newprefix; - } - read += readNow; - } while (read < prefixLength); - return prefix; - } - - @Override - public void serialize(T item, OutputStream sink) throws IOException { - primaryCodec.serialize(item, sink); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/io/FileUtils.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/com/twitter/common/io/FileUtils.java b/commons/src/main/java/com/twitter/common/io/FileUtils.java deleted file mode 100644 index f2ef5f7..0000000 --- a/commons/src/main/java/com/twitter/common/io/FileUtils.java +++ /dev/null @@ -1,193 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.twitter.common.io; - -import java.io.File; -import java.io.IOException; -import java.util.UUID; - -import com.google.common.base.Preconditions; - -import org.apache.commons.lang.SystemUtils; - -import com.twitter.common.base.ExceptionalClosure; -import com.twitter.common.base.ExceptionalFunction; - -/** - * Utility methods for working with files and directories. - * - * @author John Sirois - */ -public final class FileUtils { - - /** - * A utility for creating and working with temporary files and directories. - */ - public static class Temporary { - private static final int MAX_TMP_DIR_TRIES = 5; - - private final File basedir; - - /** - * Creates a new temporary utility that creates files and directories rooted at {@code basedir}. - * - * @param basedir The base directory to generate temporary files and directories in. - */ - public Temporary(File basedir) { - Preconditions.checkNotNull(basedir); - this.basedir = basedir; - } - - /** - * Returns a new empty temporary directory. - * - * @return a file representing the newly created directory. - * @throws IllegalStateException if a new temporary directory could not be created - */ - public File createDir() { - File tempDir; - int tries = 0; - do { - // For sanity sake, die eventually if we keep failing to pick a new unique directory name. - if (++tries > MAX_TMP_DIR_TRIES) { - throw new IllegalStateException("Failed to create a new temp directory in " - + MAX_TMP_DIR_TRIES + " attempts, giving up"); - } - tempDir = new File(basedir, UUID.randomUUID().toString()); - } while (!tempDir.mkdir()); - return tempDir; - } - - /** - * Creates a new empty temporary file. - * - * @return a new empty temporary file - * @throws IOException if there was a problem creating a new temporary file - */ - public File createFile() throws IOException { - return createFile(".tempfile"); - } - - /** - * Creates a new empty temporary file with the given filename {@code suffix}. - * - * @param suffix The suffix for the temporary file name - * @return a new empty temporary file - * @throws IOException if there was a problem creating a new temporary file - */ - public File createFile(String suffix) throws IOException { - return File.createTempFile(FileUtils.class.getName(), suffix, basedir); - } - - /** - * Creates a new temporary directory and executes the unit of {@code work} against it ensuring - * the directory and its contents are removed after the work completes normally or abnormally. - * - * @param work The unit of work to execute against the new temporary directory. - * @param <E> The type of exception this unit of work can throw. - * @throws E bubbled transparently when the unit of work throws - */ - public <E extends Exception> void doWithDir(final ExceptionalClosure<File, E> work) - throws E { - Preconditions.checkNotNull(work); - doWithDir(new ExceptionalFunction<File, Void, E>() { - @Override public Void apply(File dir) throws E { - work.execute(dir); - return null; - } - }); - } - - /** - * Creates a new temporary directory and executes the unit of {@code work} against it ensuring - * the directory and its contents are removed after the work completes normally or abnormally. - * - * @param work The unit of work to execute against the new temporary directory. - * @param <T> The type of result this unit of work produces. - * @param <E> The type of exception this unit of work can throw. - * @return the result when the unit of work completes successfully - * @throws E bubbled transparently when the unit of work throws - */ - public <T, E extends Exception> T doWithDir(ExceptionalFunction<File, T, E> work) - throws E { - Preconditions.checkNotNull(work); - return doWithTemp(createDir(), work); - } - - /** - * Creates a new temporary file and executes the unit of {@code work} against it ensuring - * the file is removed after the work completes normally or abnormally. - * - * @param work The unit of work to execute against the new temporary file. - * @param <E> The type of exception this unit of work can throw. - * @throws E bubbled transparently when the unit of work throws - * @throws IOException if there was a problem creating a new temporary file - */ - public <E extends Exception> void doWithFile(final ExceptionalClosure<File, E> work) - throws E, IOException { - Preconditions.checkNotNull(work); - doWithFile(new ExceptionalFunction<File, Void, E>() { - @Override public Void apply(File dir) throws E { - work.execute(dir); - return null; - } - }); - } - - /** - * Creates a new temporary file and executes the unit of {@code work} against it ensuring - * the file is removed after the work completes normally or abnormally. - * - * @param work The unit of work to execute against the new temporary file. - * @param <T> The type of result this unit of work produces. - * @param <E> The type of exception this unit of work can throw. - * @return the result when the unit of work completes successfully - * @throws E bubbled transparently when the unit of work throws - * @throws IOException if there was a problem creating a new temporary file - */ - public <T, E extends Exception> T doWithFile(ExceptionalFunction<File, T, E> work) - throws E, IOException { - Preconditions.checkNotNull(work); - return doWithTemp(createFile(), work); - } - - private static <T, E extends Exception> T doWithTemp(File file, - ExceptionalFunction<File, T, E> work) throws E { - try { - return work.apply(file); - } finally { - org.apache.commons.io.FileUtils.deleteQuietly(file); - } - } - } - - /** - * A temporary based at the default system temporary directory. - */ - public static final Temporary SYSTEM_TMP = new Temporary(SystemUtils.getJavaIoTmpDir()); - - /** - * Returns a new empty temporary directory. - * - * @return a file representing the newly created directory. - * @throws IllegalStateException if a new temporary directory could not be created - */ - public static File createTempDir() { - return SYSTEM_TMP.createDir(); - } - - private FileUtils() { - // utility - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/io/JsonCodec.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/com/twitter/common/io/JsonCodec.java b/commons/src/main/java/com/twitter/common/io/JsonCodec.java deleted file mode 100644 index c6c9631..0000000 --- a/commons/src/main/java/com/twitter/common/io/JsonCodec.java +++ /dev/null @@ -1,124 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.twitter.common.io; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.util.BitSet; - -import com.google.common.base.Preconditions; -import com.google.gson.ExclusionStrategy; -import com.google.gson.FieldAttributes; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -/** - * A {@code Codec} that can encode and decode objects to and from JSON using the GSON library - * (which in turn will use reflection). The codec uses the UTF-8 encoding. - * - * @author Attila Szegedi - */ -public class JsonCodec<T> implements Codec<T> { - - private static final String ENCODING = "utf-8"; - - private final Class<T> clazz; - private final Gson gson; - - /** - * Creates a new JSON codec instance for objects of the specified class. - * - * @param clazz the class of the objects the created codec is for. - * @return a newly constructed JSON codec instance for objects of the requested class. - */ - public static <T> JsonCodec<T> create(Class<T> clazz) { - return new JsonCodec<T>(clazz, DefaultGsonHolder.instance); - } - - /** - * Creates a new JSON codec instance for objects of the specified class and the specified Gson - * instance. You can use this method if you need to customize the behavior of the Gson - * serializer. - * - * @param clazz the class of the objects the created codec is for. - * @param gson the Gson instance to use for serialization/deserialization. - * @return a newly constructed JSON codec instance for objects of the requested class. - */ - public static <T> JsonCodec<T> create(Class<T> clazz, Gson gson) { - return new JsonCodec<T>(clazz, gson); - } - - private JsonCodec(Class<T> clazz, Gson gson) { - Preconditions.checkNotNull(clazz); - Preconditions.checkNotNull(gson); - this.clazz = clazz; - this.gson = gson; - } - - private static final class DefaultGsonHolder { - static final Gson instance = new Gson(); - } - - /** - * Returns a Gson exclusion strategy that excludes Thrift synthetic fields from JSON - * serialization. You can pass it to a {@link GsonBuilder} to construct a customized {@link Gson} - * instance to use with {@link JsonCodec#create(Class, Gson)}. - * - * @return a Gson exclusion strategy for thrift synthetic fields. - */ - public static ExclusionStrategy getThriftExclusionStrategy() { - return ThriftExclusionStrategy.instance; - } - - private static final class ThriftExclusionStrategy implements ExclusionStrategy { - static final ExclusionStrategy instance = new ThriftExclusionStrategy(); - - public boolean shouldSkipClass(Class<?> clazz) { - return false; - } - - public boolean shouldSkipField(FieldAttributes f) { - // Exclude Thrift synthetic fields - return f.getDeclaredClass() == BitSet.class && f.getName().equals("__isset_bit_vector"); - } - } - - @Override - public T deserialize(InputStream source) throws IOException { - return gson.fromJson(new InputStreamReader(source, ENCODING), clazz); - } - - @Override - public void serialize(T item, OutputStream sink) throws IOException { - final Writer w = new OutputStreamWriter(new UnflushableOutputStream(sink), ENCODING); - gson.toJson(item, clazz, w); - w.flush(); - } - - private static class UnflushableOutputStream extends FilterOutputStream { - UnflushableOutputStream(OutputStream out) { - super(out); - } - - @Override - public void flush() throws IOException { - // Intentionally do nothing - } - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/io/Streamer.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/com/twitter/common/io/Streamer.java b/commons/src/main/java/com/twitter/common/io/Streamer.java deleted file mode 100644 index ce601b4..0000000 --- a/commons/src/main/java/com/twitter/common/io/Streamer.java +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.twitter.common.io; - -import com.google.common.base.Predicate; -import com.twitter.common.base.Closure; - -/** - * Encapsulates iteration over a typed data stream that can be filtered. - * - * @author John Sirois - */ -public interface Streamer<T> { - - /** - * Processes a stream fully. This may cause a database query to be executed, a file to be read - * or even just call {@link Iterable#iterator()} depending on the implementation. Implementations - * guaranty that any resources allocated opening the stream will be closed whether or not process - * completes normally. - * - * @param work a closure over the work to be done for each item in the stream. - */ - void process(Closure<T> work); - - /** - * Returns a {@code Streamer} that will process the same stream as this streamer, but will stop - * processing when encountering the first item for which {@code cond} is true. - * - * @param cond a predicate that returns {@code false} as long as the stream should keep being - * processed. - * @return a streamer that will process items until the condition triggers. - */ - Streamer<T> endOn(Predicate<T> cond); - - /** - * Returns a {@code Streamer} that will process the same stream as this streamer, but with any - * items failing the filter to be omitted from processing. - * @param filter a predicate that returns {@code true} if an item in the stream should be - * processed - * @return a filtered streamer - */ - Streamer<T> filter(Predicate<T> filter); -} http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/io/ThriftCodec.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/com/twitter/common/io/ThriftCodec.java b/commons/src/main/java/com/twitter/common/io/ThriftCodec.java deleted file mode 100644 index 4c7c289..0000000 --- a/commons/src/main/java/com/twitter/common/io/ThriftCodec.java +++ /dev/null @@ -1,104 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.twitter.common.io; - -import com.google.common.base.Function; -import com.google.common.base.Preconditions; -import com.google.common.base.Supplier; -import com.twitter.common.base.MoreSuppliers; -import org.apache.thrift.TBase; -import org.apache.thrift.TException; -import org.apache.thrift.protocol.TBinaryProtocol; -import org.apache.thrift.protocol.TCompactProtocol; -import org.apache.thrift.protocol.TJSONProtocol; -import org.apache.thrift.protocol.TProtocol; -import org.apache.thrift.transport.TIOStreamTransport; -import org.apache.thrift.transport.TTransport; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * A {@code Codec} that can encode and decode thrift structs. - */ -public class ThriftCodec<T extends TBase> implements Codec<T> { - - public static final Function<TTransport, TProtocol> JSON_PROTOCOL = - new Function<TTransport, TProtocol>() { - @Override public TProtocol apply(TTransport transport) { - return new TJSONProtocol(transport); - } - }; - - public static final Function<TTransport, TProtocol> BINARY_PROTOCOL = - new Function<TTransport, TProtocol>() { - @Override public TProtocol apply(TTransport transport) { - return new TBinaryProtocol(transport); - } - }; - - public static final Function<TTransport, TProtocol> COMPACT_PROTOCOL = - new Function<TTransport, TProtocol>() { - @Override public TProtocol apply(TTransport transport) { - return new TCompactProtocol(transport); - } - }; - - private final Supplier<T> templateSupplier; - private final Function<TTransport, TProtocol> protocolFactory; - - public static <T extends TBase> ThriftCodec<T> create(final Class<T> thriftStructType, - Function<TTransport, TProtocol> protocolFactory) { - return new ThriftCodec<T>(MoreSuppliers.of(thriftStructType), protocolFactory); - } - - /** - * @deprecated use {@link ThriftCodec#create(Class, Function)} instead. - */ - @Deprecated - public ThriftCodec(final Class<T> thriftStructType, - Function<TTransport, TProtocol> protocolFactory) { - this(MoreSuppliers.of(thriftStructType), protocolFactory); - } - - public ThriftCodec(Supplier<T> templateSupplier, - Function<TTransport, TProtocol> protocolFactory) { - this.templateSupplier = Preconditions.checkNotNull(templateSupplier); - this.protocolFactory = Preconditions.checkNotNull(protocolFactory); - } - - @Override - public void serialize(T item, OutputStream sink) throws IOException { - Preconditions.checkNotNull(item); - Preconditions.checkNotNull(sink); - try { - item.write(protocolFactory.apply(new TIOStreamTransport(null, sink))); - } catch (TException e) { - throw new IOException("Problem serializing thrift struct: " + item, e); - } - } - - @Override - public T deserialize(InputStream source) throws IOException { - Preconditions.checkNotNull(source); - T template = templateSupplier.get(); - try { - template.read(protocolFactory.apply(new TIOStreamTransport(source, null))); - } catch (TException e) { - throw new IOException("Problem de-serializing thrift struct from stream", e); - } - return template; - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/logging/BufferedLog.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/com/twitter/common/logging/BufferedLog.java b/commons/src/main/java/com/twitter/common/logging/BufferedLog.java deleted file mode 100644 index 75b05be..0000000 --- a/commons/src/main/java/com/twitter/common/logging/BufferedLog.java +++ /dev/null @@ -1,278 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.twitter.common.logging; - -import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import com.twitter.common.quantity.Amount; -import com.twitter.common.quantity.Time; -import com.twitter.common.stats.StatImpl; -import com.twitter.common.stats.Stats; - -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.logging.Logger; - -/** - * Log that buffers requests before sending them to a wrapped log. - * - * @author William Farner - */ -public class BufferedLog<T, R> implements Log<T, Void> { - private static final Logger LOG = Logger.getLogger(BufferedLog.class.getName()); - - private static final ExecutorService DEFAULT_EXECUTOR_SERVICE = - Executors.newSingleThreadExecutor( - new ThreadFactoryBuilder().setDaemon(true).setNameFormat("Log Pusher-%d").build()); - private static final int DEFAULT_MAX_BUFFER_SIZE = 100000; - - // TODO(William Farner): Change to use a ScheduledExecutorService instead of a timer. - private final TimerTask logPusher = new TimerTask() { - @Override public void run() { - flush(); - } - }; - - // Local buffer of log messages. - private final List<T> localBuffer = Lists.newLinkedList(); - - // The log that is being buffered. - private Log<T, R> bufferedLog; - - // Filter to determine when a log request should be retried. - private Predicate<R> retryFilter = null; - - // Maximum number of log entries that can be buffered before truncation (lost messages). - private int maxBufferSize = DEFAULT_MAX_BUFFER_SIZE; - - // Maximum buffer length before attempting to submit. - private int chunkLength; - - // Maximum time for a message to sit in the buffer before attempting to flush. - private Amount<Integer, Time> flushInterval; - - // Service to handle flushing the log. - private ExecutorService logSubmitService = DEFAULT_EXECUTOR_SERVICE; - - private BufferedLog() { - // Created through builder. - - Stats.export(new StatImpl<Integer>("scribe_buffer_size") { - public Integer read() { return getBacklog(); } - }); - } - - public static <T, R> Builder<T, R> builder() { - return new Builder<T, R>(); - } - - /** - * Starts the log submission service by scheduling a timer to periodically submit messages. - */ - private void start() { - long flushIntervalMillis = flushInterval.as(Time.MILLISECONDS); - - new Timer(true).scheduleAtFixedRate(logPusher, flushIntervalMillis, flushIntervalMillis); - } - - /** - * Gets the current number of messages in the local buffer. - * - * @return The number of backlogged messages. - */ - protected int getBacklog() { - synchronized (localBuffer) { - return localBuffer.size(); - } - } - - /** - * Stores a log entry, flushing immediately if the buffer length limit is exceeded. - * - * @param entry Entry to log. - */ - @Override - public Void log(T entry) { - synchronized (localBuffer) { - localBuffer.add(entry); - - if (localBuffer.size() >= chunkLength) { - logSubmitService.submit(logPusher); - } - } - - return null; - } - - @Override - public Void log(List<T> entries) { - for (T entry : entries) log(entry); - - return null; - } - - @Override - public void flush() { - List<T> buffer = copyBuffer(); - if (buffer.isEmpty()) return; - - R result = bufferedLog.log(buffer); - - // Restore the buffer if the write was not successful. - if (retryFilter != null && retryFilter.apply(result)) { - LOG.warning("Log request failed, restoring spooled messages."); - restoreToLocalBuffer(buffer); - } - } - - /** - * Creats a snapshot of the local buffer and clears the local buffer. - * - * @return A snapshot of the local buffer. - */ - private List<T> copyBuffer() { - synchronized (localBuffer) { - List<T> bufferCopy = ImmutableList.copyOf(localBuffer); - localBuffer.clear(); - return bufferCopy; - } - } - - /** - * Restores log entries back to the local buffer. This can be used to commit entries back to the - * buffer after a flush operation failed. - * - * @param buffer The log entries to restore. - */ - private void restoreToLocalBuffer(List<T> buffer) { - synchronized (localBuffer) { - int restoreRecords = Math.min(buffer.size(), maxBufferSize - localBuffer.size()); - - if (restoreRecords != buffer.size()) { - LOG.severe((buffer.size() - restoreRecords) + " log records truncated!"); - - if (restoreRecords == 0) return; - } - - localBuffer.addAll(0, buffer.subList(buffer.size() - restoreRecords, buffer.size())); - } - } - - /** - * Configures a BufferedLog object. - * - * @param <T> Log message type. - * @param <R> Log result type. - */ - public static class Builder<T, R> { - private final BufferedLog<T, R> instance; - - public Builder() { - instance = new BufferedLog<T, R>(); - } - - /** - * Specifies the log that should be buffered. - * - * @param bufferedLog Log to buffer requests to. - * @return A reference to the builder. - */ - public Builder<T, R> buffer(Log<T, R> bufferedLog) { - instance.bufferedLog = bufferedLog; - return this; - } - - /** - * Adds a custom retry filter that will be used to determine whether a log result {@code R} - * should be used to indicate that a log request should be retried. Log submit retry behavior - * is not defined when the filter throws uncaught exceptions. - * - * @param retryFilter Filter to determine whether to retry. - * @return A reference to the builder. - */ - public Builder<T, R> withRetryFilter(Predicate<R> retryFilter) { - instance.retryFilter = retryFilter; - return this; - } - - /** - * Specifies the maximum allowable buffer size, after which log records will be dropped to - * conserve memory. - * - * @param maxBufferSize Maximum buffer size. - * @return A reference to the builder. - */ - public Builder<T, R> withMaxBuffer(int maxBufferSize) { - instance.maxBufferSize = maxBufferSize; - return this; - } - - /** - * Specifies the desired number of log records to submit in each request. - * - * @param chunkLength Maximum number of records to accumulate before trying to submit. - * @return A reference to the builder. - */ - public Builder<T, R> withChunkLength(int chunkLength) { - instance.chunkLength = chunkLength; - return this; - } - - /** - * Specifies the maximum amount of time that a log entry may wait in the buffer before an - * attempt is made to flush the buffer. - * - * @param flushInterval Log flush interval. - * @return A reference to the builder. - */ - public Builder<T, R> withFlushInterval(Amount<Integer, Time> flushInterval) { - instance.flushInterval = flushInterval; - return this; - } - - /** - * Specifies the executor service to use for (synchronously or asynchronously) sending - * log entries. - * - * @param logSubmitService Log submit executor service. - * @return A reference to the builder. - */ - public Builder<T, R> withExecutorService(ExecutorService logSubmitService) { - instance.logSubmitService = logSubmitService; - return this; - } - - /** - * Creates the buffered log. - * - * @return The prepared buffered log. - */ - public BufferedLog<T, R> build() { - Preconditions.checkArgument(instance.chunkLength > 0); - Preconditions.checkArgument(instance.flushInterval.as(Time.MILLISECONDS) > 0); - Preconditions.checkNotNull(instance.logSubmitService); - Preconditions.checkArgument(instance.chunkLength <= instance.maxBufferSize); - - instance.start(); - - return instance; - } - } -}
