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