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 criterion name */ 048 protected String _name; 049 /** The criterion operator */ 050 protected Operator _operator; 051 052 /** 053 * Default constructor. 054 */ 055 public ReferencingSearchModelCriterionDefinition() 056 { 057 // Nothing to do 058 } 059 060 /** 061 * Constructor used to create a BO criterion definition on a referenced item 062 * @param reference the item referenced by this criterion 063 * @param referencePath the path of the criterion's reference 064 */ 065 public ReferencingSearchModelCriterionDefinition(ElementDefinition reference, String referencePath) 066 { 067 super(reference, referencePath); 068 } 069 070 @Override 071 public Set<String> getContentTypeIds(Map<String, Object> contextualParameters) 072 { 073 return getModel().getContentTypes(contextualParameters); 074 } 075 076 @Override 077 public String getName() 078 { 079 return _name != null ? _name : _getDefaultName(); 080 } 081 082 private String _getDefaultName() 083 { 084 return CRITERION_DEFINITION_PREFIX + getReferencePath() + "-" + getOperator().getName(); 085 } 086 087 @Override 088 public void setName(String name) 089 { 090 _name = name; 091 } 092 093 @Override 094 public Query getQuery(Object value, Operator customOperator, Map<String, Object> allValues, String language, Map<String, Object> contextualParameters) 095 { 096 Operator operator = customOperator != null ? customOperator : getOperator(); 097 return super.getQuery(value, operator, allValues, language, contextualParameters); 098 } 099 100 public Operator getOperator() 101 { 102 return Optional.ofNullable(_operator) 103 .orElseGet(this::_getDefaultOperator); 104 } 105 106 /** 107 * Retrieves the default operator for the criterion 108 * @return the default operator for the criterion 109 */ 110 protected Operator _getDefaultOperator() 111 { 112 if (getEnumerator() != null) 113 { 114 return Operator.EQ; 115 } 116 else 117 { 118 ElementDefinition reference = getReference(); 119 return reference instanceof CriterionDefinitionAwareElementDefinition criterionDefinitionAwareReference 120 ? criterionDefinitionAwareReference.getDefaultCriterionOperator() 121 : ((IndexableElementType) reference.getType()).getDefaultCriterionOperator(CMSDataContext.newInstance() 122 .withModelItem(reference)); 123 } 124 } 125 126 public void setOperator(Operator operator) 127 { 128 _operator = operator; 129 } 130 131 public void setMultipleOperandOperator(LogicalOperator multipleOperand) 132 { 133 _multipleOperandOperator = multipleOperand; 134 } 135 136 @Override 137 protected Map<String, Object> _toJSON(DefinitionContext context) 138 { 139 Map<String, Object> json = super._toJSON(context); 140 json.put("criterionOperator", getOperator().toString().toLowerCase()); 141 json.put("criterionMultipleOperand", getMultipleOperandOperator().name()); 142 json.put("criterionProperty", getReferencePath()); 143 return json; 144 } 145 146 @Override 147 public void toSAX(ContentHandler contentHandler, DefinitionContext context) throws SAXException 148 { 149 super.toSAX(contentHandler, context); 150 151 XMLUtils.createElement(contentHandler, "test-operator", getOperator().toString().toLowerCase()); 152 XMLUtils.createElement(contentHandler, "multiple-operand", getMultipleOperandOperator().name()); 153 154 AttributesImpl referenceAttributes = new AttributesImpl(); 155 referenceAttributes.addCDATAAttribute("ref", getReferencePath()); 156 XMLUtils.createElement(contentHandler, "item", referenceAttributes); 157 } 158 159 @SuppressWarnings("unchecked") 160 public void copyTo(SearchModelCriterionDefinition<T> criterion, Map<String, Object> contextualParameters) 161 { 162 criterion.setModel(getModel()); 163 164 criterion.setName(getName()); 165 criterion.setPluginName(getPluginName()); 166 criterion.setLabel(getLabel()); 167 criterion.setDescription(getDescription()); 168 criterion.setWidget(getWidget()); 169 criterion.setWidgetParameters(getWidgetParameters()); 170 171 criterion.setType(getType()); 172 criterion.setMultiple(isMultiple()); 173 174 criterion.setEnumerator(getEnumerator()); 175 criterion.setCustomEnumerator(getCustomEnumerator()); 176 criterion.setEnumeratorConfiguration(getEnumeratorConfiguration()); 177 178 criterion.setValidator(getValidator()); 179 criterion.setCustomValidator(getCustomValidator()); 180 criterion.setValidatorConfiguration(getValidatorConfiguration()); 181 182 criterion.setParsedDefaultValues(getParsedDefaultValues()); 183 184 criterion.setOperator(getOperator()); 185 criterion.setMultipleOperandOperator(getMultipleOperandOperator()); 186 187 if (criterion instanceof ReferencingSearchModelCriterionDefinition referencingCriterion) 188 { 189 referencingCriterion.setSolrFacetFieldName(getSolrFacetFieldName(contextualParameters)); 190 referencingCriterion.setJoinedPaths(getJoinedPaths(contextualParameters)); 191 192 referencingCriterion.setReference(getReference()); 193 referencingCriterion.setReferencePath(getReferencePath()); 194 195 referencingCriterion.setContentTypeIds(getContentTypeIds(contextualParameters)); 196 } 197 } 198 199 @Override 200 public SearchModel getModel() 201 { 202 return (SearchModel) super.getModel(); 203 } 204}