001    // GraphLab Project: http://graphlab.sharif.edu
002    // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology
003    // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/
004    package graphlab.platform.extension;
005    
006    import graphlab.platform.Application;
007    import graphlab.platform.core.AbstractAction;
008    import graphlab.platform.core.BlackBoard;
009    import graphlab.platform.preferences.lastsettings.StorableOnExit;
010    
011    import java.io.File;
012    import java.lang.reflect.Constructor;
013    import java.util.HashSet;
014    
015    /**
016     * The base class for loading extensions.
017     * This class performs loading and reloading of extensions,  (from their source (.class or anyother format) files)
018     *
019     * @author Azin Azadi
020     */
021    public class ExtensionLoader implements StorableOnExit {
022        private static HashSet<ExtensionHandler> registeredExtensionHandlers = new HashSet<ExtensionHandler>();
023        private static HashSet<UnknownExtensionLoader> registeredUnknownExtensionLoaders = new HashSet<UnknownExtensionLoader>();
024    
025        /**
026         * Registers extHandler as an extension handler, so after this new extension that are loaded
027         * to GraphLab will be given to handler.
028         * <p/>
029         * calling this method will not affect previously loaded extensions.
030         *
031         * @param extHandler
032         */
033        public static void registerExtensionHandler(ExtensionHandler extHandler) {
034            registeredExtensionHandlers.add(extHandler);
035        }
036    
037        public static HashSet<ExtensionHandler> getRegisteredExtensionHandlers() {
038            return registeredExtensionHandlers;
039        }
040    
041        /**
042         * register e as an unKnownExtensionLoader, which GraphLab will try to load "not .class files" with them
043         *
044         * @param e
045         */
046        public static void registerUnknownExtensionLoader(UnknownExtensionLoader e) {
047            registeredUnknownExtensionLoaders.add(e);
048        }
049    
050        /**
051         * gets e as an extension and tries to create Its relating AbstractAction
052         * using registered ExtensionHandlers
053         */
054        public static AbstractAction handleExtension(BlackBoard b, Object e) {
055            AbstractAction a = null;
056            for (ExtensionHandler _ : registeredExtensionHandlers) {
057                if (a == null)
058                    a = _.handle(b, e);
059                else
060                    _.handle(b, e);
061            }
062            return a;
063        }
064    
065        /**
066         * returns an instance of extensionClass if the given extensionClass implements Extension (BasicExtension)
067         * or has default constructor, otherwise it returns null
068         *
069         * @param extensionClass
070         * @return
071         */
072        public static Object loadExtension(Class extensionClass) {
073            Object ret = null;
074            try {
075                if (BasicExtension.class.isAssignableFrom(extensionClass)) {
076                    Constructor[] cs = extensionClass.getConstructors();
077                    for (Constructor c : cs) {
078                        Class[] p = c.getParameterTypes();
079                        if (p.length == 1 && p[0].equals(BlackBoard.class)) {
080                            ret = extensionClass.getConstructor(BlackBoard.class).newInstance(Application.blackboard);
081                            break;
082                        }
083                    }
084                    if (ret == null && extensionClass.getConstructor() != null) {
085                        ret = extensionClass.newInstance();
086                    }
087                }
088                if (ret != null) {
089                    SETTINGS.registerSetting(ret, "Extention Options");
090                }
091                return ret;
092            } catch (Exception e) {
093                System.err.println(extensionClass);
094                e.printStackTrace();
095            }
096            return ret;
097        }
098    
099        /**
100         * returns an instance of extensionClsas if the given extensionClass implements Extension, otherwise it returns null
101         *
102         * @param unknownFile
103         */
104        public static Extension loadUnknownExtension(File unknownFile, BlackBoard blackboard) {
105            for (UnknownExtensionLoader _ : registeredUnknownExtensionLoaders) {
106                Extension extension = _.load(unknownFile, blackboard);
107                if (extension != null)
108                    return extension;
109            }
110            return null;
111        }
112    
113    
114    }