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.Objects;
019
020import org.ametys.cms.content.indexing.solr.SolrFieldNames;
021import org.ametys.cms.search.solr.field.CommentsSearchField;
022
023/**
024 * Represents a {@link Query} testing if contents have comments.
025 */
026public class CommentQuery implements Query
027{
028    private CommentInclusion _commentInclusion;
029    private Operator _operator;
030    
031    /**
032     * The type (validated, non validated or both) of comments to include for {@link CommentQuery}
033     */
034    public static enum CommentInclusion
035    {
036        /** Request only contents with both validated and non-validated comments */
037        VALIDATED_AND_NON_VALIDATED,
038        /** Request only contents with validated comments */
039        VALIDATED,
040        /** Request only contents with non validated-comments */
041        NON_VALIDATED,
042    }
043    
044    /**
045     * Constructor
046     * @param commentInclusion The type of comments to include in search
047     * (request only contents with {@link CommentInclusion#VALIDATED validated} comments, 
048     * or only contents with {@link CommentInclusion#NON_VALIDATED non validated} comments, 
049     * or {@link CommentInclusion#VALIDATED_AND_NON_VALIDATED both})
050     * @param operator The operator. Only {@link Query.Operator#EQ} and {@link Query.Operator#NE} are allowed.
051     */
052    public CommentQuery(CommentInclusion commentInclusion, Operator operator)
053    {
054        if (Operator.EQ != operator && Operator.NE != operator && Operator.EXISTS != operator)
055        {
056            throw new IllegalArgumentException("Test operator '" + operator + "' is unknown for comment query");
057        }
058        
059        _commentInclusion = commentInclusion;
060        _operator = operator;
061    }
062    
063    @Override
064    public String build() throws QuerySyntaxException
065    {
066        StringBuilder query = new StringBuilder();
067
068        if (_operator == Operator.EXISTS)
069        {   
070            query.append(CommentsSearchField.NAME).append(":true");
071            return query.toString();
072        }
073        
074        boolean appendNegation = _operator == Operator.NE; 
075        if (appendNegation)
076        {
077            NotQuery.appendNegation(query).append('(');
078        }
079        
080        switch (_commentInclusion)  
081        {
082            case VALIDATED_AND_NON_VALIDATED:
083                query.append(CommentsSearchField.NAME).append(":true");
084                break;
085            case VALIDATED:
086                query.append(SolrFieldNames.CONTENT_COMMENTS_VALIDATED).append(":true");
087                break;
088            case NON_VALIDATED:
089                query.append(SolrFieldNames.CONTENT_COMMENTS_NONVALIDATED).append(":true");
090                break;
091            default:
092                throw new IllegalArgumentException("CommentInclusion '" + _commentInclusion + "' is not supported.");
093        }
094        
095        if (appendNegation)
096        {
097            query.append(')');
098        }
099        
100        return query.toString();
101    }
102
103    @Override
104    public int hashCode()
105    {
106        return Objects.hash(_commentInclusion, _operator);
107    }
108
109    @Override
110    public boolean equals(Object obj)
111    {
112        if (this == obj)
113        {
114            return true;
115        }
116        
117        if (obj == null || getClass() != obj.getClass())
118        {
119            return false;
120        }
121        
122        CommentQuery other = (CommentQuery) obj;
123        return _commentInclusion == other._commentInclusion && _operator == other._operator;
124    }
125}