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