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