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.
29 * A range query is composed of one or more operator/value pairs which define the upper and lower bounds of the range,
30 * and a field to apply the query to.
33 * Operators may be one of the following:
35 * <li>gt - Greater than.</li>
36 * <li>gte - Greater than or equal to.</li>
37 * <li>lt - Less than.</li>
38 * <li>lte - Less than or equal to.</li>
40 * Values may be either numeric values (Integer or Double) or Strings representing dates.
43 * The following examples illustrate a couple of variants of the range query:
48 * // A simple numeric range query:
51 * "field": "fieldname",
57 * // A simple date range query:
60 * "field": "fieldname",
61 * "gt": "2016-10-06T00:00:00.558+03:00",
62 * "lt": "2016-10-06T23:59:59.558+03:00"
67 public class RangeQuery {
70 * The name of the field to apply the range query against.
75 * The value of the field must be greater than this value to be a match.<br>
76 * NOTE: Only one of 'gt' or 'gte' should be set on any single {@link RangeQuery} instance.
81 * The value of the field must be greater than or equal to this value to be a match.<br>
82 * NOTE: Only one of 'gt' or 'gte' should be set on any single {@link RangeQuery} instance.
87 * The value of the field must be less than this value to be a match.<br>
88 * NOTE: Only one of 'lt' or 'lte' should be set on any single {@link RangeQuery} instance.
93 * The value of the field must be less than or equal to than this value to be a match.<br>
94 * NOTE: Only one of 'lt' or 'lte' should be set on any single {@link RangeQuery} instance.
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)) || ((lte != null) && !typesMatch(gt, lte))) {
125 throw new IllegalArgumentException("Cannot mix date and numeric values in the same ranged query");
128 // If we made it here, then we're all good. Store the value.
131 throw new IllegalArgumentException("Cannot assign both 'gt' and 'gte' fields in the same ranged query");
136 public Object getGte() {
140 public void setGte(Object gte) {
142 // It does not make sense to assign a value to both the 'greater than'
143 // and 'greater than or equal' operations, so make sure we are not
144 // trying to do that.
147 // Make sure that we are not trying to mix both numeric and date
148 // type values in the same queries.
149 if (((lt != null) && !typesMatch(gte, lt)) || ((lte != null) && !typesMatch(gte, lte))) {
150 throw new IllegalArgumentException("Cannot mix date and numeric values in the same ranged query");
153 // If we made it here, then we're all good. Store the value.
157 throw new IllegalArgumentException("Cannot assign both 'gt' and 'gte' fields in the same ranged query");
161 public Object getLt() {
165 public void setLt(Object lt) {
167 // It does not make sense to assign a value to both the 'less than'
168 // and 'less than or equal' operations, so make sure we are not
169 // trying to do that.
172 // Make sure that we are not trying to mix both numeric and date
173 // type values in the same queries.
174 if (((gt != null) && !typesMatch(lt, gt)) || ((gte != null) && !typesMatch(lt, gte))) {
175 throw new IllegalArgumentException("Cannot mix date and numeric values in the same ranged query");
178 // If we made it here, then we're all good. Store the value.
182 throw new IllegalArgumentException("Cannot assign both 'lt' and 'lte' fields in the same ranged query");
186 public Object getLte() {
190 public void setLte(Object lte) {
192 // It does not make sense to assign a value to both the 'greater than'
193 // and 'greater than or equal' operations, so make sure we are not
194 // trying to do that.
197 // Make sure that we are not trying to mix both numeric and date
198 // type values in the same queries.
199 if (((gt != null) && !typesMatch(lte, gt)) || ((gte != null) && !typesMatch(lte, gte))) {
200 throw new IllegalArgumentException("Cannot mix date and numeric values in the same ranged query");
203 // If we made it here, then we're all good. Store the value.
207 throw new IllegalArgumentException("Cannot assign both 'lt' and 'lte' fields in the same ranged query");
211 public String getFormat() {
215 public void setFormat(String format) {
216 this.format = format;
219 public String getTimeZone() {
223 public void setTimeZone(String timeZone) {
224 this.timeZone = timeZone;
228 * This convenience method determines whether or not the supplied value needs to be enclosed in '"' characters when
229 * generating ElasticSearch compatible syntax.
231 * @param val - The value to check.
232 * @return - A string representation of the value for inclusion in an ElasticSearch syntax string.
234 private String formatStringOrNumericVal(Object val) {
236 if (val instanceof String) {
237 return "\"" + val.toString() + "\"";
239 return val.toString();
245 * This convenience method verifies that the supplied objects are of classes considered to be compatible for a
248 * @param value1 - The first value to check.
249 * @param value2 - The second value to check.
250 * @return - True if the two objects are compatible for inclusion in the same ranged query, False, otherwise.
252 boolean typesMatch(Object value1, Object value2) {
254 return ((value1 instanceof String) && (value2 instanceof String))
255 || (!(value1 instanceof String) && !(value2 instanceof String));
260 * This method returns a string which represents this query in syntax that is understandable by ElasticSearch and is
261 * suitable for inclusion in an ElasticSearch query string.
263 * @return - ElasticSearch syntax string.
265 public String toElasticSearch() {
267 StringBuilder sb = new StringBuilder();
270 sb.append("\"range\": {");
271 sb.append("\"").append(field).append("\": {");
273 // We may have one or zero of 'greater than' or 'greater
275 boolean needComma = false;
277 sb.append("\"gte\": ").append(formatStringOrNumericVal(gte));
279 } else if (gt != null) {
280 sb.append("\"gt\": ").append(formatStringOrNumericVal(gt));
284 // We may have one or zero of 'less than' or 'less
290 sb.append("\"lte\": ").append(formatStringOrNumericVal(lte));
291 } else if (lt != null) {
295 sb.append("\"lt\": ").append(formatStringOrNumericVal(lt));
298 // Append the format specifier if one was provided.
299 if (format != null) {
300 sb.append(", \"format\": \"").append(format).append("\"");
303 // Append the time zone specifier if one was provided.
304 if (timeZone != null) {
305 sb.append(", \"time_zone\": \"").append(timeZone).append("\"");
312 return sb.toString();
316 public String toString() {
318 String str = "{ field: " + field + ", ";
322 } else if (gte != null) {
323 str += "gte: " + gte;
327 str += (((gt != null) || (gte != null)) ? ", " : "") + "lt: " + lt;
328 } else if (lte != null) {
329 str += (((gt != null) || (gte != null)) ? ", " : "") + "lte: " + lte;