1 /*
2 * ModeShape (http://www.modeshape.org)
3 * See the COPYRIGHT.txt file distributed with this work for information
4 * regarding copyright ownership. Some portions may be licensed
5 * to Red Hat, Inc. under one or more contributor license agreements.
6 * See the AUTHORS.txt file in the distribution for a full listing of
7 * individual contributors.
8 *
9 * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10 * is licensed to you under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
13 *
14 * ModeShape is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this software; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23 */
24 package org.modeshape.graph.query.model;
25
26 import net.jcip.annotations.Immutable;
27 import org.modeshape.common.util.CheckArg;
28 import org.modeshape.common.util.HashCode;
29
30 /**
31 * A constraint that evaluates to true when the value defined by the dynamic operand evaluates to be within the specified range.
32 */
33 @Immutable
34 public class Between implements Constraint {
35
36 private static final long serialVersionUID = 1L;
37
38 private final DynamicOperand operand;
39 private final StaticOperand lowerBound;
40 private final StaticOperand upperBound;
41 private final boolean includeLowerBound;
42 private final boolean includeUpperBound;
43 private final int hc;
44
45 /**
46 * Create a constraint that the values of the supplied dynamic operand are between the lower and upper bounds (inclusive).
47 *
48 * @param operand the dynamic operand describing the values that are to be constrained
49 * @param lowerBound the lower bound of the range
50 * @param upperBound the upper bound of the range
51 * @throws IllegalArgumentException if any of the arguments are null
52 */
53 public Between( DynamicOperand operand,
54 StaticOperand lowerBound,
55 StaticOperand upperBound ) {
56 this(operand, lowerBound, upperBound, true, true);
57 }
58
59 /**
60 * Create a constraint that the values of the supplied dynamic operand are between the lower and upper bounds, specifying
61 * whether the boundary values are to be included in the range.
62 *
63 * @param operand the dynamic operand describing the values that are to be constrained
64 * @param lowerBound the lower bound of the range
65 * @param upperBound the upper bound of the range
66 * @param includeLowerBound true if the lower boundary value is not be included
67 * @param includeUpperBound true if the upper boundary value is not be included
68 * @throws IllegalArgumentException if any of the arguments are null
69 */
70 public Between( DynamicOperand operand,
71 StaticOperand lowerBound,
72 StaticOperand upperBound,
73 boolean includeLowerBound,
74 boolean includeUpperBound ) {
75 CheckArg.isNotNull(operand, "operand");
76 CheckArg.isNotNull(lowerBound, "lowerBound");
77 CheckArg.isNotNull(upperBound, "upperBound");
78 this.operand = operand;
79 this.lowerBound = lowerBound;
80 this.upperBound = upperBound;
81 this.includeLowerBound = includeLowerBound;
82 this.includeUpperBound = includeUpperBound;
83 this.hc = HashCode.compute(this.operand, this.lowerBound, this.upperBound);
84 }
85
86 /**
87 * Get the dynamic operand specification.
88 *
89 * @return the dynamic operand; never null
90 */
91 public DynamicOperand operand() {
92 return operand;
93 }
94
95 /**
96 * Get the lower bound operand.
97 *
98 * @return the lower bound; never null
99 */
100 public StaticOperand lowerBound() {
101 return lowerBound;
102 }
103
104 /**
105 * Get the upper bound operand.
106 *
107 * @return the upper bound; never null
108 */
109 public StaticOperand upperBound() {
110 return upperBound;
111 }
112
113 /**
114 * Return whether the lower bound is to be included in the results.
115 *
116 * @return true if the {@link #lowerBound() lower bound} is to be included, or false otherwise
117 */
118 public boolean isLowerBoundIncluded() {
119 return includeLowerBound;
120 }
121
122 /**
123 * Return whether the upper bound is to be included in the results.
124 *
125 * @return true if the {@link #upperBound() upper bound} is to be included, or false otherwise
126 */
127 public boolean isUpperBoundIncluded() {
128 return includeUpperBound;
129 }
130
131 /**
132 * {@inheritDoc}
133 *
134 * @see java.lang.Object#toString()
135 */
136 @Override
137 public String toString() {
138 return Visitors.readable(this);
139 }
140
141 /**
142 * {@inheritDoc}
143 *
144 * @see java.lang.Object#hashCode()
145 */
146 @Override
147 public int hashCode() {
148 return hc;
149 }
150
151 /**
152 * {@inheritDoc}
153 *
154 * @see java.lang.Object#equals(java.lang.Object)
155 */
156 @Override
157 public boolean equals( Object obj ) {
158 if (obj == this) return true;
159 if (obj instanceof Between) {
160 Between that = (Between)obj;
161 if (this.hc != that.hc) return false;
162 if (!this.operand.equals(that.operand)) return false;
163 if (!this.lowerBound.equals(that.lowerBound)) return false;
164 if (!this.upperBound.equals(that.upperBound)) return false;
165 if (this.includeLowerBound != that.includeLowerBound) return false;
166 if (this.includeUpperBound != that.includeUpperBound) return false;
167 return true;
168 }
169 return false;
170 }
171
172 /**
173 * {@inheritDoc}
174 *
175 * @see org.modeshape.graph.query.model.Visitable#accept(org.modeshape.graph.query.model.Visitor)
176 */
177 public void accept( Visitor visitor ) {
178 visitor.visit(this);
179 }
180 }