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.web.search.query;
017
018import java.util.ArrayList;
019import java.util.Arrays;
020import java.util.Collection;
021import java.util.Collections;
022import java.util.List;
023
024import org.apache.solr.client.solrj.util.ClientUtils;
025
026import org.ametys.cms.search.query.NotQuery;
027import org.ametys.cms.search.query.Query;
028import org.ametys.cms.search.query.QuerySyntaxException;
029import org.ametys.web.indexing.solr.SolrWebFieldNames;
030import org.ametys.web.search.systemprop.SiteSystemProperty;
031
032/**
033 * Represents a {@link Query} testing the site property.
034 */
035public class SiteQuery implements Query
036{
037    private Operator _operator;
038    private List<String> _names;
039    
040    
041    /**
042     * Build a SiteQuery to test if the site property exists
043     */
044    public SiteQuery()
045    {
046        this(Operator.EXISTS);
047    }
048    
049    /**
050     * Build a SiteQuery to test if the site property is equals to one of the given site names
051     * @param names the site names.
052     */
053    public SiteQuery(String... names)
054    {
055        this(Operator.EQ, names);
056    }
057    
058    /**
059     * Build a SiteQuery to test if the site property is equals to one of the given site names
060     * @param names the site names.
061     */
062    public SiteQuery(Collection<String> names)
063    {
064        this(Operator.EQ, names);
065    }
066    
067    /**
068     * Build a SiteQuery to test if the site property is equals or different to one of the given site names
069     * @param operator the operator (equals ot not-equals)
070     * @param names the site names.
071     */
072    public SiteQuery(Operator operator, String... names)
073    {
074        this(operator, Arrays.asList(names));
075    }
076    
077    /**
078     * Build a SiteQuery.
079     * @param operator the operator.
080     * @param names the site names.
081     */
082    public SiteQuery(Operator operator, Collection<String> names)
083    {
084        if (Operator.EQ != operator && Operator.NE != operator && Operator.EXISTS != operator)
085        {
086            throw new IllegalArgumentException("Test operator '" + operator + "' is unknown for test's expression.");
087        }
088        
089        _operator = operator;
090        _names = new ArrayList<>(names);
091    }
092    
093    /**
094     * Get the operator.
095     * @return the operator
096     */
097    public Operator getOperator()
098    {
099        return _operator;
100    }
101    
102    /**
103     * Get the site names.
104     * @return the site names.
105     */
106    public List<String> getNames()
107    {
108        return Collections.unmodifiableList(_names);
109    }
110    
111    @Override
112    public String build() throws QuerySyntaxException
113    {
114        if (_operator == Operator.EXISTS)
115        {
116            return SiteSystemProperty.SOLR_FIELD_NAME + ":*";
117        }
118        
119        int count = _names.size();
120        
121        StringBuilder buff = new StringBuilder();
122        
123        if (_operator == Operator.NE)
124        {
125            NotQuery.appendNegation(buff);
126        }
127        if (count > 1)
128        {
129            buff.append('(');
130        }
131        
132        boolean first = true;
133        for (String id : _names)
134        {
135            if (!first)
136            {
137                buff.append(" OR ");
138            }
139            buff.append(SolrWebFieldNames.SITE_NAME).append(':').append(ClientUtils.escapeQueryChars(id));
140            first = false;
141        }
142        
143        if (count > 1)
144        {
145            buff.append(')');
146        }
147        
148        return buff.toString();
149    }
150
151    @Override
152    public int hashCode()
153    {
154        final int prime = 31;
155        int result = 1;
156        result = prime * result + ((_names == null) ? 0 : _names.hashCode());
157        result = prime * result + ((_operator == null) ? 0 : _operator.hashCode());
158        return result;
159    }
160
161    @Override
162    public boolean equals(Object obj)
163    {
164        if (this == obj)
165        {
166            return true;
167        }
168        if (obj == null)
169        {
170            return false;
171        }
172        if (getClass() != obj.getClass())
173        {
174            return false;
175        }
176        SiteQuery other = (SiteQuery) obj;
177        if (_names == null)
178        {
179            if (other._names != null)
180            {
181                return false;
182            }
183        }
184        else if (!_names.equals(other._names))
185        {
186            return false;
187        }
188        if (_operator != other._operator)
189        {
190            return false;
191        }
192        return true;
193    }
194}