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<IncomingDeactivation>> incomingDeactivations = computeIncomingDeactivations(initialFeatures);
063        _correctedDependencies = new CorrectedDependencies(initialFeatures, incomingDeactivations, _logger);
064        
065        // First remove user-excluded features
066        _removeUserExcludedFeatures(initialFeatures, inactiveFeatures);
067        
068        // Then remove deactivated features
069        // Also remove feature containing inactive components
070        removeInactiveFeatures(initialFeatures, inactiveFeatures, incomingDeactivations, componentsConfig);
071        
072        removeWrongPointReferences(initialFeatures, inactiveFeatures, extensionPoints, errors);
073        
074        // Process outgoing dependencies
075        Map<String, Feature> features = processOutgoingDependencies(initialFeatures, inactiveFeatures, errors);
076
077        // Compute incoming dependencies
078        Map<String, Collection<String>> incomingDependencies = computeIncomingDependencies(features);
079        
080        // Finally remove unused passive features
081        removeUnusedPassiveFeatures(features, inactiveFeatures, incomingDependencies);
082        
083        // Check uniqueness of extensions and components
084        Map<String, Map<String, ExtensionDefinition>> extensions = computeExtensions(features, errors);
085        Map<String, ComponentDefinition> components = computeComponents(features, componentsConfig, errors);
086        
087        return new PluginsInformation(plugins, features, inactiveFeatures, extensionPoints, extensions, components, errors);
088    }
089    
090    private void _removeUserExcludedFeatures(Map<String, Feature> initialFeatures, Map<String, InactivityCause> inactiveFeatures)
091    {
092        Set<String> ids = initialFeatures.keySet();
093        Iterator<String> it = ids.iterator();
094        while (it.hasNext())
095        {
096            String id = it.next();
097            
098            if (_excludedFeatures.contains(id))
099            {
100                _logger.debug("Remove excluded feature '{}'", id);
101                it.remove();
102                inactiveFeatures.put(id, InactivityCause.EXCLUDED);
103            }
104        }
105    }
106    
107    @Override
108    public String shortDump(PluginsInformation pluginInfo)
109    {
110        // Do nothing in INFO log level
111        return "";
112    }
113}