View Javadoc

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 }