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.runtime.model.disableconditions;
017
018import java.util.ArrayList;
019import java.util.Collection;
020import java.util.List;
021
022import org.ametys.runtime.model.DefinitionContext;
023import org.ametys.runtime.model.Model;
024import org.ametys.runtime.model.ModelItem;
025
026/**
027 * List of disable conditions
028 * Composed by a list of sub conditions or conditions and a association operator
029 * @param <T> The type of disable condition
030 */
031public interface DisableConditions<T extends DisableCondition>
032{
033    /** Association between sub conditions*/
034    public enum ASSOCIATION_TYPE
035    {
036        /** And */
037        AND,
038        /** Or */
039        OR
040    }
041    
042    /**
043     * Get the conditions
044     * @return The list of conditions
045     */
046    public List<T> getConditions();
047    
048    /**
049     * Get the sub conditions
050     * @return The list of underlying conditions
051     */
052    public List<DisableConditions<T>> getSubConditions();
053    
054    /**
055     * Get the association
056     * @return The association
057     */
058    public ASSOCIATION_TYPE getAssociationType();
059    
060    /**
061     * Set the association
062     * @param associationType The new association between underlying conditions
063     */
064    public void setAssociation(ASSOCIATION_TYPE associationType);
065    
066    /**
067     * Used to do more initialization, checks... needing model items of distant objects
068     * Called by {@link Model} parsing when the model items of all models have been initialized.
069     * @param model the model containing the definition
070     * @param definition the model item defining this disable condition
071     * @throws Exception if an error occurs or if an additional check fails.
072     */
073    public default void init(Model model, ModelItem definition) throws Exception
074    {
075        for (DisableCondition condition : getConditions())
076        {
077            condition.init(model, definition);
078        }
079        
080        for (DisableConditions<T> subConditions : getSubConditions())
081        {
082            subConditions.init(model, definition);
083        }
084    }
085    
086    /**
087     * Retrieves the external conditions of the current {@link DisableConditions}
088     * Each condition has an index to avoid confusion if there is several conditions with the same id
089     * @param context the definition context
090     * @return the external conditions of the current {@link DisableConditions}
091     */
092    public default Collection<T> getExternalDisableConditions(DefinitionContext context)
093    {
094        Collection<T> externalConditions = new ArrayList<>();
095                
096        getConditions().stream()
097                       .filter(condition -> condition.isExternal(context))
098                       .forEach(externalConditions::add);
099        
100        getSubConditions().stream()
101                          .map(subDisableConditions -> subDisableConditions.getExternalDisableConditions(context))
102                          .forEach(externalConditions::addAll);
103        
104        return externalConditions;
105    }
106}