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; 022 023import org.apache.avalon.framework.configuration.Configuration; 024import org.apache.avalon.framework.configuration.ConfigurationException; 025import org.apache.avalon.framework.service.ServiceException; 026import org.apache.avalon.framework.service.ServiceManager; 027import org.apache.solr.common.SolrInputDocument; 028 029import org.ametys.cms.content.indexing.solr.SolrFieldNames; 030import org.ametys.cms.data.type.indexing.IndexableElementType; 031import org.ametys.cms.model.CMSDataContext; 032import org.ametys.cms.repository.Content; 033import org.ametys.cms.repository.comment.Comment; 034import org.ametys.cms.repository.comment.CommentableContent; 035import org.ametys.cms.search.model.CriterionDefinitionAwareElementDefinition; 036import org.ametys.cms.search.model.CriterionDefinitionHelper; 037import org.ametys.cms.search.model.SystemProperty; 038import org.ametys.cms.search.query.CommentQuery; 039import org.ametys.cms.search.query.CommentQuery.CommentInclusion; 040import org.ametys.cms.search.query.Query; 041import org.ametys.cms.search.query.Query.Operator; 042import org.ametys.cms.search.solr.schema.FieldDefinition; 043import org.ametys.cms.search.solr.schema.SchemaDefinition; 044import org.ametys.runtime.i18n.I18nizableText; 045import org.ametys.runtime.model.Enumerator; 046import org.ametys.runtime.model.StaticEnumerator; 047import org.ametys.runtime.model.type.DataContext; 048import org.ametys.runtime.model.type.ModelItemTypeConstants; 049import org.ametys.runtime.plugin.component.ThreadSafeComponentManager; 050 051/** 052 * {@link SystemProperty} which represents the comments of a content. 053 */ 054public class CommentsSystemProperty extends AbstractSystemProperty<Boolean, Content> implements CriterionDefinitionAwareElementDefinition<Boolean>, IndexationAwareSystemProperty<Boolean, Content> 055{ 056 /** System property identifier */ 057 public static final String SYSTEM_PROPERTY_ID = "comments"; 058 059 /** Solr field name. */ 060 public static final String SOLR_FIELD_NAME = SYSTEM_PROPERTY_ID; 061 062 /** The criterion definition helper */ 063 protected CriterionDefinitionHelper _criterionDefinitionHelper; 064 065 @Override 066 public void service(ServiceManager manager) throws ServiceException 067 { 068 super.service(manager); 069 _criterionDefinitionHelper = (CriterionDefinitionHelper) manager.lookup(CriterionDefinitionHelper.ROLE); 070 } 071 072 @Override 073 public Query getQuery(Object value, Operator operator, String language, Map<String, Object> contextualParameters) 074 { 075 if ("with-comments".equals(value)) 076 { 077 return new CommentQuery(CommentInclusion.VALIDATED_AND_NON_VALIDATED, operator); 078 } 079 else if ("with-validated-comments".equals(value)) 080 { 081 return new CommentQuery(CommentInclusion.VALIDATED, operator); 082 } 083 else // if ("with-nonvalidated-comments".equals(value)) 084 { 085 return new CommentQuery(CommentInclusion.NON_VALIDATED, operator); 086 } 087 } 088 089 @Override 090 public IndexableElementType getDefaultCriterionType() 091 { 092 return _criterionDefinitionHelper.getCriterionDefinitionType(ModelItemTypeConstants.STRING_TYPE_ID); 093 } 094 095 @Override 096 public String getRenderer() 097 { 098 return "Ametys.grid.GridColumnHelper.renderBooleanIcon"; 099 } 100 101 @Override 102 public Integer getColumnWidth() 103 { 104 return 40; 105 } 106 107 public String getSolrFieldName() 108 { 109 return SOLR_FIELD_NAME; 110 } 111 112 public String getSolrSortFieldName() 113 { 114 return SOLR_FIELD_NAME; 115 } 116 117 public String getSolrFacetFieldName() 118 { 119 // FIXME use the default implementation; 120 // This leads to Solr error during indexation : is field 'comments_dv' is already declared by someone else ? 121 return null; 122 } 123 124 @Override 125 public Collection<SchemaDefinition> getSchemaDefinitions() 126 { 127 Collection<SchemaDefinition> definitions = IndexationAwareSystemProperty.super.getSchemaDefinitions(); 128 129 definitions.add(new FieldDefinition(SolrFieldNames.CONTENT_COMMENTS_VALIDATED, "boolean", false, false)); 130 definitions.add(new FieldDefinition(SolrFieldNames.CONTENT_COMMENTS_NONVALIDATED, "boolean", false, false)); 131 132 return definitions; 133 } 134 135 @Override 136 public void indexValue(SolrInputDocument document, Content content, CMSDataContext context) 137 { 138 IndexationAwareSystemProperty.super.indexValue(document, content, context); 139 140 boolean hasComment = (boolean) getValue(content); 141 if (hasComment) 142 { 143 List<Comment> comments = ((CommentableContent) content).getComments(true, true); 144 document.addField(SolrFieldNames.CONTENT_COMMENTS_VALIDATED, comments.stream().anyMatch(c -> c.isValidated())); 145 document.addField(SolrFieldNames.CONTENT_COMMENTS_NONVALIDATED, comments.stream().anyMatch(c -> !c.isValidated())); 146 } 147 } 148 149 @Override 150 public Object getValue(Content content) 151 { 152 if (content instanceof CommentableContent commentableContent) 153 { 154 List<Comment> comments = commentableContent.getComments(true, true); 155 return Boolean.valueOf(!comments.isEmpty()); 156 } 157 158 return Boolean.valueOf(false); 159 } 160 161 @Override 162 public Object valueToJSON(Content content, DataContext context) 163 { 164 // FIXME pourquoi ne pas retourner getRawValue directement ? 165 Map<String, Object> infos = new LinkedHashMap<>(); 166 infos.put("comments", getValue(content)); 167 return infos; 168 } 169 170 @Override 171 public Enumerator<String> getDefaultCriterionEnumerator(Configuration configuration, ThreadSafeComponentManager<Enumerator> enumeratorManager) throws ConfigurationException 172 { 173 StaticEnumerator<String> enumerator = new StaticEnumerator<>(); 174 enumerator.add(new I18nizableText("plugin.cms", "PLUGINS_CMS_CONTENT_COMMENTS_SEARCH_ALL"), "with-comments"); 175 enumerator.add(new I18nizableText("plugin.cms", "PLUGINS_CMS_CONTENT_COMMENTS_SEARCH_VALIDATED"), "with-validated-comments"); 176 enumerator.add(new I18nizableText("plugin.cms", "PLUGINS_CMS_CONTENT_COMMENTS_SEARCH_NOTVALIDATED"), "with-nonvalidated-comments"); 177 return enumerator; 178 } 179 180 @Override 181 protected String getTypeId() 182 { 183 return ModelItemTypeConstants.BOOLEAN_TYPE_ID; 184 } 185}