/** * */ package vnet.sms.common.shell.clamshellspring.internal; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.clamshellcli.api.Command; import org.clamshellcli.api.Context; import org.clamshellcli.api.IOConsole; import org.clamshellcli.api.Plugin; import org.clamshellcli.api.Prompt; import org.clamshellcli.api.Shell; import org.clamshellcli.api.SplashScreen; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * @author obergner * */ public class SpringPluginRegistry implements PluginRegistry, BeanPostProcessor { private final Logger log = LoggerFactory.getLogger(getClass()); private final List<Plugin> plugins = new ArrayList<Plugin>(); @Override public List<Plugin> getPlugins() { return Collections.unmodifiableList(this.plugins); } @Override public <T> List<T> getPluginsByType(final Class<T> type) { final List<T> result = new ArrayList<T>(); for (final Plugin p : getPlugins()) { if (type.isAssignableFrom(p.getClass())) { result.add((T) p); } } return Collections.unmodifiableList(result); } @Override public Shell getShell() { final List<Shell> shells = getPluginsByType(Shell.class); if (shells.isEmpty()) { throw new IllegalStateException("No 'Shell' has been registered"); } if (shells.size() > 1) { throw new IllegalStateException( "More than one 'Shell' has been registered"); } return shells.get(0); } @Override public IOConsole getIOConsole() { final List<IOConsole> consoles = getPluginsByType(IOConsole.class); if (consoles.isEmpty()) { throw new IllegalStateException( "No 'IOConsole' has been registered"); } if (consoles.size() > 1) { throw new IllegalStateException( "More than one 'IOConsole' has been registered"); } return consoles.get(0); } @Override public Prompt getPrompt() { final List<Prompt> prompts = getPluginsByType(Prompt.class); if (prompts.isEmpty()) { final Prompt usernamePrompt = new UsernamePrompt(); this.plugins.add(usernamePrompt); return getPrompt(); } if (prompts.size() > 1) { throw new IllegalStateException( "More than one 'Prompt' has been registered"); } return prompts.get(0); } private static class UsernamePrompt implements Prompt { private final String value = System.getProperty("user.name") + " > "; @Override public String getValue(final Context ctx) { return this.value; } @Override public void plug(final Context plug) { } } @Override public SplashScreen getSplashScreen() { final List<SplashScreen> splashScreens = getPluginsByType(SplashScreen.class); final SplashScreen result; if (splashScreens.isEmpty()) { result = null; } else if (splashScreens.size() == 1) { result = splashScreens.get(0); } else { throw new IllegalStateException( "More than one 'SplashScreen' has been registered"); } return result; } /** * @see vnet.sms.common.beans.factory.config.BeanPostProcessor# * postProcessBeforeInitialization(java.lang.Object, java.lang.String) */ @Override public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException { return bean; } /** * @see vnet.sms.common.beans.factory.config.BeanPostProcessor# * postProcessAfterInitialization(java.lang.Object, java.lang.String) */ @Override public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException { this.log.debug( "Testing if bean [name = {}|bean = {}] implements {} and is not a {} ...", new Object[] { bean, beanName, Plugin.class.getName(), Command.class.getName() }); if (Plugin.class.isInstance(bean) && !Command.class.isInstance(bean)) { this.plugins.add(Plugin.class.cast(bean)); this.log.info( "Bean [name = {}|bean = {}] implements {} and is not a {} - it has been added to the list of known plugins", new Object[] { bean, beanName, Plugin.class.getName(), Command.class.getName() }); } else { this.log.debug( "Bean [name = {}|bean = {}] does NOT implement {} OR is a {} - it will be ignored", new Object[] { bean, beanName, Plugin.class.getName(), Command.class.getName() }); } return bean; } }