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 if (getEnumerator() != null) 100 { 101 return Operator.EQ; 102 } 103 else 104 { 105 ElementDefinition reference = getReference(); 106 return reference instanceof CriterionDefinitionAwareElementDefinition criterionDefinitionAwareReference 107 ? criterionDefinitionAwareReference.getDefaultCriterionOperator() 108 : ((IndexableElementType) reference.getType()).getDefaultCriterionOperator(CMSDataContext.newInstance() 109 .withModelItem(reference)); 110 } 111 } 112 113 public void setOperator(Operator operator) 114 { 115 _operator = operator; 116 } 117 118 public void setMultipleOperandOperator(LogicalOperator multipleOperand) 119 { 120 _multipleOperandOperator = multipleOperand; 121 } 122 123 @Override 124 protected Map<String, Object> _toJSON(DefinitionContext context) 125 { 126 Map<String, Object> json = super._toJSON(context); 127 json.put("criterionOperator", getOperator().toString().toLowerCase()); 128 json.put("criterionMultipleOperand", getMultipleOperandOperator().name()); 129 json.put("criterionProperty", getReferencePath()); 130 return json; 131 } 132 133 @Override 134 public void toSAX(ContentHandler contentHandler, DefinitionContext context) throws SAXException 135 { 136 super.toSAX(contentHandler, context); 137 138 XMLUtils.createElement(contentHandler, "test-operator", getOperator().toString().toLowerCase()); 139 XMLUtils.createElement(contentHandler, "multiple-operand", getMultipleOperandOperator().name()); 140 141 AttributesImpl referenceAttributes = new AttributesImpl(); 142 referenceAttributes.addCDATAAttribute("ref", getReferencePath()); 143 XMLUtils.createElement(contentHandler, "item", referenceAttributes); 144 } 145 146 @SuppressWarnings("unchecked") 147 public void copyTo(SearchModelCriterionDefinition<T> criterion, Map<String, Object> contextualParameters) 148 { 149 criterion.setModel(getModel()); 150 151 criterion.setName(getName()); 152 criterion.setPluginName(getPluginName()); 153 criterion.setLabel(getLabel()); 154 criterion.setDescription(getDescription()); 155 criterion.setWidget(getWidget()); 156 criterion.setWidgetParameters(getWidgetParameters()); 157 158 criterion.setType(getType()); 159 criterion.setMultiple(isMultiple()); 160 161 criterion.setEnumerator(getEnumerator()); 162 criterion.setCustomEnumerator(getCustomEnumerator()); 163 criterion.setEnumeratorConfiguration(getEnumeratorConfiguration()); 164 165 criterion.setValidator(getValidator()); 166 criterion.setCustomValidator(getCustomValidator()); 167 criterion.setValidatorConfiguration(getValidatorConfiguration()); 168 169 criterion.setParsedDefaultValues(getParsedDefaultValues()); 170 171 criterion.setOperator(getOperator()); 172 criterion.setMultipleOperandOperator(getMultipleOperandOperator()); 173 174 if (criterion instanceof ReferencingSearchModelCriterionDefinition referencingCriterion) 175 { 176 referencingCriterion.setSolrFacetFieldName(getSolrFacetFieldName(contextualParameters)); 177 referencingCriterion.setJoinedPaths(getJoinedPaths(contextualParameters)); 178 179 referencingCriterion.setReference(getReference()); 180 referencingCriterion.setReferencePath(getReferencePath()); 181 182 referencingCriterion.setContentTypeIds(getContentTypeIds(contextualParameters)); 183 } 184 } 185 186 @Override 187 public SearchModel getModel() 188 { 189 return (SearchModel) super.getModel(); 190 } 191}