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.solver;
21
22 import org.apache.commons.lang3.tuple.Pair;
23 import org.grouplens.grapht.reflect.InjectionPoint;
24 import org.grouplens.grapht.reflect.Satisfaction;
25 import org.grouplens.grapht.reflect.internal.SimpleInjectionPoint;
26 import org.grouplens.grapht.util.AbstractChain;
27
28 import javax.annotation.Nullable;
29
30 /**
31 * <p>
32 * InjectionContext represents the current path through the dependency graph to
33 * the desire being resolved by
34 * {@link BindingFunction#bind(InjectionContext, DesireChain)}. The InjectionContext
35 * is most significantly represented as a list of satisfactions and the
36 * associated injection point attributes. This list represents the "type path"
37 * from the root node in the graph to the previously resolved satisfaction.
38 *
39 * @author <a href="http://grouplens.org">GroupLens Research</a>
40 */
41 public class InjectionContext extends AbstractChain<Pair<Satisfaction,InjectionPoint>> {
42 private static final long serialVersionUID = 1L;
43
44 /**
45 * Construct a singleton injection context.
46 * @param satisfaction The satisfaction.
47 * @param ip The injection point.
48 * @return The injection context.
49 */
50 public static InjectionContext singleton(Satisfaction satisfaction, InjectionPoint ip) {
51 return new InjectionContext(null, satisfaction, ip);
52 }
53
54 /**
55 * Extend or create an injection context.
56 * @param prefix The initial context.
57 * @param satisfaction The satisfaction.
58 * @param ip The injection point.
59 * @return The injection context.
60 */
61 public static InjectionContext extend(@Nullable InjectionContext prefix, Satisfaction satisfaction, InjectionPoint ip) {
62 if (prefix == null) {
63 return singleton(satisfaction, ip);
64 } else {
65 return prefix.extend(satisfaction, ip);
66 }
67 }
68
69 /**
70 * Construct a singleton injection context with no attributes.
71 * @param satisfaction The satisfaction.
72 * @return The injection context.
73 */
74 public static InjectionContext singleton(Satisfaction satisfaction) {
75 return singleton(satisfaction, new SimpleInjectionPoint(null, satisfaction.getErasedType(), true));
76 }
77
78 private InjectionContext(InjectionContext prior, Satisfaction satisfaction, InjectionPoint ip) {
79 super(prior, Pair.of(satisfaction, ip));
80 }
81
82 /**
83 * Create a new context that is updated to have the satisfaction and attribute pushed to the
84 * end of its type path. The value cache for the new context will be empty.
85 *
86 * @param satisfaction The next satisfaction in the dependency graph
87 * @param ip The injection point receiving the satisfaction
88 * @return A new context with updated type path
89 */
90 public InjectionContext extend(Satisfaction satisfaction, InjectionPoint ip) {
91 return new InjectionContext(this, satisfaction, ip);
92 }
93
94 /**
95 * Get everything except the last element of this context.
96 *
97 * @return Everything except the last element of this context, or {@code null} if the context is
98 * a singleton.
99 */
100 @Nullable
101 public InjectionContext getLeading() {
102 return (InjectionContext) previous;
103 }
104 }