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.ArrayList;
019import java.util.Arrays;
020import java.util.Collection;
021import java.util.Collections;
022import java.util.List;
023
024import org.apache.commons.lang3.StringUtils;
025
026/**
027 * Represents a search {@link Query} corresponding to the logical "and" between several other queries.
028 */
029public class AndQuery implements Query
030{
031    
032    /** The list of queries. */
033    protected List<Query> _queries;
034    /** If a query is empty should just ignore it, or return an empty AndQuery */
035    protected boolean _ignoreEmptyQueries;
036    
037    /**
038     * Build an AndQuery object.
039     * @param queries the queries.
040     */
041    public AndQuery(Query... queries)
042    {
043        this(true, queries);
044    }
045    
046    /**
047     * Build an AndQuery object.
048     * @param ignoreEmptyQueries If a query is empty should just ignore it, or return an empty AndQuery
049     * @param queries the queries.
050     */
051    public AndQuery(boolean ignoreEmptyQueries, Query... queries)
052    {
053        _queries = Arrays.asList(queries);
054        _ignoreEmptyQueries = ignoreEmptyQueries;
055    }
056    
057    /**
058     * Build an AndQuery object.
059     * @param queries the queries as a Collection.
060     */
061    public AndQuery(Collection<Query> queries)
062    {
063        this(true, queries);
064    }
065    
066    /**
067     * Build an AndQuery object.
068     * @param ignoreEmptyQueries If a query is empty should just ignore it, or return an empty AndQuery
069     * @param queries the queries as a Collection.
070     */
071    public AndQuery(boolean ignoreEmptyQueries, Collection<Query> queries)
072    {
073        _queries = new ArrayList<>(queries);
074        _ignoreEmptyQueries = ignoreEmptyQueries;
075    }
076    
077    /**
078     * Get the list of queries in this "and".
079     * @return the list of queries.
080     */
081    public List<Query> getQueries()
082    {
083        return Collections.unmodifiableList(_queries);
084    }
085    
086    @Override
087    public String build() throws QuerySyntaxException
088    {
089        boolean isFirst = true;
090        StringBuilder sb = new StringBuilder("(");
091        
092        for (Query subQuery : _queries)
093        {
094            if (subQuery != null)
095            {
096                String exprAsString = subQuery.build();
097                if (StringUtils.isNotBlank(exprAsString))
098                {
099                    if (!isFirst)
100                    {
101                        sb.append(" AND ");
102                    }
103                    sb.append(exprAsString);
104                    isFirst = false;
105                }    
106                else if (!_ignoreEmptyQueries)
107                {
108                    return "";
109                }
110            }
111        }
112        
113        if (isFirst)
114        {
115            return "";
116        }
117        else
118        {
119            return sb.append(")").toString();
120        }
121    }
122    
123}