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