2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * Copyright © 2017-2018 Amdocs
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
21 package org.onap.aai.sa.searchdbabstraction.searchapi;
23 import com.fasterxml.jackson.annotation.JsonProperty;
26 * This class represents a simple range query.
28 * <p>A range query is composed of one or more operator/value pairs which define
29 * the upper and lower bounds of the range, and a field to apply the query to.
31 * <p>Operators may be one of the following:
33 * <li>gt - Greater than. </li>
34 * <li>gte - Greater than or equal to. </li>
35 * <li>lt - Less than. </li>
36 * <li>lte - Less than or equal to. </li>
38 * Values may be either numeric values (Integer or Double) or Strings representing
41 * <p>The following examples illustrate a couple of variants of the range query:
44 * // A simple numeric range query:
47 * "field": "fieldname",
53 * // A simple date range query:
56 * "field": "fieldname",
57 * "gt": "2016-10-06T00:00:00.558+03:00",
58 * "lt": "2016-10-06T23:59:59.558+03:00"
63 public class RangeQuery {
66 * The name of the field to apply the range query against.
71 * The value of the field must be greater than this value to be a match.<br>
72 * NOTE: Only one of 'gt' or 'gte' should be set on any single {@link RangeQuery}
78 * The value of the field must be greater than or equal to this value to be a match.<br>
79 * NOTE: Only one of 'gt' or 'gte' should be set on any single {@link RangeQuery}
85 * The value of the field must be less than this value to be a match.<br>
86 * NOTE: Only one of 'lt' or 'lte' should be set on any single {@link RangeQuery}
92 * The value of the field must be less than or equal to than this value to be a match.<br>
93 * NOTE: Only one of 'lt' or 'lte' should be set on any single {@link RangeQuery}
98 private String format;
100 @JsonProperty("time-zone")
101 private String timeZone;
103 public String getField() {
107 public void setField(String field) {
111 public Object getGt() {
115 public void setGt(Object gt) {
117 // It does not make sense to assign a value to both the 'greater than'
118 // and 'greater than or equal' operations, so make sure we are not
119 // trying to do that.
122 // Make sure that we are not trying to mix both numeric and date
123 // type values in the same queries.
124 if (((lt != null) && !typesMatch(gt, lt))
125 || ((lte != null) && !typesMatch(gt, lte))) {
126 throw new IllegalArgumentException("Cannot mix date and numeric values in the same ranged query");
129 // If we made it here, then we're all good. Store the value.
132 throw new IllegalArgumentException("Cannot assign both 'gt' and 'gte' fields in the same ranged query");
137 public Object getGte() {
141 public void setGte(Object gte) {
143 // It does not make sense to assign a value to both the 'greater than'
144 // and 'greater than or equal' operations, so make sure we are not
145 // trying to do that.
148 // Make sure that we are not trying to mix both numeric and date
149 // type values in the same queries.
150 if (((lt != null) && !typesMatch(gte, lt))
151 || ((lte != null) && !typesMatch(gte, lte))) {
152 throw new IllegalArgumentException("Cannot mix date and numeric values in the same ranged query");
155 // If we made it here, then we're all good. Store the value.
159 throw new IllegalArgumentException("Cannot assign both 'gt' and 'gte' fields in the same ranged query");
163 public Object getLt() {
167 public void setLt(Object lt) {
169 // It does not make sense to assign a value to both the 'less than'
170 // and 'less than or equal' operations, so make sure we are not
171 // trying to do that.
174 // Make sure that we are not trying to mix both numeric and date
175 // type values in the same queries.
176 if (((gt != null) && !typesMatch(lt, gt))
177 || ((gte != null) && !typesMatch(lt, gte))) {
178 throw new IllegalArgumentException("Cannot mix date and numeric values in the same ranged query");
181 // If we made it here, then we're all good. Store the value.
185 throw new IllegalArgumentException("Cannot assign both 'lt' and 'lte' fields in the same ranged query");
189 public Object getLte() {
193 public void setLte(Object lte) {
195 // It does not make sense to assign a value to both the 'greater than'
196 // and 'greater than or equal' operations, so make sure we are not
197 // trying to do that.
200 // Make sure that we are not trying to mix both numeric and date
201 // type values in the same queries.
202 if (((gt != null) && !typesMatch(lte, gt))
203 || ((gte != null) && !typesMatch(lte, gte))) {
204 throw new IllegalArgumentException("Cannot mix date and numeric values in the same ranged query");
207 // If we made it here, then we're all good. Store the value.
211 throw new IllegalArgumentException("Cannot assign both 'lt' and 'lte' fields in the same ranged query");
215 public String getFormat() {
219 public void setFormat(String format) {
220 this.format = format;
223 public String getTimeZone() {
227 public void setTimeZone(String timeZone) {
228 this.timeZone = timeZone;
232 * This convenience method determines whether or not the supplied
233 * value needs to be enclosed in '"' characters when generating
234 * ElasticSearch compatible syntax.
236 * @param val - The value to check.
237 * @return - A string representation of the value for inclusion
238 * in an ElasticSearch syntax string.
240 private String formatStringOrNumericVal(Object val) {
242 if (val instanceof String) {
243 return "\"" + val.toString() + "\"";
245 return val.toString();
251 * This convenience method verifies that the supplied objects are
252 * of classes considered to be compatible for a ranged query.
254 * @param value1 - The first value to check.
255 * @param value2 - The second value to check.
256 * @return - True if the two objects are compatible for inclusion in the
257 * same ranged query, False, otherwise.
259 boolean typesMatch(Object value1, Object value2) {
261 return ((value1 instanceof String) && (value2 instanceof String))
262 || (!(value1 instanceof String) && !(value2 instanceof String));
267 * This method returns a string which represents this query in syntax
268 * that is understandable by ElasticSearch and is suitable for inclusion
269 * in an ElasticSearch query string.
271 * @return - ElasticSearch syntax string.
273 public String toElasticSearch() {
275 StringBuilder sb = new StringBuilder();
278 sb.append("\"range\": {");
279 sb.append("\"").append(field).append("\": {");
281 // We may have one or zero of 'greater than' or 'greater
283 boolean needComma = false;
285 sb.append("\"gte\": ").append(formatStringOrNumericVal(gte));
287 } else if (gt != null) {
288 sb.append("\"gt\": ").append(formatStringOrNumericVal(gt));
292 // We may have one or zero of 'less than' or 'less
298 sb.append("\"lte\": ").append(formatStringOrNumericVal(lte));
299 } else if (lt != null) {
303 sb.append("\"lt\": ").append(formatStringOrNumericVal(lt));
306 // Append the format specifier if one was provided.
307 if (format != null) {
308 sb.append(", \"format\": \"").append(format).append("\"");
311 // Append the time zone specifier if one was provided.
312 if (timeZone != null) {
313 sb.append(", \"time_zone\": \"").append(timeZone).append("\"");
320 return sb.toString();
324 public String toString() {
326 String str = "{ field: " + field + ", ";
330 } else if (gte != null) {
331 str += "gte: " + gte;
335 str += (((gt != null) || (gte != null)) ? ", " : "") + "lt: " + lt;
336 } else if (lte != null) {
337 str += (((gt != null) || (gte != null)) ? ", " : "") + "lte: " + lte;