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    
028    /** Enumeration of available operators in {@link Query} */
029    public enum Operator 
030    {
031        /** Operator testing the existence of a property. */
032        EXISTS("exists"),
033        /** Constant of test's operator for textual search, on unstemmed terms. Works only for type String */
034        SEARCH("search"),
035        /** Constant of test's operator for textual search, on stemmed terms. Works only for type String */
036        SEARCH_STEMMED("searchStemmed"),
037        /** Constant of test's operator for 'like' comparison. Works only for type String */
038        LIKE("like"), 
039        /** Constant of test's operator for fuzzy search. Works only for type String */
040        FUZZY("fuzzy"),
041        /** Constant of test's operator for 'less than' comparison */
042        LT("lt"),
043        /** Constant of test's operator for 'less than or equals to' comparison */
044        LE("le"),
045        /** Constant of test's operator for 'greater than' comparison */
046        GT("gt"),
047        /** Constant of test's operator for 'greater than or equals to' comparison */
048        GE("ge"),
049        /** Constant of test's operator for 'equals to' comparison */
050        EQ("eq"),
051        /** Constant of test's operator for 'not equals to' comparison */
052        NE("ne");
053        
054        private static Map<String, Operator> _OP_NAMES = new HashMap<>();
055        static 
056        {
057            for (Operator op : values())
058            {
059                _OP_NAMES.put(op.getName(), op);
060            }
061        }
062        
063        private final String _name;
064        
065        Operator(String name)
066        {
067            _name = name;
068        }
069        
070        /**
071         * Get the operator name.
072         * @return the operator name.
073         */
074        public String getName()
075        {
076            return _name;
077        }
078        
079        /**
080         * Get an Operator object from its name.
081         * @param name the operator name.
082         * @return the operator object, or null if not found.
083         */
084        public static Operator fromName(String name)
085        {
086            if (_OP_NAMES.containsKey(name))
087            {
088                return _OP_NAMES.get(name);
089            }
090            throw new IllegalArgumentException("No operator with code '" + name + "'");
091        }
092    }
093    
094    /** Enumeration of available logical operators in {@link Query} */
095    public enum LogicalOperator 
096    {
097        /** Logical operator AND */
098        AND,
099        /** Logical operator OR */
100        OR
101    }
102    
103    /**
104     * Build the solr query string representing the Query object.
105     * @return the solr query string representing the Query object.
106     * @throws QuerySyntaxException if the query can't be built because of a syntax error.
107     */
108    String build() throws QuerySyntaxException;
109    
110    /**
111     * Gets a representation of this {@link Query}, for pretty-printing for logging and debugging purposes
112     * @param indent The current indentation. Base indentation is 2 (for printing a sub-level)
113     * @return a representation of this {@link Query}
114     */
115    default String toString(int indent)
116    {
117        return QueryDebugger.toDebugString(this, indent);
118    }
119}