View Javadoc

1   /*
2    * Grapht, an open source dependency injector.
3    * Copyright 2014-2015 various contributors (see CONTRIBUTORS.txt)
4    * Copyright 2010-2014 Regents of the University of Minnesota
5    *
6    * This program is free software; you can redistribute it and/or modify
7    * it under the terms of the GNU Lesser General Public License as
8    * published by the Free Software Foundation; either version 2.1 of the
9    * License, or (at your option) any later version.
10   *
11   * This program is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13   * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14   * details.
15   *
16   * You should have received a copy of the GNU General Public License along with
17   * this program; if not, write to the Free Software Foundation, Inc., 51
18   * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19   */
20  package org.grouplens.grapht;
21  
22  import org.grouplens.grapht.context.ContextPattern;
23  
24  import javax.annotation.Nullable;
25  import javax.inject.Qualifier;
26  import java.lang.annotation.Annotation;
27  
28  /**
29   * <p>
30   * Context is the main entry point for configuring bind rules using the fluent
31   * API. The dependency injector uses the contexts to limit the scope of a
32   * binding. Every time a dependency is satisfied, that type (and possibly {@link Qualifier})
33   * is pushed onto the context stack. Thus, if two different types each require a
34   * Foo, there can be two different bindings activated depending on which first
35   * type is in the context stack.
36   * <p>
37   * The "root" context is an empty stack, and will always be matched. When
38   * creating bindings, the context stack can be configured by calling
39   * {@link #in(Class)} or {@link #in(Class, Class)}.
40   * 
41   * @author <a href="http://grouplens.org">GroupLens Research</a>
42   */
43  public interface Context {
44      /**
45       * Start a new binding for the given type T within the scope of this
46       * context.  The returned Binding instance can be configured and completed by
47       * invoking one of its various to() methods.  Unless further configuration is
48       * done, this binding will match unqualified dependencies and dependencies
49       * with a qualifier annotated with
50       * {@link org.grouplens.grapht.annotation.AllowUnqualifiedMatch}.
51       * 
52       * @param <T> The matched source type
53       * @param type The raw class that is matched
54       * @return A new binding in this context for type T
55       */
56      <T> Binding<T> bind(Class<T> type);
57  
58      /**
59       * Start a new binding for a qualified type. A shortcut for
60       * {@code bind(type).withQualifier(qual)}.
61       * @param qual The type's qualifier.
62       * @param type The type to bind.
63       * @param <T> The type to bind.
64       * @return A new binding in this context for T with qualifier qual.
65       * @see Binding#withQualifier(Class)
66       */
67      <T> Binding<T> bind(Class<? extends Annotation> qual, Class<T> type);
68  
69      /**
70       * Start a new binding for a type irrespective of qualifier.  This is a
71       * shortcut for {@code bind(type).withAnyQualifier()}.
72       * @param type The type.
73       * @return A new binding in this context for type T with any (or no) 
74       *         qualifier.
75       */
76      <T> Binding<T> bindAny(Class<T> type);
77  
78      /**
79       * @deprecated Use {@link #within(Class)}.
80       */
81      @Deprecated
82      Context in(Class<?> type);
83  
84      /**
85       * @deprecated Use {@link #within(Class, Class)}.
86       */
87      @Deprecated
88      Context in(@Nullable Class<? extends Annotation> qualifier, Class<?> type);
89  
90      /**
91       * @deprecated Use {@link #within(Annotation, Class)}.
92       */
93      @Deprecated
94      Context in(@Nullable Annotation qualifier, Class<?> type);
95  
96      /**
97       * Create a new Context that extends the current context stack with the
98       * given class type. This matches with the default {@link Qualifier}. This is equivalent
99       * to <code>within(null, type);</code>
100      *
101      * @param type The type to extend this context by
102      * @return A new Context with a longer context stack
103      */
104     Context within(Class<?> type);
105 
106     /**
107      * Create a new Context that extends the current context stack with the
108      * given class and {@link Qualifier} annotation. If the qualifier is null,
109      * the default or null qualifier is used.
110      *
111      * @param qualifier The qualifier type that must be matched along with the type
112      * @param type The type to extend this context by
113      * @return A new Context with a longer context stack
114      */
115     Context within(@Nullable Class<? extends Annotation> qualifier, Class<?> type);
116 
117     /**
118      * Create a new Context that extends the current context stack with the
119      * given class, qualified by the specific Annotation instance. If the
120      * qualifier is null, the default or null qualifier is used.
121      *
122      * <p>The annotation provided must be serializable.  Annotations built by {@link
123      * org.grouplens.grapht.annotation.AnnotationBuilder} (recommended) or retrieved from the Java
124      * reflection API are serializable; if you use some other annotation implementation, it must be
125      * serializable.
126      *
127      * @param qualifier The qualifier instance that must be matched along with
128      *            the type
129      * @param type The type to extend this context by
130      * @return A new Context with a longer context stack
131      */
132     Context within(@Nullable Annotation qualifier, Class<?> type);
133 
134     /**
135      * Restruct context to matching a particular pattern.  The pattern is appended to the pattern
136      * generated by the other context-restriction methods.  This is a high-powered method that
137      * won't be needed in most situations, but allows fine-grained control of context matching.
138      *
139      * @param pattern The context pattern to match.
140      * @return A context with longer context.
141      */
142     Context matching(ContextPattern pattern);
143 
144     /**
145      * Create a new Context that extends the current context stack with the given class type as an
146      * anchored match. This matches with the default {@link Qualifier}. This is equivalent to
147      * <code>at(null, type);</code>
148      *
149      * @param type The type to extend this context by
150      * @return A new Context with a longer context stack
151      * @see #at(Class, Class)
152      */
153     Context at(Class<?> type);
154 
155     /**
156      * Create a new Context that extends the current context stack with the given class and {@link
157      * Qualifier} annotation as an anchored match. If the qualifier is null, the default or null
158      * qualifier is used.
159      * <p>
160      * Unlike {@link #in(Class,Class)}, this match is <em>anchored</em> &mdash; that is, it only
161      * matches at the end of a context chain.  Context is matched if it ends with this or,
162      * if further context is opened inside this context, if the inner context matches immediately.
163      * </p>
164      *
165      * @param qualifier The qualifier type that must be matched along with the type
166      * @param type      The type to extend this context by
167      * @return A new Context with a longer context stack
168      */
169     Context at(@Nullable Class<? extends Annotation> qualifier, Class<?> type);
170 
171     /**
172      * Create a new Context that extends the current context stack with the given class, qualified
173      * by the specific Annotation instance. as an anchored match. If the qualifier is null, the
174      * default or null qualifier is used.
175      *
176      * <p>The annotation provided must be serializable.  Annotations built by {@link
177      * org.grouplens.grapht.annotation.AnnotationBuilder} (recommended) or retrieved from the Java
178      * reflection API are serializable; if you use some other annotation implementation, it must be
179      * serializable.
180      *
181      * @param qualifier The qualifier instance that must be matched along with the type
182      * @param type      The type to extend this context by
183      * @return A new Context with a longer context stack
184      */
185     Context at(@Nullable Annotation qualifier, Class<?> type);
186 }