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     * Removes all the conditions with the given name
056     * The conditions in the sub conditions are removed too
057     * @param conditionName The name of the conditions to remove
058     */
059    public void removeConditions(String conditionName);
060    
061    /**
062     * Get the association
063     * @return The association
064     */
065    public ASSOCIATION_TYPE getAssociationType();
066    
067    /**
068     * Set the association
069     * @param associationType The new association between underlying conditions
070     */
071    public void setAssociation(ASSOCIATION_TYPE associationType);
072    
073    /**
074     * Used to do more initialization, checks... needing model items of distant objects
075     * Called by {@link Model} parsing when the model items of all models have been initialized.
076     * @param model the model containing the definition
077     * @param definition the model item defining this disable condition
078     * @throws Exception if an error occurs or if an additional check fails.
079     */
080    public default void init(Model model, ModelItem definition) throws Exception
081    {
082        for (DisableCondition condition : getConditions())
083        {
084            condition.init(model, definition);
085        }
086        
087        for (DisableConditions<T> subConditions : getSubConditions())
088        {
089            subConditions.init(model, definition);
090        }
091    }
092    
093    /**
094     * Retrieves the external conditions of the current {@link DisableConditions}
095     * Each condition has an index to avoid confusion if there is several conditions with the same id
096     * @param context the definition context
097     * @return the external conditions of the current {@link DisableConditions}
098     */
099    public default Collection<T> getExternalDisableConditions(DefinitionContext context)
100    {
101        Collection<T> externalConditions = new ArrayList<>();
102                
103        getConditions().stream()
104                       .filter(condition -> condition.isExternal(context))
105                       .forEach(externalConditions::add);
106        
107        getSubConditions().stream()
108                          .map(subDisableConditions -> subDisableConditions.getExternalDisableConditions(context))
109                          .forEach(externalConditions::addAll);
110        
111        return externalConditions;
112    }
113}