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; 25 26 import java.util.HashMap; 27 import java.util.Map; 28 import net.jcip.annotations.Immutable; 29 import org.modeshape.common.collection.Problems; 30 import org.modeshape.common.collection.SimpleProblems; 31 import org.modeshape.common.util.CheckArg; 32 import org.modeshape.graph.query.model.BindVariableName; 33 import org.modeshape.graph.query.model.TypeSystem; 34 import org.modeshape.graph.query.plan.PlanHints; 35 import org.modeshape.graph.query.validate.Schemata; 36 37 /** 38 * An immutable context in which queries are to be executed. Each query context defines the information that is available during 39 * query execution. 40 */ 41 @Immutable 42 public class QueryContext { 43 private final TypeSystem typeSystem; 44 private final PlanHints hints; 45 private final Schemata schemata; 46 private final Problems problems; 47 private final Map<String, Object> variables; 48 49 /** 50 * Create a new context for query execution. 51 * 52 * @param schemata the schemata 53 * @param typeSystem the types system 54 * @param hints the hints, or null if there are no hints 55 * @param problems the problems container, or null if a new problems container should be created 56 * @param variables the mapping of variables and values, or null if there are no such variables 57 * @throws IllegalArgumentException if the values or schmata are null 58 */ 59 public QueryContext( Schemata schemata, 60 TypeSystem typeSystem, 61 PlanHints hints, 62 Problems problems, 63 Map<String, Object> variables ) { 64 CheckArg.isNotNull(typeSystem, "typeSystem"); 65 CheckArg.isNotNull(schemata, "schemata"); 66 this.typeSystem = typeSystem; 67 this.hints = hints != null ? hints : new PlanHints(); 68 this.schemata = schemata; 69 this.problems = problems != null ? problems : new SimpleProblems(); 70 this.variables = variables != null ? new HashMap<String, Object>(variables) : new HashMap<String, Object>(); 71 assert this.typeSystem != null; 72 assert this.hints != null; 73 assert this.schemata != null; 74 assert this.problems != null; 75 assert this.variables != null; 76 } 77 78 /** 79 * Create a new context for query execution. 80 * 81 * @param schemata the schemata 82 * @param typeSystem the types system 83 * @param hints the hints, or null if there are no hints 84 * @param problems the problems container, or null if a new problems container should be created 85 * @throws IllegalArgumentException if the values or schmata are null 86 */ 87 public QueryContext( Schemata schemata, 88 TypeSystem typeSystem, 89 PlanHints hints, 90 Problems problems ) { 91 this(schemata, typeSystem, hints, problems, null); 92 } 93 94 /** 95 * Create a new context for query execution. 96 * 97 * @param schemata the schemata 98 * @param typeSystem the types system 99 * @param hints the hints, or null if there are no hints 100 * @throws IllegalArgumentException if the context or schmata are null 101 */ 102 public QueryContext( Schemata schemata, 103 TypeSystem typeSystem, 104 PlanHints hints ) { 105 this(schemata, typeSystem, hints, null, null); 106 } 107 108 /** 109 * Create a new context for query execution. 110 * 111 * @param schemata the schemata 112 * @param typeSystem the types system 113 * @throws IllegalArgumentException if the values or schmata are null 114 */ 115 public QueryContext( Schemata schemata, 116 TypeSystem typeSystem ) { 117 this(schemata, typeSystem, null, null, null); 118 } 119 120 /** 121 * Create a new context that is a copy of the supplied context. This constructor is useful for subclasses that wish to add 122 * store additional fields in a QueryContext. 123 * 124 * @param original the original context 125 * @throws IllegalArgumentException if the original is null 126 */ 127 protected QueryContext( QueryContext original ) { 128 this(original.schemata, original.typeSystem, original.hints, original.problems, original.variables); 129 } 130 131 /** 132 * Get the interface for working with literal values and types. 133 * 134 * @return the type system; never null 135 */ 136 public TypeSystem getTypeSystem() { 137 return typeSystem; 138 } 139 140 /** 141 * Get the plan hints. 142 * 143 * @return the plan hints; never null 144 */ 145 public final PlanHints getHints() { 146 return hints; 147 } 148 149 /** 150 * Get the problem container used by this query context. Any problems that have been encountered will be accumlated in this 151 * container. 152 * 153 * @return the problem container; never null 154 */ 155 public final Problems getProblems() { 156 return problems; 157 } 158 159 /** 160 * Get the definition of the tables available within this query context. 161 * 162 * @return the schemata; never null 163 */ 164 public Schemata getSchemata() { 165 return schemata; 166 } 167 168 /** 169 * Get the variables that are to be substituted into the {@link BindVariableName} used in the query. 170 * 171 * @return immutable map of variable values keyed by their name; never null but possibly empty 172 */ 173 public Map<String, Object> getVariables() { 174 return variables; 175 } 176 177 /** 178 * {@inheritDoc} 179 * 180 * @see java.lang.Object#equals(java.lang.Object) 181 */ 182 @Override 183 public boolean equals( Object obj ) { 184 if (obj == this) return true; 185 if (obj instanceof QueryContext) { 186 QueryContext that = (QueryContext)obj; 187 if (!this.typeSystem.equals(that.getTypeSystem())) return false; 188 if (!this.schemata.equals(that.getSchemata())) return false; 189 if (!this.variables.equals(that.getVariables())) return false; 190 return true; 191 } 192 return false; 193 } 194 195 /** 196 * Obtain a copy of this context, except that the copy uses the supplied type system. 197 * 198 * @param typeSystem the type system that should be used in the new query context 199 * @return the new context; never null 200 * @throws IllegalArgumentException if the execution context reference is null 201 */ 202 public QueryContext with( TypeSystem typeSystem ) { 203 CheckArg.isNotNull(typeSystem, "typeSystem"); 204 return new QueryContext(schemata, typeSystem, hints, problems, variables); 205 } 206 207 /** 208 * Obtain a copy of this context, except that the copy uses the supplied schemata. 209 * 210 * @param schemata the schemata that should be used in the new context 211 * @return the new context; never null 212 * @throws IllegalArgumentException if the schemata reference is null 213 */ 214 public QueryContext with( Schemata schemata ) { 215 CheckArg.isNotNull(schemata, "schemata"); 216 return new QueryContext(schemata, typeSystem, hints, problems, variables); 217 } 218 219 /** 220 * Obtain a copy of this context, except that the copy uses the supplied hints. 221 * 222 * @param hints the hints that should be used in the new context 223 * @return the new context; never null 224 * @throws IllegalArgumentException if the hints reference is null 225 */ 226 public QueryContext with( PlanHints hints ) { 227 CheckArg.isNotNull(hints, "hints"); 228 return new QueryContext(schemata, typeSystem, hints, problems, variables); 229 } 230 231 /** 232 * Obtain a copy of this context, except that the copy uses the supplied problem container. 233 * 234 * @param problems the problems that should be used in the new context; may be null if a new problem container should be used 235 * @return the new context; never null 236 */ 237 public QueryContext with( Problems problems ) { 238 return new QueryContext(schemata, typeSystem, hints, problems, variables); 239 } 240 241 /** 242 * Obtain a copy of this context, except that the copy uses the supplied variables. 243 * 244 * @param variables the variables that should be used in the new context; may be null if there are no such variables 245 * @return the new context; never null 246 */ 247 public QueryContext with( Map<String, Object> variables ) { 248 return new QueryContext(schemata, typeSystem, hints, problems, variables); 249 } 250 251 }