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.model; 017 018import java.util.Collection; 019import java.util.Collections; 020import java.util.Map; 021 022import org.apache.avalon.framework.configuration.Configuration; 023import org.apache.solr.common.SolrInputDocument; 024import org.xml.sax.ContentHandler; 025import org.xml.sax.SAXException; 026 027import org.ametys.cms.contenttype.MetadataType; 028import org.ametys.cms.repository.Content; 029import org.ametys.cms.search.SearchField; 030import org.ametys.cms.search.query.Query; 031import org.ametys.cms.search.query.Query.Operator; 032import org.ametys.cms.search.solr.schema.SchemaDefinition; 033import org.ametys.plugins.repository.metadata.MultilingualString; 034import org.ametys.runtime.i18n.I18nizableText; 035import org.ametys.runtime.parameter.Enumerator; 036 037/** 038 * Represents a universal property of a {@link Content} (content types, language, current workflow step, ...) 039 */ 040public interface SystemProperty 041{ 042 043 /** 044 * Get the system property ID. 045 * @return The property ID. 046 */ 047 String getId(); 048 049 /** 050 * Get the system property label. 051 * @return The property label. 052 */ 053 I18nizableText getLabel(); 054 055 /** 056 * Get the system property description. 057 * @return The property description. 058 */ 059 I18nizableText getDescription(); 060 061 /** 062 * Get the property type. 063 * @return the property type. 064 */ 065 MetadataType getType(); 066 067 /** 068 * Get the multiple status of the property. 069 * @return <code>true</code> if the property can have multiple values, <code>false</code> otherwise. 070 */ 071 boolean isMultiple(); 072 073 /** 074 * Get the definition of an enumerator. 075 * @param configuration The enumerator configuration. 076 * @return The enumerator definition or null if the property is not enumerated. 077 */ 078 default EnumeratorDefinition getEnumeratorDefinition(Configuration configuration) 079 { 080 // Default null, override to set an enumerator. 081 return null; 082 } 083 084 /** 085 * In case of a Content reference field, the content type ID. 086 * @return the content type ID. 087 */ 088 default String getContentTypeId() 089 { 090 return null; 091 } 092 093 /** 094 * Get if the property can be searched on (i.e. used in a SearchCriterion). 095 * @return <code>true</code> if the property can be searched on, <code>false</code> otherwise. 096 */ 097 default boolean isSearchable() 098 { 099 // Default to true: override when the property is not searchable. 100 return true; 101 } 102 103 /** 104 * Get if the property can be displayed (i.e. used in a ResultField). 105 * @return <code>true</code> if the property can be displayed, <code>false</code> otherwise. 106 */ 107 default boolean isDisplayable() 108 { 109 // Default to true: override when the property is not displayable. 110 return true; 111 } 112 113 /** 114 * Get if the property can be sorted on. 115 * @return <code>true</code> if the property can be sorted on, <code>false</code> otherwise. 116 */ 117 default boolean isSortable() 118 { 119 // Default to true: override when the property is not sortable. 120 return true; 121 } 122 123 /** 124 * Gets if the property can be facetable 125 * @return <code>true</code> if the property can be facetable, <code>false</code> otherwise. 126 */ 127 default boolean isFacetable() 128 { 129 SearchField searchField = getSearchField(); 130 return searchField != null ? searchField.getFacetField() != null : false; 131 } 132 133 /** 134 * Get the {@link Query} associated to the given value. 135 * @param value the user-submitted value for this property. 136 * @param operator In advanced search mode, the operator chosen by the user. <code>null</code> to use the criterion-defined operator (simple search mode). 137 * @param language The current search language. 138 * @param contextualParameters the search contextual parameters. 139 * @return The {@link Query} associated to the given value. 140 */ 141 Query getQuery(Object value, Operator operator, String language, Map<String, Object> contextualParameters); 142 143 /** 144 * Get the default widget to use when rendering this property as a criterion. 145 * @return The default widget to use, or <code>null</code> if no specific widget is necessary. 146 */ 147 default String getWidget() 148 { 149 return null; 150 } 151 152 /** 153 * Get the widget parameters. 154 * @param configuration The system property configuration 155 * @return The widget parameters as a Map. 156 */ 157 default Map<String, I18nizableText> getWidgetParameters(Configuration configuration) 158 { 159 return Collections.emptyMap(); 160 } 161 162 /** 163 * Get the renderer. 164 * @return The column renderer. 165 */ 166 default String getRenderer() 167 { 168 return null; 169 } 170 171 /** 172 * Get the property column converter. 173 * @return The property column converter. 174 */ 175 default String getConverter() 176 { 177 return null; 178 } 179 180 /** 181 * Get the column width. 182 * @return the default column width, can be null. 183 */ 184 default Integer getColumnWidth() 185 { 186 return null; 187 } 188 189 /** 190 * Index the system property in a solr document. 191 * @param content The content to index. 192 * @param document The solr document to index into. 193 */ 194 void index(Content content, SolrInputDocument document); 195 196// /** 197// * Get the name of the field to use when indexing this property. 198// * @return The field name. 199// */ 200// String getField(); 201 202 /** 203 * Get the {@link SearchField} representing this system property. 204 * @return The search field representing this system property. 205 */ 206 SearchField getSearchField(); 207 208 /** 209 * Get the typed raw value for this field in the given result content. 210 * The returned object depends on this field's type:<br> 211 * - {@link MetadataType#STRING} must return String or String[] if multiple<br> 212 * - {@link MetadataType#DATE} or {@link MetadataType#DATETIME} must return Date or Date[] if multiple<br> 213 * - {@link MetadataType#LONG} must return Long or Long[] if multiple<br> 214 * - {@link MetadataType#DOUBLE} must return Double or Double[] if multiple<br> 215 * - {@link MetadataType#CONTENT} must return String or String[] if multiple<br> 216 * - {@link MetadataType#GEOCODE} must return Map<String, Double><br> 217 * - {@link MetadataType#USER} must return UserIdentity or UserIdentity[] if multiple<br> 218 * - {@link MetadataType#MULTILINGUAL_STRING} must return {@link MultilingualString}<br> 219 * Others types are not supported. 220 * @param content The result content 221 * @return The typed value, cast to the appropriate object according its type. 222 */ 223 Object getValue(Content content); 224 225 /** 226 * Get the jsonified value 227 * @param content the result content 228 * @param full <code>true</code> to get full value. 229 * @return the content field value 230 */ 231 default Object getJsonValue(Content content, boolean full) 232 { 233 return getValue(content); 234 } 235 236 /** 237 * SAX the value 238 * @param handler The content handler to sax into 239 * @param content The content 240 * @throws SAXException If an error occurred while saxing 241 */ 242 void saxValue(ContentHandler handler, Content content) throws SAXException; 243 244 /** 245 * Get the sort value represented by this field in the given result content. 246 * @param content the result content. 247 * @return the content sort value, must be scalar (String, long, double, Date). 248 */ 249 default Object getSortValue(Content content) 250 { 251 // No sortable by default; 252 return null; 253 } 254 255 /** 256 * Get the schema definitions brought by this property. 257 * @return The schema definitions used by this property. 258 */ 259 Collection<SchemaDefinition> getSchemaDefinitions(); 260 261 /** 262 * Representation of an Enumerator, used to generate an Enumerator on the fly. 263 */ 264 class EnumeratorDefinition 265 { 266 267 private boolean _isStatic; 268 269 private Class<? extends Enumerator> _enumeratorClass; 270 271 private Configuration _configuration; 272 273 private Map<String, I18nizableText> _staticEntries; 274 275 /** 276 * Build a definition representing a dynamic Enumerator. 277 * @param enumeratorClass The enumerator class. 278 * @param configuration The enumerator configuration. 279 */ 280 public EnumeratorDefinition(Class<? extends Enumerator> enumeratorClass, Configuration configuration) 281 { 282 this._enumeratorClass = enumeratorClass; 283 this._configuration = configuration; 284 this._isStatic = false; 285 } 286 287 /** 288 * Build a definition representing a static Enumerator. 289 * @param staticEntries the enumerator entries. 290 */ 291 public EnumeratorDefinition(Map<String, I18nizableText> staticEntries) 292 { 293 this._staticEntries = staticEntries; 294 this._isStatic = true; 295 } 296 297 public boolean isStatic() 298 { 299 return _isStatic; 300 } 301 302 public Class<? extends Enumerator> getEnumeratorClass() 303 { 304 return _enumeratorClass; 305 } 306 307 public Configuration getConfiguration() 308 { 309 return _configuration; 310 } 311 312 public Map<String, I18nizableText> getStaticEntries() 313 { 314 return Collections.unmodifiableMap(_staticEntries); 315 } 316 317 } 318 319}