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