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