001/* 002 * Copyright 2014 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 020import org.ametys.cms.content.indexing.solr.SolrFieldNames; 021import org.ametys.cms.search.QueryBuilder; 022 023/** 024 * A {@link Query} realizing a full-text search on contents (search on all properties). 025 * Available operators:<ul> 026 * <li>SEARCH (default)</li> 027 * <li>SEARCH_STEMMED</li> 028 * <li>LIKE</li> 029 * <li>EQ</li> 030 * </ul> 031 */ 032public class FullTextQuery implements Query 033{ 034 /** The value to test. */ 035 protected String _value; 036 /** The language. */ 037 protected String _language; 038 /** The operator. */ 039 protected Operator _operator; 040 /** <code>true</code> if the value is already escaped and there is no need to escape again the value during {@link #build() the build of the query}. */ 041 protected boolean _valueAlreadyEscaped; 042 043 /** 044 * Build a FullTextQuery. 045 * @param value the value. 046 */ 047 public FullTextQuery(String value) 048 { 049 this(value, Operator.SEARCH); 050 } 051 052 /** 053 * Build a FullTextQuery. 054 * @param value the value. 055 * @param operator The operator to use. 056 */ 057 public FullTextQuery(String value, Operator operator) 058 { 059 this(value, null, operator); 060 } 061 062 /** 063 * Build a FullTextQuery. 064 * @param value the value. 065 * @param language the language. 066 */ 067 public FullTextQuery(String value, String language) 068 { 069 this(value, language, Operator.SEARCH); 070 } 071 072 /** 073 * Build a FullTextQuery. 074 * @param value the value. 075 * @param language the language. 076 * @param operator The operator to use. 077 */ 078 public FullTextQuery(String value, String language, Operator operator) 079 { 080 this(value, language, operator, false); 081 } 082 083 /** 084 * Build a FullTextQuery. 085 * @param value the value. 086 * @param language the language. 087 * @param operator The operator to use. 088 * @param alreadyEscaped true if the value is already escaped and there is no need to escape again the value during {@link #build() the build of the query}. 089 */ 090 public FullTextQuery(String value, String language, Operator operator, boolean alreadyEscaped) 091 { 092 _value = value; 093 _language = language; 094 _operator = operator; 095 _valueAlreadyEscaped = alreadyEscaped; 096 } 097 098 /** 099 * Get the value. 100 * @return the value. 101 */ 102 public String getValue() 103 { 104 return _value; 105 } 106 107 /** 108 * Get the language. 109 * @return the language. 110 */ 111 public String getLanguage() 112 { 113 return _language; 114 } 115 116 /** 117 * Get the operator to use. 118 * @return the operator. 119 */ 120 public Operator getOperator() 121 { 122 return _operator; 123 } 124 125 @Override 126 public String build() throws QuerySyntaxException 127 { 128 String language = _language != null ? _language : QueryBuilder.DEFAULT_LANGUAGE; 129 130 AbstractTextQuery.checkStringValue(_value); 131 132 String escapedValue = _valueAlreadyEscaped ? _value : AbstractTextQuery.escapeStringValue(_value, _operator); 133 134 StringBuilder solrQuery = new StringBuilder(); 135 136 switch (_operator) 137 { 138 case EQ: 139 solrQuery.append(SolrFieldNames.FULL_EXACT_WS) 140 .append(":\"").append(escapedValue).append('"'); 141 break; 142 case LIKE: 143 solrQuery.append(SolrFieldNames.FULL_GENERAL) 144 .append(":(").append(escapedValue).append(')'); 145 break; 146 case SEARCH_STEMMED: 147 solrQuery.append(SolrFieldNames.FULL_STEMMED_PREFIX).append(language) 148 .append(":(").append(escapedValue).append(')'); 149 break; 150 case SEARCH: 151 default: 152 solrQuery.append(SolrFieldNames.FULL_PREFIX).append(language) 153 .append(":(").append(escapedValue).append(')'); 154 break; 155 } 156 157 return solrQuery.toString(); 158 } 159 160 @Override 161 public int hashCode() 162 { 163 return 31 + Objects.hash(_language, _operator, _value); 164 } 165 166 @Override 167 public boolean equals(Object obj) 168 { 169 if (this == obj) 170 { 171 return true; 172 } 173 174 if (obj == null || getClass() != obj.getClass()) 175 { 176 return false; 177 } 178 179 FullTextQuery other = (FullTextQuery) obj; 180 return Objects.equals(_language, other._language) 181 && Objects.equals(_operator, other._operator) 182 && Objects.equals(_value, other._value); 183 } 184}