001/* 002 * Copyright 2024 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.Locale; 019import java.util.Map; 020 021import org.apache.avalon.framework.configuration.Configuration; 022import org.apache.avalon.framework.configuration.ConfigurationException; 023import org.apache.commons.lang3.BooleanUtils; 024 025import org.ametys.cms.data.ametysobject.ModelAwareDataAwareAmetysObject; 026import org.ametys.cms.data.type.indexing.IndexableElementType; 027import org.ametys.cms.model.CMSDataContext; 028import org.ametys.cms.search.QueryBuilder; 029import org.ametys.cms.search.query.Query; 030import org.ametys.cms.search.query.Query.Operator; 031import org.ametys.runtime.i18n.I18nizableText; 032import org.ametys.runtime.model.ElementDefinition; 033import org.ametys.runtime.model.Enumerator; 034import org.ametys.runtime.model.exception.BadItemTypeException; 035import org.ametys.runtime.plugin.component.ThreadSafeComponentManager; 036 037/** 038 * Interface for {@link ElementDefinition} supporting referencing criteria 039 * @param <T> Type of the element value 040 * @param <C> Type of criterion 041 * @param <X> type of ametys object supported by this definition 042 */ 043public interface CriterionDefinitionAwareElementDefinition<T, C, X extends ModelAwareDataAwareAmetysObject> extends IndexationAwareElementDefinition<T, X> 044{ 045 /** 046 * Get the enumerator to use when rendering this item as a criterion, if no other enumerator is specified on criterion 047 * @param configuration The enumerator configuration. 048 * @param enumeratorManager ComponentManager for the criterion's {@link Enumerator} 049 * @return The enumerator or <code>null</code> if there is no default enumerator for the criterion 050 * @throws ConfigurationException If an error occurs while initializing the enumerator 051 */ 052 @SuppressWarnings("unchecked") 053 public default Enumerator<C> getDefaultCriterionEnumerator(Configuration configuration, ThreadSafeComponentManager<Enumerator> enumeratorManager) throws ConfigurationException 054 { 055 return (Enumerator<C>) getEnumerator(); 056 } 057 058 /** 059 * Get the type to use when rendering the element as a criterion 060 * @return the type to use for a criterion 061 */ 062 public IndexableElementType getCriterionType(); 063 064 /** 065 * Converts the given value to have the right typed value to give to the {@link #getQuery(Object, Operator, String, Map)} method 066 * @param value the value to convert 067 * @param language The current search language. 068 * @param contextualParameters the search contextual parameters. 069 * @return the value, converted to a well typed value 070 * @throws BadItemTypeException if the given value can not be converted 071 */ 072 public default Object convertQueryValue(Object value, String language, Map<String, Object> contextualParameters) throws BadItemTypeException 073 { 074 CMSDataContext context = CMSDataContext.newInstance() 075 .withMultilingualSearch(contextualParameters.containsKey(QueryBuilder.MULTILINGUAL_SEARCH)) 076 .withSearchedValueEscaped(BooleanUtils.isTrue((Boolean) contextualParameters.get(QueryBuilder.VALUE_IS_ESCAPED))) 077 .withLocale(Locale.forLanguageTag(language)) 078 .withModelItem(this); 079 080 IndexableElementType type = getCriterionType(); 081 return type.convertQueryValue(value, context); 082 } 083 084 /** 085 * Get the {@link Query} associated to the given value. 086 * @param value the user-submitted value for this item. 087 * @param operator In advanced search mode, the operator chosen by the user. <code>null</code> to use the criterion-defined operator (simple search mode). 088 * @param language The current search language. 089 * @param contextualParameters the search contextual parameters. 090 * @return The {@link Query} associated to the given value. 091 */ 092 public default Query getQuery(Object value, Operator operator, String language, Map<String, Object> contextualParameters) 093 { 094 CMSDataContext context = CMSDataContext.newInstance() 095 .withMultilingualSearch(contextualParameters.containsKey(QueryBuilder.MULTILINGUAL_SEARCH)) 096 .withSearchedValueEscaped(BooleanUtils.isTrue((Boolean) contextualParameters.get(QueryBuilder.VALUE_IS_ESCAPED))) 097 .withLocale(Locale.forLanguageTag(language)) 098 .withModelItem(this); 099 100 IndexableElementType type = getCriterionType(); 101 return type.getDefaultQuery(value, getName(), operator, false, context); 102 } 103 104 /** 105 * Get the widget to use when rendering this item as a criterion, if no other widget is specified on criterion 106 * @return The widget to use, or <code>null</code> if no specific widget is necessary by default. 107 */ 108 public default String getDefaultCriterionWidget() 109 { 110 CMSDataContext context = CMSDataContext.newInstance() 111 .withModelItem(this); 112 113 IndexableElementType type = getCriterionType(); 114 return type.getDefaultCriterionWidget(context); 115 } 116 117 /** 118 * Get the widget parameters to use when rendering this item as a criterion 119 * If some other parameters are specified on criterion, all parameters are used 120 * If a parameter with the same name is specified on criterion, this parameter is used, not the default one 121 * @param configuration The widget parameters configuration 122 * @return The default widget parameters to use, or an empty Map if no specific widget parameters are necessary by default. 123 */ 124 public default Map<String, I18nizableText> getDefaultCriterionWidgetParameters(Configuration configuration) 125 { 126 CMSDataContext context = CMSDataContext.newInstance() 127 .withModelItem(this); 128 129 IndexableElementType type = getCriterionType(); 130 return type.getDefaultCriterionWidgetParameters(context); 131 } 132 133 /** 134 * Get the operator to use when rendering this item as a criterion, if no other operator is specified on criterion 135 * @return The default operator to use 136 */ 137 public default Operator getDefaultCriterionOperator() 138 { 139 CMSDataContext context = CMSDataContext.newInstance() 140 .withModelItem(this); 141 142 IndexableElementType type = getCriterionType(); 143 return type.getDefaultCriterionOperator(context); 144 } 145}