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