Package com.godshawk.lib.plugin

Source Code of com.godshawk.lib.plugin.PluginManager

/*
* LibGodshawk - General-purpose Java library
* Copyright (C) 2014-2015 godshawk
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.godshawk.lib.plugin;

import com.godshawk.lib.annotations.modularity.Plugin;
import com.godshawk.lib.exception.InitializationException;
import com.godshawk.lib.exception.TooManyPluginsException;
import com.godshawk.lib.interfaces.modularity.IPlugin;
import com.godshawk.lib.manager.AbstractManager;
import com.godshawk.lib.plugin.metadata.EnumPluginKeys;
import com.godshawk.lib.plugin.metadata.PluginMetadata;
import com.godshawk.lib.reflection.ClassEnumerator;

import java.awt.geom.IllegalPathStateException;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("unused")
public final class PluginManager extends AbstractManager<IPlugin> {
    /**
     * Sanity limit on the number of plugins
     */
    private static final int HARD_LIMIT = 128;

    private final File pluginDir;

    private String configExtension = "plugin";

    public PluginManager(File pluginDir) {
        super();
        this.pluginDir = pluginDir;
        if (!this.pluginDir.exists()) {
            if (!this.pluginDir.mkdir()) {
                throw new IllegalPathStateException("Unable to create plugin directory!");
            }
        }
    }

    @SuppressWarnings("unchecked")
    private void loadPlugins() throws TooManyPluginsException {
        List<Class<?>> classesInDir = ClassEnumerator.getClassesFromExternalDirectory(pluginDir);
        List<Class<? extends IPlugin>> pluginClasses = new ArrayList<>();
        classesInDir.stream().filter(IPlugin.class::isAssignableFrom).sequential()
                .forEach(c -> pluginClasses.add((Class<? extends IPlugin>) c));

        if (pluginClasses.size() + getObjects().size() > HARD_LIMIT) {
            throw new TooManyPluginsException(pluginClasses.size(), HARD_LIMIT);
        }

        pluginClasses.forEach(this::internalPluginLoad);
    }

    private void setupPlugins() throws InitializationException {
        for (IPlugin plugin : getObjects()) {
            plugin.initialize();
        }
    }

    @Override
    public void initialize() throws InitializationException {
        try {
            loadPlugins();
            setupPlugins();
        } catch (TooManyPluginsException e) {
            throw new RuntimeException(e);
        }
    }

    public PluginMetadata generateMetadata(Class<? extends IPlugin> plugin) {
        if (!plugin.isAnnotationPresent(Plugin.class)) {
            throw new IllegalArgumentException(String.format("Plugin %s is not annotated!", plugin.getSimpleName()));
        }
        Plugin pl = plugin.getDeclaredAnnotation(Plugin.class);
        return new PluginMetadata(pl.name(), pl.id(), pl.author(), pl.type());
    }

    public void internalPluginLoad(Class<? extends IPlugin> pluginClass) {
        try {
            PluginMetadata metadata = generateMetadata(pluginClass);
            IPlugin plugin = pluginClass.getDeclaredConstructor(
                    PluginManager.class, File.class, File.class
            ).newInstance(
                    this, pluginDir, new File(
                            String.format("%s%s%s.%s",
                                    pluginDir.getAbsolutePath(),
                                    File.separator,
                                    metadata.getKeyValue(EnumPluginKeys.PLUGIN_ID.getValue()),
                                    configExtension
                            )
                    )
            );
            plugin.setMetadata(metadata);

            addObject(plugin);
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException
                | InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public void setConfigExtension(String ext) {
        configExtension = ext;
    }

    @SuppressWarnings("unchecked")
    public <T extends IPlugin> T getPluginByPluginId(String id) {
        for (IPlugin p : getObjects()) {
            if (p.getMetadata().getKeyValue(EnumPluginKeys.PLUGIN_ID.getValue()).equals(id)) {
                return (T) p;
            }
        }
        return null;
    }
}
TOP

Related Classes of com.godshawk.lib.plugin.PluginManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.