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> — 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 }