View Javadoc
1   package com.atlassian.dbexporter;
2   
3   import com.google.common.collect.Collections2;
4   import com.google.common.collect.Iterables;
5   
6   import java.util.Collection;
7   import java.util.LinkedList;
8   
9   import static com.google.common.base.Predicates.instanceOf;
10  import static java.util.Arrays.asList;
11  
12  public final class Context {
13      private final Collection<Object> context = new LinkedList<Object>();
14  
15      public Context(Object... objects) {
16          context.addAll(asList(objects));
17      }
18  
19      /**
20       * Gets the single element of the given type in the import context, returning {@code null} if none is present.
21       *
22       * @param type the type of the element to look for
23       * @param <T>  the type parameter of the type to look for
24       * @return the element if it exists, {@code null} otherwise
25       * @throws IllegalStateException if more than one element of the given type are present in the context. If you need
26       *                               to get multiple elements of type {@code T} use the {@link #getAll(Class)} method.
27       * @see #getAll(Class)
28       */
29      public <T> T get(Class<T> type) {
30          final Collection<T> zeroOrOne = getZeroOrOneElement(type);
31          return zeroOrOne.isEmpty() ? null : first(zeroOrOne);
32      }
33  
34      /**
35       * Gets all the element of the given type in the import context
36       *
37       * @param type the type of the elements to look for
38       * @param <T>  the type parameter of the type to look for
39       * @return all the elements of type {@code T}, note that there might be none.
40       * @see #get(Class)
41       */
42      public <T> Collection<T> getAll(Class<T> type) {
43          return filter(type);
44      }
45  
46      /**
47       * Add the given object to the context
48       *
49       * @param obj the new object in the context
50       * @return {@code this}
51       */
52      public Context put(Object obj) {
53          context.add(obj);
54          return this;
55      }
56  
57      /**
58       * Add all the given objects to the context
59       *
60       * @param objs the collection of objects to add to the context
61       * @return {@code this}
62       */
63      public Context putAll(Collection<?> objs) {
64          context.addAll(objs);
65          return this;
66      }
67  
68      private <T> Collection<T> getZeroOrOneElement(Class<T> type) {
69          return checkZeroOrOneElement(type, getAll(type));
70      }
71  
72      private <T> Collection<T> checkZeroOrOneElement(Class<T> type, Collection<T> c) {
73          if (c.size() > 1) {
74              throw new IllegalStateException("Found more than one element of type " + type.getName() + " in import context!");
75          }
76          return c;
77      }
78  
79      @SuppressWarnings("unchecked")
80      private <T> Collection<T> filter(Class<T> type) {
81          return (Collection<T>) Collections2.filter(context, instanceOf(type));
82      }
83  
84      private static <T> T first(Iterable<T> c) {
85          return Iterables.get(c, 0);
86      }
87  }