001/* 002 * Copyright 2025 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.data.holder; 017 018import java.util.Collection; 019import java.util.List; 020import java.util.Map; 021import java.util.Optional; 022import java.util.UUID; 023 024import org.apache.avalon.framework.configuration.ConfigurationException; 025 026import org.ametys.cms.search.model.SystemProperty; 027import org.ametys.plugins.repository.data.holder.DataHolder; 028import org.ametys.plugins.repository.data.holder.ModelAwareDataHolder; 029import org.ametys.runtime.model.DefinitionContext; 030import org.ametys.runtime.model.Model; 031import org.ametys.runtime.model.ModelHelper; 032import org.ametys.runtime.model.ModelItem; 033import org.ametys.runtime.model.ModelItemAccessor; 034import org.ametys.runtime.model.disableconditions.AbstractRelativeDisableCondition; 035import org.ametys.runtime.model.disableconditions.DisableCondition; 036import org.ametys.runtime.model.exception.BadItemTypeException; 037import org.ametys.runtime.model.exception.UndefinedItemPathException; 038 039/** 040 * {@link DisableCondition} for model aware {@link DataHolder} 041 */ 042public class DataHolderRelativeDisableCondition extends AbstractRelativeDisableCondition 043{ 044 /** The data holder relative disable condition helper */ 045 protected DataHolderRelativeDisableConditionsHelper _disableConditionsHelper; 046 047 /** 048 * Creates a data holder disable condition 049 * @param name The condition name 050 * @param operator comparison operator of the condition ('eq'...) 051 * @param value value to compare to 052 * @param disableConditionsHelper the data holder relative disable condition helper 053 */ 054 public DataHolderRelativeDisableCondition(String name, OPERATOR operator, String value, DataHolderRelativeDisableConditionsHelper disableConditionsHelper) 055 { 056 this(name, operator, value, false, disableConditionsHelper); 057 } 058 059 /** 060 * Creates a data holder disable condition 061 * @param name The condition name 062 * @param operator comparison operator of the condition ('eq'...) 063 * @param value value to compare to 064 * @param hideIfDisabled <code>true</code> to hide the item if the condition is verified, <code>false</code> otherwise 065 * @param disableConditionsHelper the data holder relative disable condition helper 066 */ 067 public DataHolderRelativeDisableCondition(String name, OPERATOR operator, String value, boolean hideIfDisabled, DataHolderRelativeDisableConditionsHelper disableConditionsHelper) 068 { 069 _id = UUID.randomUUID().toString(); 070 _name = name; 071 _operator = operator; 072 _value = value; 073 _hideIfDisabled = hideIfDisabled; 074 _disableConditionsHelper = disableConditionsHelper; 075 } 076 077 @Override 078 protected List<ModelItem> getAllModelItemsInPath(Model model, ModelItem definition) throws UndefinedItemPathException, IllegalArgumentException 079 { 080 String conditionPath = ModelHelper.getDisableConditionAbsolutePath(this, definition.getPath()); 081 SystemProperty systemProperty = _disableConditionsHelper.getSystemProperty(conditionPath); 082 return systemProperty != null 083 ? _disableConditionsHelper.getAllModelItemsInPathToSystemProperty(this, conditionPath, model, definition, systemProperty) 084 : super.getAllModelItemsInPath(model, definition); 085 } 086 087 @Override 088 protected void checkModelItemPathSegment(Model model, ModelItem definition, ModelItem segmentModelItem, int segmentIndex, int conditionPathSize) throws ConfigurationException 089 { 090 super.checkModelItemPathSegment(model, definition, segmentModelItem, segmentIndex, conditionPathSize); 091 _disableConditionsHelper.checkModelItemPathSegment(this, model, definition, segmentModelItem, segmentIndex, conditionPathSize); 092 } 093 094 @Override 095 protected <T> RelativeDefinitionAndValue _getConditionDefinitionAndValue(ModelItem definition, String dataPath, Optional<String> oldDataPath, Map<String, Object> values, Optional<T> dataHolder, Map<String, Object> contextualParameters) 096 { 097 dataHolder.filter(ModelAwareDataHolder.class::isInstance) 098 .map(ModelAwareDataHolder.class::cast) 099 .ifPresent(dH -> contextualParameters.putAll(_disableConditionsHelper.getAdditionalContextualParameters(this, oldDataPath, dH))); 100 101 return super._getConditionDefinitionAndValue(definition, dataPath, oldDataPath, values, dataHolder, contextualParameters); 102 } 103 104 @Override 105 protected <T> Collection<? extends ModelItemAccessor> getModelItemAccessors(ModelItem definition, Optional<T> object) 106 { 107 return _disableConditionsHelper.getModelItemAccessors(object) 108 .orElseGet(() -> super.getModelItemAccessors(definition, object)); 109 } 110 111 @Override 112 protected ModelItem getModelItem(Collection<? extends ModelItemAccessor> modelItemAccessors, String conditionDataPath, Map<String, Object> contextualParameters) throws UndefinedItemPathException 113 { 114 SystemProperty systemProperty = _disableConditionsHelper.getSystemProperty(conditionDataPath); 115 return systemProperty != null 116 ? systemProperty 117 : super.getModelItem(modelItemAccessors, conditionDataPath, contextualParameters); 118 } 119 120 /** 121 * {@inheritDoc} 122 * @throws BadItemTypeException if a value does not correspond to the model of given object 123 */ 124 @Override 125 protected boolean containsRelativeValue(Collection<? extends ModelItemAccessor> modelItemAccessors, String conditionDataPath, Map<String, Object> values, Map<String, Object> contextualParameters) throws BadItemTypeException 126 { 127 return _disableConditionsHelper.containsValue(modelItemAccessors, conditionDataPath, values, contextualParameters); 128 } 129 130 /** 131 * {@inheritDoc} 132 * @throws BadItemTypeException if a value does not correspond to the model of given object 133 */ 134 @Override 135 protected Object getRelativeValueFromMap(Collection<? extends ModelItemAccessor> modelItemAccessors, String conditionDataPath, Map<String, Object> values, Map<String, Object> contextualParameters) throws BadItemTypeException 136 { 137 return _disableConditionsHelper.getValueFromMap(modelItemAccessors, conditionDataPath, values, contextualParameters); 138 } 139 140 @Override 141 protected <T> Object getStoredRelativeValue(String conditionDataPath, Optional<String> oldConditionDataPath, T dataHolder, Map<String, Object> contextualParameters) 142 { 143 String dataPath = oldConditionDataPath.orElse(conditionDataPath); 144 return _disableConditionsHelper.doesEvaluateConditionForNewRepeaterEntry((ModelAwareDataHolder) dataHolder, dataPath) 145 ? null // The condition is external, so the relative item will not be valued 146 : ((ModelAwareDataHolder) dataHolder).getValueWithMultiValuedPathSegments(dataPath); 147 } 148 149 public boolean isExternal(DefinitionContext context) 150 { 151 return _disableConditionsHelper.isExternal(this, context); 152 } 153}