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.grouplens.grapht.CachePolicy;
23 import org.grouplens.grapht.reflect.Desire;
24 import org.grouplens.grapht.util.Preconditions;
25
26 import java.util.EnumSet;
27
28 /**
29 * BindingResult is the result tuple of a {@link BindingFunction}. It is
30 * effectively a {@link Desire} with additional metadata needed to implement
31 * certain features within the dependency solver.
32 *
33 * @author <a href="http://grouplens.org">GroupLens Research</a>
34 */
35 public class BindingResult {
36 private final Desire desire;
37 private final CachePolicy policy;
38 private final EnumSet<BindingFlag> flags;
39
40 /**
41 * Create a new result that wraps the given Desire.
42 *
43 * @param desire The resultant desire from a BindingFunction
44 * @param policy The CachePolicy for this binding
45 * @throws NullPointerException if desire or policy is null
46 */
47 BindingResult(Desire desire, CachePolicy policy, EnumSet<BindingFlag> flags) {
48 Preconditions.notNull("desire", desire);
49 Preconditions.notNull("policy", policy);
50
51 this.policy = policy;
52 this.desire = desire;
53 this.flags = flags.clone();
54 }
55
56 public static Builder newBuilder() {
57 return new Builder();
58 }
59
60 public static Builder newBuilder(Desire desire, CachePolicy policy) {
61 return newBuilder()
62 .setDesire(desire)
63 .setCachePolicy(policy);
64 }
65
66 /**
67 * @return The restricted desire result of the binding function
68 */
69 public Desire getDesire() {
70 return desire;
71 }
72
73 /**
74 * @return The CachePolicy for this binding
75 */
76 public CachePolicy getCachePolicy() {
77 return policy;
78 }
79
80 /**
81 * Query if the binding result is fixed.
82 * @return {@code true} if the resulting satisfaction should refuse to be rewritten.
83 */
84 public boolean isFixed() {
85 return flags.contains(BindingFlag.FIXED);
86 }
87
88 /**
89 * @return True if the resulting desire should be deferred until all other
90 * desires in this phase have been completed
91 */
92 public boolean isDeferred() {
93 return flags.contains(BindingFlag.DEFERRED);
94 }
95
96 /**
97 * @return True if no more binding functions should process the resulting
98 * desire
99 */
100 public boolean terminates() {
101 return flags.contains(BindingFlag.TERMINAL);
102 }
103
104 /**
105 * Query whether this binding result should be skipped when one of its dependencies fails.
106 * @return {@code true} if this binding result should be skipped if one of its dependencies fails.
107 */
108 public boolean isSkippable() {
109 return flags.contains(BindingFlag.SKIPPABLE);
110 }
111
112 public static class Builder {
113 private Desire desire;
114 private CachePolicy policy;
115 private EnumSet<BindingFlag> flags = BindingFlag.emptySet();
116
117 private Builder() {}
118
119 public Builder setDesire(Desire desire) {
120 this.desire = desire;
121 return this;
122 }
123
124 public Builder setCachePolicy(CachePolicy policy) {
125 this.policy = policy;
126 return this;
127 }
128
129 public Builder addFlag(BindingFlag flag) {
130 flags.add(flag);
131 return this;
132 }
133
134 public Builder setFlags(EnumSet<BindingFlag> flags) {
135 this.flags = flags.clone();
136 return this;
137 }
138
139 public BindingResult build() {
140 com.google.common.base.Preconditions.checkState(desire != null, "no desire set");
141 com.google.common.base.Preconditions.checkState(policy != null, "no policy set");
142 return new BindingResult(desire, policy, flags);
143 }
144 }
145 }