net.morematerials.manager.HandlerManager.java Source code

Java tutorial

Introduction

Here is the source code for net.morematerials.manager.HandlerManager.java

Source

/*
 * This file is part of MoreMaterials, licensed under the MIT License (MIT).
 *
 * Copyright (c) 2013 AlmuraDev <http://www.almuradev.com/>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package net.morematerials.manager;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;

import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

import org.apache.commons.lang.StringUtils;
import org.bukkit.event.Event;

import net.morematerials.MoreMaterials;
import net.morematerials.handlers.GenericHandler;

@SuppressWarnings("restriction")
public class HandlerManager {

    private Map<String, GenericHandler> handlers = new HashMap<String, GenericHandler>();
    private MoreMaterials plugin;
    private List<Map<String, Object>> handlerRegister = new ArrayList<Map<String, Object>>();

    private List<String> compilerOptions = new ArrayList<String>();

    public HandlerManager(MoreMaterials plugin) {
        this.plugin = plugin;

        File folder = new File(plugin.getDataFolder(), "handlers");

        // We can only compile if the JDK is found.
        if (ToolProvider.getSystemJavaCompiler() != null) {
            this.prepareCompiler(new File(folder, "bin"));
            for (File file : (new File(folder, "src")).listFiles()) {
                if (file.getName().endsWith(".java")) {
                    try {
                        this.compile(file);
                    } catch (Exception exception) {
                        this.plugin.getUtilsManager().log("Error compiling handler: " + file.getName(),
                                Level.WARNING);
                    }
                }
            }
        } else {
            this.plugin.getUtilsManager()
                    .log("Server not using Java JDK environment, custom handlers will not function.", Level.INFO);
            this.plugin.getUtilsManager()
                    .log("Ignore this error if your not trying to use your own custom handlers.", Level.INFO);
        }

        for (File file : (new File(folder, "bin")).listFiles()) {
            if (file.getName().endsWith(".class") && file.getName().indexOf("$") == -1) {
                this.load(file);
            }
        }
    }

    private void compile(File file) throws IOException {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
        Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjects(file);
        CompilationTask task = compiler.getTask(null, fileManager, null, this.compilerOptions, null,
                compilationUnits);
        task.call();
    }

    public void load(File handlerClass) {
        String className = handlerClass.getName().substring(0, handlerClass.getName().lastIndexOf("."));
        String useName = className.replaceAll("Handler$", "");
        try {
            @SuppressWarnings("resource")
            ClassLoader loader = new URLClassLoader(new URL[] { handlerClass.getParentFile().toURI().toURL() },
                    GenericHandler.class.getClassLoader());
            Class<?> clazz = loader.loadClass(className);
            Object object = clazz.newInstance();
            if (!(object instanceof GenericHandler)) {
                this.plugin.getUtilsManager().log("Not a handler: " + useName, Level.WARNING);
            } else {
                GenericHandler handler = (GenericHandler) object;
                handler.init(this.plugin);
                this.handlers.put(useName, handler);
                this.plugin.getUtilsManager().log("Loaded handler: " + useName);
            }
        } catch (Exception exception) {
            this.plugin.getUtilsManager().log("Error loading handler: " + useName, Level.SEVERE);
        }
    }

    public GenericHandler getHandler(String handler) {
        if (this.handlers.containsKey(handler)) {
            return this.handlers.get(handler);
        }
        return null;
    }

    public void registerHandler(String eventType, Integer materialId, Map<String, Object> config) {
        config.put("materialId", materialId);
        config.put("eventType", eventType);
        this.handlerRegister.add(config);
    }

    public void triggerHandlers(String eventType, Integer materialId, Event event) {
        for (Map<String, Object> config : this.handlerRegister) {
            if (((Integer) config.get("materialId")).equals(materialId)
                    && ((String) config.get("eventType")).equals(eventType)) {
                this.getHandler((String) config.get("Name")).onActivation(event, config);
            }
        }
    }

    private void prepareCompiler(File binFolder) {
        //Search & add dependencies
        List<String> libs = new ArrayList<String>();
        libs.add(System.getProperty("java.class.path"));

        // Add all plugins to allow using other plugins.
        for (File lib : (new File("plugins")).listFiles()) {
            if (lib.getName().endsWith(".jar")) {
                libs.add("plugins/" + lib.getName());
            }
        }

        // Set the classpath.
        this.compilerOptions.addAll(Arrays.asList("-classpath", StringUtils.join(libs, File.pathSeparator), "-d",
                binFolder.getAbsolutePath()));
    }

    public void inject(Class<? extends GenericHandler> clazz) {
        String useName = clazz.getName().split("Handler")[0].split("net.morematerials.handlers.")[1];

        try {
            Object object = clazz.newInstance();
            GenericHandler handler = (GenericHandler) object;
            handler.init(this.plugin);
            this.handlers.put(useName, handler);
            this.plugin.getUtilsManager().log("Loaded Internal MM handler: " + useName);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}