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.impl; 017 018import java.util.Map; 019import java.util.Optional; 020import java.util.Set; 021 022import org.apache.cocoon.xml.AttributesImpl; 023import org.apache.cocoon.xml.XMLUtils; 024import org.xml.sax.ContentHandler; 025import org.xml.sax.SAXException; 026 027import org.ametys.cms.data.type.indexing.IndexableElementType; 028import org.ametys.cms.model.CMSDataContext; 029import org.ametys.cms.search.model.CriterionDefinitionAwareElementDefinition; 030import org.ametys.cms.search.model.SearchModel; 031import org.ametys.cms.search.model.SearchModelCriterionDefinition; 032import org.ametys.cms.search.query.Query; 033import org.ametys.cms.search.query.Query.LogicalOperator; 034import org.ametys.cms.search.query.Query.Operator; 035import org.ametys.runtime.model.DefinitionContext; 036import org.ametys.runtime.model.ElementDefinition; 037 038/** 039 * Default implementation for {@link SearchModelCriterionDefinition} searching on a model item. 040 * @param <T> Type of the criterion value 041 */ 042public class ReferencingSearchModelCriterionDefinition<T> extends ReferencingCriterionDefinition<T> implements SearchModelCriterionDefinition<T> 043{ 044 /** Prefix for name of referencing criterion definitions */ 045 public static final String CRITERION_DEFINITION_PREFIX = "reference-"; 046 047 /** The criteria operator */ 048 protected Operator _operator; 049 050 /** 051 * Default constructor. 052 */ 053 public ReferencingSearchModelCriterionDefinition() 054 { 055 // Nothing to do 056 } 057 058 /** 059 * Constructor used to create a BO criterion definition on a referenced item 060 * @param reference the item referenced by this criterion 061 * @param referencePath the path of the criterion's reference 062 */ 063 public ReferencingSearchModelCriterionDefinition(ElementDefinition reference, String referencePath) 064 { 065 super(reference, referencePath); 066 } 067 068 @Override 069 public Set<String> getContentTypeIds(Map<String, Object> contextualParameters) 070 { 071 return getModel().getContentTypes(contextualParameters); 072 } 073 074 @Override 075 public String getName() 076 { 077 return CRITERION_DEFINITION_PREFIX + getReferencePath() + "-" + getOperator().getName(); 078 } 079 080 @Override 081 public Query getQuery(Object value, Operator customOperator, Map<String, Object> allValues, String language, Map<String, Object> contextualParameters) 082 { 083 Operator operator = customOperator != null ? customOperator : getOperator(); 084 return super.getQuery(value, operator, allValues, language, contextualParameters); 085 } 086 087 public Operator getOperator() 088 { 089 return Optional.ofNullable(_operator) 090 .orElseGet(this::_getDefaultOperator); 091 } 092 093 /** 094 * Retrieves the default operator for the criterion 095 * @return the default operator for the criterion 096 */ 097 protected Operator _getDefaultOperator() 098 { 099 ElementDefinition reference = getReference(); 100 return reference instanceof CriterionDefinitionAwareElementDefinition criterionDefinitionAwareReference 101 ? criterionDefinitionAwareReference.getDefaultCriterionOperator() 102 : ((IndexableElementType) reference.getType()).getDefaultCriterionOperator(CMSDataContext.newInstance() 103 .withModelItem(reference)); 104 } 105 106 public void setOperator(Operator operator) 107 { 108 _operator = operator; 109 } 110 111 public void setMultipleOperandOperator(LogicalOperator multipleOperand) 112 { 113 _multipleOperandOperator = multipleOperand; 114 } 115 116 @Override 117 protected Map<String, Object> _toJSON(DefinitionContext context) 118 { 119 Map<String, Object> json = super._toJSON(context); 120 json.put("criterionOperator", getOperator().toString().toLowerCase()); 121 json.put("criterionMultipleOperand", getMultipleOperandOperator().name()); 122 json.put("criterionProperty", getReferencePath()); 123 return json; 124 } 125 126 @Override 127 public void toSAX(ContentHandler contentHandler, DefinitionContext context) throws SAXException 128 { 129 super.toSAX(contentHandler, context); 130 131 XMLUtils.createElement(contentHandler, "test-operator", getOperator().toString().toLowerCase()); 132 XMLUtils.createElement(contentHandler, "multiple-operand", getMultipleOperandOperator().name()); 133 134 AttributesImpl referenceAttributes = new AttributesImpl(); 135 referenceAttributes.addCDATAAttribute("ref", getReferencePath()); 136 XMLUtils.createElement(contentHandler, "item", referenceAttributes); 137 } 138 139 @SuppressWarnings("unchecked") 140 public void copyTo(SearchModelCriterionDefinition<T> criterion, Map<String, Object> contextualParameters) 141 { 142 criterion.setModel(getModel()); 143 144 criterion.setName(getName()); 145 criterion.setPluginName(getPluginName()); 146 criterion.setLabel(getLabel()); 147 criterion.setDescription(getDescription()); 148 criterion.setWidget(getWidget()); 149 criterion.setWidgetParameters(getWidgetParameters()); 150 151 criterion.setType(getType()); 152 criterion.setMultiple(isMultiple()); 153 154 criterion.setEnumerator(getEnumerator()); 155 criterion.setCustomEnumerator(getCustomEnumerator()); 156 criterion.setEnumeratorConfiguration(getEnumeratorConfiguration()); 157 158 criterion.setValidator(getValidator()); 159 criterion.setCustomValidator(getCustomValidator()); 160 criterion.setValidatorConfiguration(getValidatorConfiguration()); 161 162 criterion.setParsedDefaultValues(getParsedDefaultValues()); 163 164 criterion.setOperator(getOperator()); 165 criterion.setMultipleOperandOperator(getMultipleOperandOperator()); 166 167 if (criterion instanceof ReferencingSearchModelCriterionDefinition referencingCriterion) 168 { 169 referencingCriterion.setSolrFacetFieldName(getSolrFacetFieldName(contextualParameters)); 170 referencingCriterion.setJoinedPaths(getJoinedPaths(contextualParameters)); 171 172 referencingCriterion.setReference(getReference()); 173 referencingCriterion.setReferencePath(getReferencePath()); 174 175 referencingCriterion.setContentTypeIds(getContentTypeIds(contextualParameters)); 176 } 177 } 178 179 @Override 180 public SearchModel getModel() 181 { 182 return (SearchModel) super.getModel(); 183 } 184}