001/* 002 * Copyright 2022 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.cms.search.query; 017 018import java.util.Objects; 019 020/** 021 * Base class for all range-based queries. 022 * @param <T> the value type. 023 */ 024public abstract class AbstractRangeQuery<T> implements Query 025{ 026 private String _fieldName; 027 private T _lower; 028 private T _upper; 029 private boolean _includeLower; 030 private boolean _includeUpper; 031 032 /** 033 * Build a range query. 034 * @param fieldName The field path. 035 * @param lowerBound The lower end of the range. 036 * @param upperBound The upper end of the range. 037 * @param includeLower Whether to include the lower end or not. 038 * @param includeUpper Whether to include the upper end or not. 039 */ 040 public AbstractRangeQuery(String fieldName, T lowerBound, T upperBound, boolean includeLower, boolean includeUpper) 041 { 042 _fieldName = fieldName; 043 _lower = lowerBound; 044 _upper = upperBound; 045 _includeLower = includeLower; 046 _includeUpper = includeUpper; 047 } 048 049 /** 050 * Returns the Solr field name. 051 * @return the field name 052 */ 053 public String getFieldName() 054 { 055 return _fieldName; 056 } 057 058 /** 059 * Returns true if the query should include the lower bound. 060 * @return true if the query should include the lower bound. 061 */ 062 public boolean includeLowerBound() 063 { 064 return _includeLower; 065 } 066 067 /** 068 * Returns true if the query should include the upper bound. 069 * @return true if the query should include the upper bound. 070 */ 071 public boolean includeUpperBound() 072 { 073 return _includeUpper; 074 } 075 076 /** 077 * Returns the lower bound of the range. 078 * @return the lower bound of the range. 079 */ 080 public T getLowerBound() 081 { 082 return _lower; 083 } 084 085 /** 086 * Returns the upper bound of the range. 087 * @return the upper bound of the range. 088 */ 089 public T getUpperBound() 090 { 091 return _upper; 092 } 093 094 /** 095 * Computes the lower bound for Solr client 096 * @param value the typed value 097 * @return the value, adapted for Solr 098 */ 099 public String lowerBoundForQuery(T value) 100 { 101 return value.toString(); 102 } 103 104 /** 105 * Computes the upper bound for Solr client 106 * @param value the typed value 107 * @return the value, adapted for Solr 108 */ 109 public String upperBoundForQuery(T value) 110 { 111 return value.toString(); 112 } 113 114 public String build() throws QuerySyntaxException 115 { 116 StringBuilder query = new StringBuilder(); 117 118 query.append(getFieldName()) 119 .append(includeLowerBound() ? '[' : '{') 120 .append(lowerBoundForQuery(getLowerBound())).append(" TO ").append(upperBoundForQuery(getUpperBound())) 121 .append(includeUpperBound() ? ']' : '}'); 122 123 return query.toString(); 124 } 125 126 @Override 127 public int hashCode() 128 { 129 return Objects.hash(_fieldName, _lower, _upper, _includeLower, _includeUpper); 130 } 131 132 @Override 133 public boolean equals(Object obj) 134 { 135 if (this == obj) 136 { 137 return true; 138 } 139 140 if (obj == null || getClass() != obj.getClass()) 141 { 142 return false; 143 } 144 145 AbstractRangeQuery other = (AbstractRangeQuery) obj; 146 return Objects.equals(_fieldName, other._fieldName) 147 && Objects.equals(_lower, other._lower) 148 && Objects.equals(_upper, other._upper) 149 && Objects.equals(_includeLower, other._includeLower) 150 && Objects.equals(_includeUpper, other._includeUpper); 151 } 152}