Java tutorial
/****************************************************************************** * WebJavin - Java Web Framework. * * * * Copyright (c) 2011 - Sergey "Frosman" Lukjanov, me@frostman.ru * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ package ru.frostman.web.plugin; import com.google.common.base.Objects; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import javassist.CtClass; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.frostman.web.aop.MethodInterceptor; import ru.frostman.web.classloading.AppClass; import ru.frostman.web.config.JavinConfig; import ru.frostman.web.inject.InjectionRule; import ru.frostman.web.thr.JavinPluginException; import java.util.List; import java.util.Map; import java.util.Set; /** * Javin framework plugins manager. * * @author slukjanov aka Frostman */ public class JavinPlugins extends Plugin { private static final Logger log = LoggerFactory.getLogger(JavinPlugins.class); private static JavinPlugins instance; private final List<String> loadedPlugins; private final List<Plugin> plugins; private List<String> appPackages; private List<MethodInterceptor> methodInterceptors; private List<InjectionRule> customInjections; private JavinPlugins(List<String> loadedPlugins, List<Plugin> plugins) { super(0); // prepend main Javin plugin loadedPlugins.add(0, JavinPlugin.class.getName()); this.loadedPlugins = loadedPlugins; plugins.add(0, new JavinPlugin()); this.plugins = plugins; } /** * Reload all Javin plugins and return aggregated plugin to run some handlers. * * @return true if app classes should be reloaded */ public static boolean update() { if (instance != null && Objects.equal(instance.loadedPlugins, JavinConfig.get().getPlugins())) { return instance.reload(); } else { List<String> pluginClassNames = JavinConfig.get().getPlugins(); Set<Plugin> newPlugins = Sets.newTreeSet(); for (String pluginClassName : pluginClassNames) { Class pluginRawClass; try { pluginRawClass = Class.forName(pluginClassName); } catch (ClassNotFoundException e) { log.warn("Unable to load plugin with main class: " + pluginClassName); continue; } if (Plugin.class.isAssignableFrom(pluginRawClass)) { Plugin plugin; try { plugin = (Plugin) pluginRawClass.newInstance(); } catch (Exception e) { throw new JavinPluginException( "Exception while instantiating plugin with main class: " + pluginClassName, e); } newPlugins.add(plugin); } else { throw new JavinPluginException( "There is class not inherited from Plugin in plugins list: " + pluginClassName); } } instance = new JavinPlugins(Lists.<String>newLinkedList(pluginClassNames), Lists.<Plugin>newLinkedList(newPlugins)); return instance.reload(); } } /** * @return current aggregated plugin to run handlers */ public static Plugin get() { return instance; } @Override public boolean reload() { appPackages = Lists.newLinkedList(); methodInterceptors = Lists.newLinkedList(); customInjections = null; boolean result = false; for (Plugin plugin : plugins) { try { result |= plugin.reload(); appPackages.addAll(plugin.getAppClassesPackages()); methodInterceptors.addAll(plugin.getMethodInterceptors()); } catch (Exception e) { throw new JavinPluginException("Exception while executing update() on plugin with main class: " + plugin.getClass().getName(), e); } } return result; } @Override public void beforeClassesEnhance(Map<String, AppClass> classes) { for (Plugin plugin : plugins) { try { plugin.beforeClassesEnhance(classes); } catch (Exception e) { throw new JavinPluginException( "Exception while executing beforeClassesEnhance() on plugin with main class: " + plugin.getClass().getName(), e); } } } @Override public void afterClassesEnhance(Map<String, AppClass> classes) { for (Plugin plugin : plugins) { try { plugin.afterClassesEnhance(classes); } catch (Exception e) { throw new JavinPluginException( "Exception while executing afterClassesEnhance() on plugin with main class: " + plugin.getClass().getName(), e); } } } @Override public void enhanceClass(Map<String, AppClass> classes, CtClass ctClass) { for (Plugin plugin : plugins) { try { plugin.enhanceClass(classes, ctClass); } catch (Exception e) { throw new JavinPluginException( "Exception while executing enhanceClass() on plugin with main class: " + plugin.getClass().getName(), e); } } } @Override public List<String> getAppClassesPackages() { return appPackages; } @Override public List<MethodInterceptor> getMethodInterceptors() { return methodInterceptors; } public List<InjectionRule> getInjections() { if (customInjections == null) { customInjections = Lists.newLinkedList(); for (Plugin plugin : plugins) { try { customInjections.addAll(plugin.getInjections()); } catch (Exception e) { throw new JavinPluginException( "Exception while getting custom injections on plugin with main class: " + plugin.getClass().getName(), e); } } } return customInjections; } }