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;
022
023import org.apache.avalon.framework.configuration.ConfigurationException;
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.avalon.framework.service.Serviceable;
027
028import org.ametys.cms.search.model.SystemProperty;
029import org.ametys.plugins.repository.data.holder.DataHolder;
030import org.ametys.plugins.repository.data.holder.ModelAwareDataHolder;
031import org.ametys.runtime.model.DefinitionContext;
032import org.ametys.runtime.model.Model;
033import org.ametys.runtime.model.ModelHelper;
034import org.ametys.runtime.model.ModelItem;
035import org.ametys.runtime.model.ModelItemAccessor;
036import org.ametys.runtime.model.disableconditions.AbstractStaticRelativeDisableCondition;
037import org.ametys.runtime.model.disableconditions.DisableCondition;
038import org.ametys.runtime.model.exception.BadItemTypeException;
039import org.ametys.runtime.model.exception.UndefinedItemPathException;
040
041/**
042 * {@link DisableCondition} for model aware {@link DataHolder}
043 * This is a static (i.e. coming from configurable component) implementation
044 */
045public class DataHolderStaticRelativeDisableCondition extends AbstractStaticRelativeDisableCondition implements Serviceable
046{
047    /** The data holder relative disable condition helper */
048    protected DataHolderRelativeDisableConditionsHelper _disableConditionsHelper;
049    
050    public void service(ServiceManager manager) throws ServiceException
051    {
052        _disableConditionsHelper = (DataHolderRelativeDisableConditionsHelper) manager.lookup(DataHolderRelativeDisableConditionsHelper.ROLE);
053    }
054    
055    @Override
056    protected List<ModelItem> getAllModelItemsInPath(Model model, ModelItem definition) throws UndefinedItemPathException, IllegalArgumentException
057    {
058        String conditionPath = ModelHelper.getDisableConditionAbsolutePath(this, definition.getPath());
059        SystemProperty systemProperty = _disableConditionsHelper.getSystemProperty(conditionPath);
060        return systemProperty != null
061                ? _disableConditionsHelper.getAllModelItemsInPathToSystemProperty(this, conditionPath, model, definition, systemProperty)
062                : super.getAllModelItemsInPath(model, definition);
063    }
064
065    @Override
066    protected void checkModelItemPathSegment(Model model, ModelItem definition, ModelItem segmentModelItem, int segmentIndex, int conditionPathSize) throws ConfigurationException
067    {
068        super.checkModelItemPathSegment(model, definition, segmentModelItem, segmentIndex, conditionPathSize);
069        _disableConditionsHelper.checkModelItemPathSegment(this, model, definition, segmentModelItem, segmentIndex, conditionPathSize);
070    }
071    
072    @Override
073    protected <T> RelativeDefinitionAndValue _getConditionDefinitionAndValue(ModelItem definition, String dataPath, Optional<String> oldDataPath, Map<String, Object> values, Optional<T> dataHolder, Map<String, Object> contextualParameters)
074    {
075        dataHolder.filter(ModelAwareDataHolder.class::isInstance)
076                  .map(ModelAwareDataHolder.class::cast)
077                  .ifPresent(dH -> contextualParameters.putAll(_disableConditionsHelper.getAdditionalContextualParameters(this, oldDataPath, dH)));
078
079        return super._getConditionDefinitionAndValue(definition, dataPath, oldDataPath, values, dataHolder, contextualParameters);
080    }
081    
082    @Override
083    protected <T> Collection<? extends ModelItemAccessor> getModelItemAccessors(ModelItem definition, Optional<T> object)
084    {
085        return _disableConditionsHelper.getModelItemAccessors(object)
086                                       .orElseGet(() -> super.getModelItemAccessors(definition, object));
087    }
088    
089    @Override
090    protected ModelItem getModelItem(Collection<? extends ModelItemAccessor> modelItemAccessors, String conditionDataPath, Map<String, Object> contextualParameters) throws UndefinedItemPathException
091    {
092        SystemProperty systemProperty = _disableConditionsHelper.getSystemProperty(conditionDataPath);
093        return systemProperty != null
094                ? systemProperty
095                : super.getModelItem(modelItemAccessors, conditionDataPath, contextualParameters);
096    }
097    
098    /**
099     * {@inheritDoc}
100     * @throws BadItemTypeException if a value does not correspond to the model of given object
101     */
102    @Override
103    protected boolean containsRelativeValue(Collection<? extends ModelItemAccessor> modelItemAccessors, String conditionDataPath, Map<String, Object> values, Map<String, Object> contextualParameters) throws BadItemTypeException
104    {
105        return _disableConditionsHelper.containsValue(modelItemAccessors, conditionDataPath, values, contextualParameters);
106    }
107    
108    /**
109     * {@inheritDoc}
110     * @throws BadItemTypeException if a value does not correspond to the model of given object
111     */
112    @Override
113    protected Object getRelativeValueFromMap(Collection<? extends ModelItemAccessor> modelItemAccessors, String conditionDataPath, Map<String, Object> values, Map<String, Object> contextualParameters) throws BadItemTypeException
114    {
115        return _disableConditionsHelper.getValueFromMap(modelItemAccessors, conditionDataPath, values, contextualParameters);
116    }
117
118    @Override
119    protected <T> Object getStoredRelativeValue(String conditionDataPath, Optional<String> oldConditionDataPath, T dataHolder, Map<String, Object> contextualParameters)
120    {
121        String dataPath = oldConditionDataPath.orElse(conditionDataPath);
122        return _disableConditionsHelper.doesEvaluateConditionForNewRepeaterEntry((ModelAwareDataHolder) dataHolder, dataPath)
123            ? null // The condition is external, so the relative item will not be valued
124            : ((ModelAwareDataHolder) dataHolder).getValue(dataPath, true);
125    }
126    
127    public boolean isExternal(DefinitionContext context)
128    {
129        return _disableConditionsHelper.isExternal(this, context);
130    }
131}