View Javadoc
1   /*
2    * #%L
3    * QueryVersionVisitor.java - mongodb-async-driver - Allanbank Consulting, Inc.
4    * %%
5    * Copyright (C) 2011 - 2014 Allanbank Consulting, Inc.
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   * 
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package com.allanbank.mongodb.client.message;
21  
22  import com.allanbank.mongodb.Version;
23  import com.allanbank.mongodb.bson.Document;
24  import com.allanbank.mongodb.bson.VisitorAdapter;
25  import com.allanbank.mongodb.builder.Find;
26  import com.allanbank.mongodb.builder.GeospatialOperator;
27  import com.allanbank.mongodb.builder.MiscellaneousOperator;
28  import com.allanbank.mongodb.client.VersionRange;
29  
30  /**
31   * QueryVersionVisitor provides the ability to inspect a query document for the
32   * required server version.
33   * 
34   * @copyright 2013, Allanbank Consulting, Inc., All Rights Reserved
35   */
36  public class QueryVersionVisitor extends VisitorAdapter {
37  
38      /**
39       * Helper to returns the required server version to support the query
40       * operators.
41       * 
42       * @param query
43       *            The query to inspect.
44       * @return The version of the server that is required to support to support
45       *         the query. May be {@code null}.
46       */
47      public static VersionRange version(final Document query) {
48          final QueryVersionVisitor visitor = new QueryVersionVisitor();
49  
50          if (query != null) {
51              query.accept(visitor);
52          }
53  
54          return VersionRange.range(visitor.getRequiredServerVersion(),
55                  visitor.getMaximumServerVersion());
56      }
57  
58      /**
59       * The version of the server that removed the ability to process the visited
60       * query.
61       */
62      private Version myMaximumServerVersion;
63  
64      /** The required server version to support the query. */
65      private Version myRequiredServerVersion;
66  
67      /**
68       * Creates a new QueryVersionVisitor.
69       */
70      public QueryVersionVisitor() {
71          myRequiredServerVersion = null;
72      }
73  
74      /**
75       * Returns the version of the server that removed the ability to process the
76       * visited query.
77       * 
78       * @return The version of the server that removed the ability to process the
79       *         visited query.
80       */
81      public Version getMaximumServerVersion() {
82          return myMaximumServerVersion;
83      }
84  
85      /**
86       * Returns the required server version to support the visited query.
87       * 
88       * @return The required server version to support the visited query.
89       */
90      public Version getRequiredServerVersion() {
91          return myRequiredServerVersion;
92      }
93  
94      /**
95       * <p>
96       * Overridden to determine the version of the server required based on the
97       * query operators.
98       * </p>
99       * {@inheritDoc}
100      */
101     @SuppressWarnings("deprecation")
102     @Override
103     protected void visitName(final String name) {
104         if (GeospatialOperator.GEO_WITHIN.getToken().equals(name)) {
105             myRequiredServerVersion = Version.later(myRequiredServerVersion,
106                     GeospatialOperator.GEO_WITHIN.getVersion());
107         }
108         else if (GeospatialOperator.INTERSECT.getToken().equals(name)) {
109             myRequiredServerVersion = Version.later(myRequiredServerVersion,
110                     GeospatialOperator.INTERSECT.getVersion());
111         }
112         else if (GeospatialOperator.POLYGON.equals(name)) {
113             myRequiredServerVersion = Version.later(myRequiredServerVersion,
114                     GeospatialOperator.POLYGON_VERSION);
115         }
116         else if ("$maxTimeMS".equals(name)) {
117             myRequiredServerVersion = Version.later(myRequiredServerVersion,
118                     Find.MAX_TIMEOUT_VERSION);
119         }
120         else if (MiscellaneousOperator.COMMENT.getToken().equals(name)) {
121             myRequiredServerVersion = Version.later(myRequiredServerVersion,
122                     MiscellaneousOperator.COMMENT.getVersion());
123         }
124         else if (MiscellaneousOperator.TEXT.getToken().equals(name)) {
125             myRequiredServerVersion = Version.later(myRequiredServerVersion,
126                     MiscellaneousOperator.TEXT.getVersion());
127         }
128         else if (GeospatialOperator.UNIQUE_DOCS_MODIFIER.equals(name)) {
129             myMaximumServerVersion = Version.earlier(myMaximumServerVersion,
130                     GeospatialOperator.UNIQUE_DOCS_REMOVED_VERSION);
131         }
132     }
133 }