zoukankan      html  css  js  c++  java
  • constellio——基于solr的开源搜索引擎系统源码研究(五)

    插件工厂类PluginFactory.java

    /**
     * Constellio, Open Source Enterprise Search
     * Copyright (C) 2010 DocuLibre inc.
     *
     * This copyrighted material is made available to anyone wishing to use, modify,
     * copy, or redistribute it subject to the terms and conditions of the GNU
     * Lesser General Public License, as published by the Free Software Foundation.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
     * for more details.
     *
     * You should have received a copy of the GNU Lesser General Public License
     * along with this distribution; if not, write to:
     * Free Software Foundation, Inc.
     * 51 Franklin Street, Fifth Floor
     * Boston, MA  02110-1301  USA
     */
    package com.doculibre.constellio.plugins;
    
    import java.io.File;
    import java.io.FileFilter;
    import java.net.URI;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    
    import net.xeoh.plugins.base.PluginManager;
    import net.xeoh.plugins.base.impl.PluginManagerFactory;
    import net.xeoh.plugins.base.impl.PluginManagerImpl;
    import net.xeoh.plugins.base.impl.classpath.ClassPathManager;
    import net.xeoh.plugins.base.impl.classpath.ClassPathManagerUtils;
    import net.xeoh.plugins.base.util.PluginManagerUtil;
    
    import org.apache.commons.io.FileUtils;
    
    import com.doculibre.constellio.plugins.api.ConstellioPlugin;
    import com.doculibre.constellio.plugins.defaults.DefaultConstellioPlugin;
    import com.doculibre.constellio.utils.ClasspathUtils;
    import com.doculibre.constellio.utils.ConstellioSpringUtils;
    
    public class PluginFactory {
    
        private static Set<ClassLoader> classLoaders = new HashSet<ClassLoader>();
    
        private static PluginManager pm;
    
        @SuppressWarnings("unchecked")
        private static void initPluginManager() {
            if (pm == null) {
                pm = PluginManagerFactory.createPluginManager();
                File classesDir = ClasspathUtils.getClassesDir();
    
                pm.addPluginsFrom(classesDir.toURI());
    
                File pluginsDir = getPluginsDir();
                File[] pluginDirs = pluginsDir.listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File pathname) {
                        boolean accept;
                        if (pathname.isFile()) {
                            accept = false;
                        } else if (DefaultConstellioPlugin.NAME.equals(pathname)) {
                            accept = true;
                        } else {
                            List<String> availablePluginNames = ConstellioSpringUtils.getAvailablePluginNames();
                            accept = availablePluginNames.contains(pathname.getName());
                        }
                        return accept;
                    }
                });
                for (File pluginDir : pluginDirs) {
                    // Plugin root dir jars
                    Collection<File> pluginJarFiles = FileUtils.listFiles(pluginDir, new String[] { "jar" },
                        false);
                    // Accept only one root dir jar
                    File pluginJarFile = pluginJarFiles.isEmpty() ? null : pluginJarFiles.iterator().next();
                    if (pluginJarFile != null) {
                        URI pluginJarFileURI = pluginJarFile.toURI();
                        pm.addPluginsFrom(pluginJarFileURI);
    
                        PluginManagerImpl pmImpl = (PluginManagerImpl) pm;
                        ClassPathManager classPathManager = pmImpl.getClassPathManager();
                        ClassLoader classLoader = ClassPathManagerUtils.getClassLoader(classPathManager,
                            pluginJarFile);
                        classLoaders.add(classLoader);
    
                        File pluginLibDir = new File(pluginDir, "lib");
                        if (pluginLibDir.exists() && pluginLibDir.isDirectory()) {
                            Collection<File> pluginDependencies = FileUtils.listFiles(pluginLibDir,
                                new String[] { "jar" }, false);
                            ClassPathManagerUtils.addJarDependencies(classPathManager, pluginJarFile,
                                pluginDependencies);
                        }
                    }
                }
            }
        }
    
        public static <P extends ConstellioPlugin> P getPlugin(Class<P> pluginClass) {
            return getPlugin(pluginClass, false);
        }
    
        public static <P extends ConstellioPlugin> P getDefaultPlugin(Class<P> pluginClass) {
            return getPlugin(pluginClass, true);
        }
    
        private static <P extends ConstellioPlugin> P getPlugin(Class<P> pluginClass, boolean onlyDefault) {
            List<P> matches = getPlugins(pluginClass, onlyDefault);
            return !matches.isEmpty() ? matches.get(0) : null;
        }
    
        public static <P extends ConstellioPlugin> List<P> getPlugins(Class<P> pluginClass) {
            return getPlugins(pluginClass, false);
        }
    
        public static <P extends ConstellioPlugin> List<P> getDefaultPlugins(Class<P> pluginClass) {
            return getPlugins(pluginClass, true);
        }
    
        private static <P extends ConstellioPlugin> List<P> getPlugins(Class<P> pluginClass, boolean onlyDefault) {
            List<P> matches = new ArrayList<P>();
            P defaultPlugin = null;
    
            initPluginManager();
            PluginManagerUtil pmu = new PluginManagerUtil(pm);
            for (P impl : pmu.getPlugins(pluginClass)) {
                // ClassLoader classLoader = impl.getClass().getClassLoader();
                // classLoaders.add(classLoader);
                if (DefaultConstellioPlugin.NAME.equals(impl.getName())) {
                    defaultPlugin = impl;
                } else if (!onlyDefault) {
                    matches.add(impl);
                }
            }
            if (matches.isEmpty()) {
                if (defaultPlugin != null) {
                    matches.add(defaultPlugin);
                }
            } else {
                // If many plugins are found, they are sorted in the order they are configured in constellio.xml
                // (the last has priority over the previous)
                Collections.sort(matches, new Comparator<ConstellioPlugin>() {
                    @Override
                    public int compare(ConstellioPlugin o1, ConstellioPlugin o2) {
                        List<String> availablePluginNames = ConstellioSpringUtils.getAvailablePluginNames();
                        Integer indexOfPluginName1 = availablePluginNames.indexOf(o1.getName());
                        Integer indexOfPluginName2 = availablePluginNames.indexOf(o2.getName());
                        return indexOfPluginName1.compareTo(indexOfPluginName2);
                    }
                });
            }
            return matches;
        }
    
        public static File getPluginsDir() {
            File webinfDir = ClasspathUtils.getWebinfDir();
            return new File(webinfDir, "plugins");
        }
    
        @SuppressWarnings("unchecked")
        public static boolean isValidPlugin(String name) {
            boolean validPlugin;
            File pluginsDir = getPluginsDir();
            File pluginDir = new File(pluginsDir, name);
            if (!pluginDir.exists() || pluginDir.isFile()) {
                validPlugin = false;
            } else {
                Collection<File> pluginJarFiles = FileUtils.listFiles(pluginDir, new String[] { "jar" }, false);
                // Accept only one root dir jar
                File pluginJarFile = pluginJarFiles.isEmpty() ? null : pluginJarFiles.iterator().next();
                if (pluginJarFile != null) {
                    validPlugin = true;
                } else {
                    validPlugin = false;
                }
            }
            return validPlugin;
        }
    
        public static Set<ClassLoader> getClassLoaders() {
            initPluginManager();
            return classLoaders;
        }
    
    }

    自定义类加载器PluginAwareClassLoader.java

    /**
     * Constellio, Open Source Enterprise Search
     * Copyright (C) 2010 DocuLibre inc.
     *
     * This copyrighted material is made available to anyone wishing to use, modify,
     * copy, or redistribute it subject to the terms and conditions of the GNU
     * Lesser General Public License, as published by the Free Software Foundation.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
     * for more details.
     *
     * You should have received a copy of the GNU Lesser General Public License
     * along with this distribution; if not, write to:
     * Free Software Foundation, Inc.
     * 51 Franklin Street, Fifth Floor
     * Boston, MA  02110-1301  USA
     */
    package com.doculibre.constellio.plugins;
    
    import java.io.IOException;
    import java.net.URL;
    import java.util.Enumeration;
    import java.util.Set;
    
    public class PluginAwareClassLoader extends ClassLoader {
        
        private ClassLoader defaultClassLoader;
        
        public PluginAwareClassLoader() {
            defaultClassLoader = Thread.currentThread().getContextClassLoader();
            while (defaultClassLoader instanceof PluginAwareClassLoader) {
                PluginAwareClassLoader nested = (PluginAwareClassLoader) defaultClassLoader;
                defaultClassLoader = nested.getDefaultClassLoader();
            }
        }
    
        public ClassLoader getDefaultClassLoader() {
            return defaultClassLoader;
        }
    
        public void setDefaultClassLoader(ClassLoader defaultClassLoader) {
            this.defaultClassLoader = defaultClassLoader;
        }
        
        protected Set<ClassLoader> getExtraClassLoaders() {
            Set<ClassLoader> extraClassLoaders = PluginFactory.getClassLoaders();
            extraClassLoaders.add(PluginAwareClassLoader.class.getClassLoader());
            return extraClassLoaders;
        }
    
        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            Class<?> clazz;
            Throwable throwable;
            try {
                clazz = defaultClassLoader.loadClass(name);
                throwable = null;
            } catch (Throwable t) {
                clazz = null;
                throwable = t;
            }
            if (clazz == null) {
                for (ClassLoader extraClassLoader : getExtraClassLoaders()) {
                    try {
                        clazz = extraClassLoader.loadClass(name);
                        if (clazz != null) {
                            break;
                        }
                    } catch (ClassNotFoundException e) {
                        // Ignore, already handled
                    }
                }
            }
            if (clazz == null && throwable != null) {
                if (throwable instanceof ClassNotFoundException) {
                    throw (ClassNotFoundException) throwable;
                } else if (throwable instanceof RuntimeException) {
                    throw (RuntimeException) throwable;
                } else {
                    throw new RuntimeException(throwable);
                }
            } 
            return clazz;
        }
    
        @Override
        protected URL findResource(String name) {
            URL resource;
            Throwable throwable;
            try {
                resource = defaultClassLoader.getResource(name);
                throwable = null;
            } catch (Throwable t) {
                resource = null;
                throwable = t;
            }
            if (resource == null) {
                for (ClassLoader extraClassLoader : getExtraClassLoaders()) {
                    resource = extraClassLoader.getResource(name);
                    if (resource != null) {
                        break;
                    }
                }
            }
            if (resource == null && throwable != null) {
                if (throwable instanceof RuntimeException) {
                    throw (RuntimeException) throwable;
                } else {
                    throw new RuntimeException(throwable);
                }
            } 
            return resource;
        }
    
        @Override
        protected Enumeration<URL> findResources(String name) throws IOException {
            Enumeration<URL> resources;
            Throwable throwable;
            try {
                resources = defaultClassLoader.getResources(name);
                throwable = null;
            } catch (Throwable t) {
                resources = null;
                throwable = t;
            }
            if (resources == null) {
                for (ClassLoader extraClassLoader : getExtraClassLoaders()) {
                    resources = extraClassLoader.getResources(name);
                    if (resources != null) {
                        break;
                    }
                }
            }
            if (resources == null && throwable != null) {
                if (throwable instanceof IOException) {
                    throw (IOException) throwable;
                } else if (throwable instanceof RuntimeException) {
                    throw (RuntimeException) throwable;
                } else {
                    throw new RuntimeException(throwable);
                }
            } 
            return resources;
        }
    
    }

    插件框架参考 http://www.cnblogs.com/chenying99/archive/2013/04/01/2994529.html

  • 相关阅读:
    第60届IMO 第5题
    第31届IMO 第2题
    洛谷【P1595 信封问题】 题解
    洛谷【P2022 有趣的数】 题解
    洛谷【P5004 专心OI
    04-----jQuery的属性操作
    03-----jQuery动画效果
    02-----jQuery的选择器
    01-----jQuery介绍
    17-----案例
  • 原文地址:https://www.cnblogs.com/chenying99/p/2914886.html
Copyright © 2011-2022 走看看