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.cms.search.systemprop;
017
018import java.util.Collection;
019import java.util.LinkedHashMap;
020import java.util.List;
021import java.util.Map;
022import java.util.Optional;
023
024import org.apache.avalon.framework.configuration.Configuration;
025import org.apache.avalon.framework.configuration.ConfigurationException;
026import org.apache.solr.common.SolrInputDocument;
027
028import org.ametys.cms.content.indexing.solr.SolrFieldNames;
029import org.ametys.cms.data.type.indexing.IndexableDataContext;
030import org.ametys.cms.repository.Content;
031import org.ametys.cms.repository.comment.Comment;
032import org.ametys.cms.repository.comment.CommentableContent;
033import org.ametys.cms.search.SearchField;
034import org.ametys.cms.search.model.SystemProperty;
035import org.ametys.cms.search.query.CommentQuery;
036import org.ametys.cms.search.query.CommentQuery.CommentInclusion;
037import org.ametys.cms.search.query.Query;
038import org.ametys.cms.search.query.Query.Operator;
039import org.ametys.cms.search.solr.field.CommentsSearchField;
040import org.ametys.cms.search.solr.schema.FieldDefinition;
041import org.ametys.cms.search.solr.schema.SchemaDefinition;
042import org.ametys.runtime.i18n.I18nizableText;
043import org.ametys.runtime.model.Enumerator;
044import org.ametys.runtime.model.StaticEnumerator;
045import org.ametys.runtime.model.ViewItem;
046import org.ametys.runtime.model.type.DataContext;
047import org.ametys.runtime.model.type.ModelItemTypeConstants;
048import org.ametys.runtime.plugin.component.ThreadSafeComponentManager;
049
050/**
051 * {@link SystemProperty} which represents the comments of a content.
052 */
053public class CommentsSystemProperty extends AbstractSystemProperty<Boolean, Content>
054{
055    @Override
056    public boolean isMultiple()
057    {
058        return false;
059    }
060    
061    @Override
062    public boolean isSortable()
063    {
064        return true;
065    }
066    
067    @Override
068    public Query getQuery(Object value, Operator operator, String language, Map<String, Object> contextualParameters)
069    {
070        if ("with-comments".equals(value))
071        {
072            return new CommentQuery(CommentInclusion.VALIDATED_AND_NON_VALIDATED, operator);
073        }
074        else if ("with-validated-comments".equals(value))
075        {
076            return new CommentQuery(CommentInclusion.VALIDATED, operator);
077        }
078        else // if ("with-nonvalidated-comments".equals(value))
079        {
080            return new CommentQuery(CommentInclusion.NON_VALIDATED, operator);
081        }
082    }
083    
084    @Override
085    public String getCriterionWidget()
086    {
087        // Force standard combobox as the default widget, as the property type is boolean.
088        return "edition.combobox";
089    }
090    
091    @Override
092    public String getRenderer()
093    {
094        return "Ametys.plugins.cms.search.SearchGridHelper.renderBooleanIcon";
095    }
096    
097    @Override
098    public Integer getColumnWidth()
099    {
100        return 40;
101    }
102    
103    @Override
104    public SearchField getSearchField()
105    {
106        return new CommentsSearchField();
107    }
108    
109    @Override
110    public Collection<SchemaDefinition> getSchemaDefinitions()
111    {
112        Collection<SchemaDefinition> definitions = super.getSchemaDefinitions();
113        
114        definitions.add(new FieldDefinition(SolrFieldNames.CONTENT_COMMENTS_VALIDATED, "boolean", false, false));
115        definitions.add(new FieldDefinition(SolrFieldNames.CONTENT_COMMENTS_NONVALIDATED, "boolean", false, false));
116        
117        return definitions;
118    }
119    
120    @Override
121    public void indexValue(SolrInputDocument document, Content content, IndexableDataContext context)
122    {
123        super.indexValue(document, content, context);
124        
125        boolean hasComment = (boolean) getValue(content);
126        if (hasComment)
127        {
128            List<Comment> comments = ((CommentableContent) content).getComments(true, true);
129            document.addField(SolrFieldNames.CONTENT_COMMENTS_VALIDATED, comments.stream().anyMatch(c -> c.isValidated()));
130            document.addField(SolrFieldNames.CONTENT_COMMENTS_NONVALIDATED, comments.stream().anyMatch(c -> !c.isValidated()));
131        }
132    }
133    
134    @Override
135    public Object getValue(Content content)
136    {
137        if (content instanceof CommentableContent commentableContent)
138        {
139            List<Comment> comments = commentableContent.getComments(true, true);
140            return Boolean.valueOf(!comments.isEmpty());
141        }
142        
143        return Boolean.valueOf(false);
144    }
145    
146    @Override
147    public Object valueToJSON(Content content, Optional<ViewItem> viewItem, DataContext context)
148    {
149        // FIXME pourquoi ne pas retourner getRawValue directement ?
150        Map<String, Object> infos = new LinkedHashMap<>();
151        infos.put("comments", getValue(content));
152        return infos;
153    }
154    
155    public Enumerator<String> getCriterionEnumerator(Configuration configuration, ThreadSafeComponentManager<Enumerator> enumeratorManager) throws ConfigurationException
156    {
157        StaticEnumerator<String> enumerator = new StaticEnumerator<>();
158        enumerator.add(new I18nizableText("plugin.cms", "PLUGINS_CMS_CONTENT_COMMENTS_SEARCH_ALL"), "with-comments");
159        enumerator.add(new I18nizableText("plugin.cms", "PLUGINS_CMS_CONTENT_COMMENTS_SEARCH_VALIDATED"), "with-validated-comments");
160        enumerator.add(new I18nizableText("plugin.cms", "PLUGINS_CMS_CONTENT_COMMENTS_SEARCH_NOTVALIDATED"), "with-nonvalidated-comments");
161        return enumerator;
162    }
163    
164    @Override
165    protected String _getTypeId()
166    {
167        return ModelItemTypeConstants.BOOLEAN_TYPE_ID;
168    }
169}