001/*
002 *  Copyright 2018 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.plugin;
017
018import java.util.ArrayList;
019import java.util.Collection;
020import java.util.HashMap;
021import java.util.Iterator;
022import java.util.Map;
023import java.util.Set;
024
025import org.ametys.runtime.plugin.PluginsManager.InactivityCause;
026import org.ametys.runtime.plugin.PluginsManager.InactivityStatus;
027
028/**
029 * Default {@link FeatureActivator} which activates all non-passive and non-excluded features.
030 */
031public final class ExcludePolicyFeatureActivator extends AbstractFeatureActivator
032{
033    private Collection<String> _excludedPlugins;
034    private Collection<String> _excludedFeatures;
035    /**
036     * Constructs a new feature activator with an 'exclude' policy
037     * @param allPlugins all plugins
038     * @param excludedPlugins The plugins to exclude
039     * @param excludedFeatures The features to exclude
040     */
041    public ExcludePolicyFeatureActivator(Map<String, Plugin> allPlugins, Collection<String> excludedPlugins, Collection<String> excludedFeatures)
042    {
043        super(allPlugins);
044        _excludedPlugins = excludedPlugins;
045        _excludedFeatures = excludedFeatures;
046    }
047
048    @Override
049    public PluginsInformation computeActiveFeatures(Map<String, String> componentsConfig, boolean safeMode)
050    {
051        _safeMode = safeMode;
052        
053        Map<String, Feature> initialFeatures = new HashMap<>();
054        Map<String, ExtensionPointDefinition> extensionPoints = new HashMap<>();
055        Map<String, InactivityStatus> inactiveFeatures = new HashMap<>();
056        
057        Collection<PluginIssue> errors = new ArrayList<>();
058
059        // Get actual plugin list, corresponding extension points and initial feature list
060        Map<String, Plugin> plugins = computeActivePlugins(_excludedPlugins, initialFeatures, inactiveFeatures, extensionPoints, errors);
061
062        // Compute incoming deactivations
063        Map<String, Collection<IncomingDeactivation>> incomingDeactivations = computeIncomingDeactivations(initialFeatures);
064        _correctedDependencies = new CorrectedDependencies(initialFeatures, incomingDeactivations, _logger);
065        
066        // First remove user-excluded features
067        _removeUserExcludedFeatures(initialFeatures, inactiveFeatures);
068        
069        // Then remove deactivated features
070        // Also remove feature containing inactive components
071        removeInactiveFeatures(initialFeatures, inactiveFeatures, incomingDeactivations, componentsConfig);
072        
073        removeWrongPointReferences(initialFeatures, inactiveFeatures, extensionPoints, errors);
074        
075        // Process outgoing dependencies
076        Map<String, Feature> features = processOutgoingDependencies(initialFeatures, inactiveFeatures, errors);
077
078        // Compute incoming dependencies
079        Map<String, Collection<String>> incomingDependencies = computeIncomingDependencies(features);
080        
081        // Finally remove unused passive features
082        removeUnusedPassiveFeatures(features, inactiveFeatures, incomingDependencies);
083        
084        // Check uniqueness of extensions and components
085        Map<String, Map<String, ExtensionDefinition>> extensions = computeExtensions(features, errors);
086        Map<String, ComponentDefinition> components = computeComponents(features, componentsConfig, errors);
087        
088        return new PluginsInformation(plugins, features, inactiveFeatures, extensionPoints, extensions, components, errors);
089    }
090    
091    private void _removeUserExcludedFeatures(Map<String, Feature> initialFeatures, Map<String, InactivityStatus> inactiveFeatures)
092    {
093        Set<String> ids = initialFeatures.keySet();
094        Iterator<String> it = ids.iterator();
095        while (it.hasNext())
096        {
097            String id = it.next();
098            
099            if (_excludedFeatures.contains(id))
100            {
101                _logger.debug("Remove excluded feature '{}'", id);
102                it.remove();
103                inactiveFeatures.put(id, new InactivityStatus(InactivityCause.EXCLUDED, null));
104            }
105        }
106    }
107    
108    @Override
109    public String shortDump(PluginsInformation pluginInfo)
110    {
111        // Do nothing in INFO log level
112        return "";
113    }
114}