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.Arrays;
019
020import org.apache.solr.client.solrj.util.ClientUtils;
021
022import org.ametys.cms.content.indexing.solr.SolrFieldNames;
023
024/**
025 * Represents a {@link Query} testing the content language.
026 */
027public class ContentLanguageQuery implements Query
028{
029    
030    /** The operator (can only be EQ or NE). */
031    private Operator _operator;
032    /** The language values to test. */
033    private String[] _values;
034    /** The logical operator between the values. */
035    private LogicalOperator _logicalOperator;
036    
037    /**
038     * Build a ContentLanguageQuery to test if the contentLanguage property exists.
039     */
040    public ContentLanguageQuery()
041    {
042        this(Operator.EXISTS);
043    }
044    
045    /**
046     * Build a ContentLanguageQuery.
047     * @param value the language equality to test.
048     */
049    public ContentLanguageQuery(String value)
050    {
051        this(Operator.EQ, value);
052    }
053    
054    /**
055     * Build a ContentLanguageQuery.
056     * @param values the languages to test.
057     */
058    public ContentLanguageQuery(String... values)
059    {
060        this(Operator.EQ, values);
061    }
062    
063    /**
064     * Build a ContentLanguageQuery.
065     * @param operator the operator.
066     * @param value the language code.
067     */
068    public ContentLanguageQuery(Operator operator, String value)
069    {
070        this(operator, LogicalOperator.OR, new String[] {value});
071    }
072    
073    /**
074     * Build a ContentLanguageQuery.
075     * @param operator the operator.
076     * @param values the language codes.
077     */
078    public ContentLanguageQuery(Operator operator, String... values)
079    {
080        this(operator, LogicalOperator.OR, values);
081    }
082    
083    /**
084     * Build a ContentLanguageQuery.
085     * @param operator the operator.
086     * @param logicalOperator the logical operator.
087     * @param values the language codes.
088     */
089    public ContentLanguageQuery(Operator operator, LogicalOperator logicalOperator, String... values)
090    {
091        if (Operator.EQ != operator && Operator.NE != operator && Operator.EXISTS != operator)
092        {
093            throw new IllegalArgumentException("Test operator '" + operator + "' is unknown for test's expression.");
094        }
095        
096        _operator = operator;
097        _logicalOperator = logicalOperator;
098        _values = values;
099    }
100    
101    /**
102     * Get the operator.
103     * @return the operator
104     */
105    public Operator getOperator()
106    {
107        return _operator;
108    }
109    
110    /**
111     * Get the values.
112     * @return the values
113     */
114    public String[] getValues()
115    {
116        return _values;
117    }
118    
119    /**
120     * Get the logical operator.
121     * @return the logical operator.
122     */
123    public LogicalOperator getLogicalOperator()
124    {
125        return _logicalOperator;
126    }
127    
128    @Override
129    public String build() throws QuerySyntaxException
130    {
131        if (_operator == Operator.EXISTS)
132        {
133            return SolrFieldNames.CONTENT_LANGUAGE + ":*";
134        }
135        
136        StringBuilder query = new StringBuilder();
137        
138        if (_values.length > 0)
139        {
140            if (_values.length > 1)
141            {
142                query.append('(');
143            }
144            for (int i = 0; i < _values.length; i++)
145            {
146                if (i > 0)
147                {
148                    query.append(' ').append(_logicalOperator).append(' ');
149                }
150                
151                if (_operator == Operator.NE)
152                {
153                    NotQuery.appendNegation(query);
154                }
155                
156                query.append(SolrFieldNames.CONTENT_LANGUAGE).append(":\"").append(ClientUtils.escapeQueryChars(_values[i])).append('"');
157            }
158            if (_values.length > 1)
159            {
160                query.append(')');
161            }
162        }
163        
164        return query.toString();
165    }
166
167    @Override
168    public int hashCode()
169    {
170        final int prime = 31;
171        int result = 1;
172        result = prime * result + ((_logicalOperator == null) ? 0 : _logicalOperator.hashCode());
173        result = prime * result + ((_operator == null) ? 0 : _operator.hashCode());
174        result = prime * result + Arrays.hashCode(_values);
175        return result;
176    }
177
178    @Override
179    public boolean equals(Object obj)
180    {
181        if (this == obj)
182        {
183            return true;
184        }
185        if (obj == null)
186        {
187            return false;
188        }
189        if (getClass() != obj.getClass())
190        {
191            return false;
192        }
193        ContentLanguageQuery other = (ContentLanguageQuery) obj;
194        if (_logicalOperator != other._logicalOperator)
195        {
196            return false;
197        }
198        if (_operator != other._operator)
199        {
200            return false;
201        }
202        if (!Arrays.equals(_values, other._values))
203        {
204            return false;
205        }
206        return true;
207    }
208}