001package org.javasimon.console;
002
003import java.util.ArrayList;
004import java.util.Collections;
005import java.util.List;
006
007/**
008 * Collection of plugin used by Simon console actions
009 *
010 * @author gquintana
011 */
012public class SimonConsolePluginManager {
013
014        /**
015         * List of plugins
016         */
017        private final List<SimonConsolePlugin> plugins = new ArrayList<>();
018
019        /**
020         * Return plugin list.
021         */
022        public List<SimonConsolePlugin> getPlugins() {
023                return Collections.unmodifiableList(plugins);
024        }
025
026        /**
027         * Return plugin list, filtered by plugin type.
028         */
029        public <T extends SimonConsolePlugin> List<T> getPluginsByType(Class<T> pluginType) {
030                List<T> specPlugins = new ArrayList<>();
031                for (SimonConsolePlugin plugin : plugins) {
032                        if (pluginType.isInstance(plugin)) {
033                                specPlugins.add(pluginType.cast(plugin));
034                        }
035                }
036                return Collections.unmodifiableList(specPlugins);
037        }
038
039        /**
040         * Return plugin, filtered by plugin Id.
041         */
042        public SimonConsolePlugin getPluginById(String id) {
043                for (SimonConsolePlugin plugin : plugins) {
044                        if (plugin.getId().equals(id)) {
045                                return plugin;
046                        }
047                }
048                return null;
049        }
050
051        /**
052         * Register a plugin
053         *
054         * @param plugin Plugin
055         */
056        public void addPlugin(SimonConsolePlugin plugin) {
057                SimonConsolePlugin existingPlugin = getPluginById(plugin.getId());
058                if (existingPlugin != null) {
059                        throw new IllegalArgumentException("Plugin " + plugin.getId() + " already registered");
060                }
061                plugins.add(plugin);
062        }
063
064        /**
065         * Register a plugin
066         *
067         * @param pluginType Plugin type
068         */
069        public <T extends SimonConsolePlugin> void addPlugin(Class<T> pluginType) {
070                try {
071                        SimonConsolePlugin plugin = pluginType.newInstance();
072                        addPlugin(plugin);
073                } catch (InstantiationException | IllegalAccessException instantiationException) {
074                        throw new IllegalArgumentException("Invalid plugin type " + pluginType.getName(), instantiationException);
075                }
076        }
077
078        /**
079         * Register a plugin
080         *
081         * @param pluginTypeName Plugin type
082         */
083        public void addPlugin(String pluginTypeName) {
084                try {
085                        Class<?> pluginType = Class.forName(pluginTypeName);
086                        if (SimonConsolePlugin.class.isAssignableFrom(pluginType)) {
087                                addPlugin((Class<? extends SimonConsolePlugin>) pluginType);
088                        } else {
089                                throw new IllegalArgumentException("Invalid plugin type " + pluginTypeName);
090                        }
091                } catch (ClassNotFoundException classNotFoundException) {
092                        throw new IllegalArgumentException("Invalid plugin type " + pluginTypeName, classNotFoundException);
093                }
094        }
095
096        /**
097         * Register plugins
098         *
099         * @param pluginTypeNames Comma separated list for plugin classes
100         */
101        public void addPlugins(String pluginTypeNames) {
102                String[] pluginTypeNameList = pluginTypeNames.split(",");
103                for (String pluginTypeName : pluginTypeNameList) {
104                        pluginTypeName = pluginTypeName.trim();
105                        if (!pluginTypeName.equals("")) {
106                                addPlugin(pluginTypeName);
107                        }
108                }
109        }
110
111        /**
112         * Return plugin, filtered by plugin Id.
113         */
114        public boolean removePluginById(String id) {
115                SimonConsolePlugin plugin = getPluginById(id);
116                return plugin != null && plugins.remove(plugin);
117        }
118
119        /**
120         * Get all action bindings of all plugins.
121         */
122        public List<ActionBinding> getActionBindings() {
123                List<ActionBinding> actionBindings = new ArrayList<>();
124                for (SimonConsolePlugin plugin : plugins) {
125                        actionBindings.addAll(plugin.getActionBindings());
126                }
127                return Collections.unmodifiableList(actionBindings);
128        }
129}