001/* 002 * Copyright 2015 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.HashMap; 019import java.util.Map; 020 021/** 022 * Represents a search predicate. 023 */ 024@FunctionalInterface 025public interface Query 026{ 027 /** Constant for mandatory boolean clauses */ 028 public static final String BOOL_MUST = "must"; 029 030 /** Constant for prohibited boolean clauses */ 031 public static final String BOOL_MUST_NOT = "must_not"; 032 033 /** Constant for optional boolean clauses */ 034 public static final String BOOL_SHOULD = "should"; 035 036 /** Constant for mandatory, but not affecting score, boolean clauses */ 037 public static final String BOOL_FILTER = "filter"; 038 039 /** Enumeration of available operators in {@link Query} */ 040 public enum Operator 041 { 042 /** Operator testing the existence of a property. */ 043 EXISTS("exists"), 044 /** Constant of test's operator for textual search, on unstemmed terms. Works only for type String */ 045 SEARCH("search"), 046 /** Constant of test's operator for textual search, on stemmed terms. Works only for type String */ 047 SEARCH_STEMMED("searchStemmed"), 048 /** Constant of test's operator for 'like' comparison. Works only for type String */ 049 LIKE("like"), 050 /** Constant of test's operator for fuzzy search. Works only for type String */ 051 FUZZY("fuzzy"), 052 /** Constant of test's operator for 'less than' comparison */ 053 LT("lt"), 054 /** Constant of test's operator for 'less than or equals to' comparison */ 055 LE("le"), 056 /** Constant of test's operator for 'greater than' comparison */ 057 GT("gt"), 058 /** Constant of test's operator for 'greater than or equals to' comparison */ 059 GE("ge"), 060 /** Constant of test's operator for 'equals to' comparison */ 061 EQ("eq"), 062 /** Constant of test's operator for 'not equals to' comparison */ 063 NE("ne"); 064 065 private static Map<String, Operator> _OP_NAMES = new HashMap<>(); 066 static 067 { 068 for (Operator op : values()) 069 { 070 _OP_NAMES.put(op.getName(), op); 071 } 072 } 073 074 private final String _name; 075 076 Operator(String name) 077 { 078 _name = name; 079 } 080 081 /** 082 * Get the operator name. 083 * @return the operator name. 084 */ 085 public String getName() 086 { 087 return _name; 088 } 089 090 /** 091 * Get an Operator object from its name. 092 * @param name the operator name. 093 * @return the operator object, or null if not found. 094 */ 095 public static Operator fromName(String name) 096 { 097 if (_OP_NAMES.containsKey(name)) 098 { 099 return _OP_NAMES.get(name); 100 } 101 throw new IllegalArgumentException("No operator with code '" + name + "'"); 102 } 103 } 104 105 /** Enumeration of available logical operators in {@link Query} */ 106 public enum LogicalOperator 107 { 108 /** Logical operator AND */ 109 AND, 110 /** Logical operator OR */ 111 OR 112 } 113 114 /** 115 * Build the solr query string representing the Query object. 116 * @return the solr query string representing the Query object. 117 * @throws QuerySyntaxException if the query can't be built because of a syntax error. 118 */ 119 String build() throws QuerySyntaxException; 120 121 /** 122 * Build the solr query representing the Query object.<br> 123 * The return type may be either String or Map<String, Object> following the Solr JSON Query DSL. 124 * @return the solr query representing the Query object. 125 * @throws QuerySyntaxException if the query can't be built because of a syntax error. 126 */ 127 default Object buildAsJson() throws QuerySyntaxException 128 { 129 return build(); 130 } 131 132 /** 133 * Rewrite this Query to allow further optimisations. 134 * @return a rewritten Query, sementically identical 135 */ 136 default Query rewrite() 137 { 138 return this; 139 } 140 141 /** 142 * Gets a representation of this {@link Query}, for pretty-printing for logging and debugging purposes 143 * @param indent The current indentation. Base indentation is 2 (for printing a sub-level) 144 * @return a representation of this {@link Query} 145 */ 146 default String toString(int indent) 147 { 148 return QueryDebugger.toDebugString(this, indent); 149 } 150}