Package ch.njol.skript

Source Code of ch.njol.skript.SkriptAddon

/*
*   This file is part of Skript.
*
*  Skript is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  Skript 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 General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with Skript.  If not, see <http://www.gnu.org/licenses/>.
*
*
* Copyright 2011-2014 Peter Güttinger
*
*/

package ch.njol.skript;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.bukkit.plugin.java.JavaPlugin;
import org.eclipse.jdt.annotation.Nullable;

import ch.njol.skript.localization.Language;
import ch.njol.skript.util.Utils;
import ch.njol.skript.util.Version;
import ch.njol.util.coll.iterator.EnumerationIterable;

/**
* Utility class for Skript addons. Use {@link Skript#registerAddon(JavaPlugin)} to create a SkriptAddon instance for your plugin.
*
* @author Peter Güttinger
*/
public final class SkriptAddon {
 
  public final JavaPlugin plugin;
  public final Version version;
  private final String name;
 
  /**
   * Package-private constructor. Use {@link Skript#registerAddon(JavaPlugin)} to get a SkriptAddon for your plugin.
   *
   * @param p
   */
  SkriptAddon(final JavaPlugin p) {
    plugin = p;
    name = "" + p.getName();
    Version v;
    try {
      v = new Version("" + p.getDescription().getVersion());
    } catch (final IllegalArgumentException e) {
      final Matcher m = Pattern.compile("(\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?").matcher(p.getDescription().getVersion());
      if (!m.find())
        throw new IllegalArgumentException("The version of the plugin " + p.getName() + " does not contain any numbers: " + p.getDescription().getVersion());
      v = new Version(Utils.parseInt("" + m.group(1)), m.group(2) == null ? 0 : Utils.parseInt("" + m.group(2)), m.group(3) == null ? 0 : Utils.parseInt("" + m.group(3)));
      Skript.warning("The plugin " + p.getName() + " uses a non-standard version syntax: '" + p.getDescription().getVersion() + "'. Skript will use " + v + " instead.");
    }
    version = v;
  }
 
  @Override
  public final String toString() {
    return name;
  }
 
  public String getName() {
    return name;
  }
 
  /**
   * Loads classes of the plugin by package. Useful for registering many syntax elements like Skript does it.
   *
   * @param basePackage The base package to add to all sub packages, e.g. <tt>"ch.njol.skript"</tt>.
   * @param subPackages Which subpackages of the base package should be loaded, e.g. <tt>"expressions", "conditions", "effects"</tt>. Subpackages of these packages will be loaded
   *            as well. Use an empty array to load all subpackages of the base package.
   * @throws IOException If some error occurred attempting to read the plugin's jar file.
   * @return This SkriptAddon
   */
  public SkriptAddon loadClasses(String basePackage, final String... subPackages) throws IOException {
    assert subPackages != null;
    final JarFile jar = new JarFile(getFile());
    for (int i = 0; i < subPackages.length; i++)
      subPackages[i] = subPackages[i].replace('.', '/') + "/";
    basePackage = basePackage.replace('.', '/') + "/";
    try {
      for (final JarEntry e : new EnumerationIterable<JarEntry>(jar.entries())) {
        if (e.getName().startsWith(basePackage) && e.getName().endsWith(".class")) {
          boolean load = subPackages.length == 0;
          for (final String sub : subPackages) {
            if (e.getName().startsWith(sub, basePackage.length())) {
              load = true;
              break;
            }
          }
          if (load) {
            final String c = e.getName().replace('/', '.').substring(0, e.getName().length() - ".class".length());
            try {
              Class.forName(c, true, plugin.getClass().getClassLoader());
            } catch (final ClassNotFoundException ex) {
              Skript.exception(ex, "Cannot load class " + c + " from " + this);
            } catch (final ExceptionInInitializerError err) {
              Skript.exception(err.getCause(), this + "'s class " + c + " generated an exception while loading");
            }
            continue;
          }
        }
      }
    } finally {
      try {
        jar.close();
      } catch (final IOException e) {}
    }
    return this;
  }
 
  @Nullable
  private String languageFileDirectory = null;
 
  /**
   * Makes Skript load language files from the specified directory, e.g. "lang" or "skript lang" if you have a lang folder yourself. Localised files will be read from the
   * plugin's jar and the plugin's data folder, but the default English file is only taken from the jar and <b>must</b> exist!
   *
   * @param directory Directory name
   * @return This SkriptAddon
   */
  public SkriptAddon setLanguageFileDirectory(String directory) {
    if (languageFileDirectory != null)
      throw new IllegalStateException();
    directory = "" + directory.replace('\\', '/');
    if (directory.endsWith("/"))
      directory = "" + directory.substring(0, directory.length() - 1);
    languageFileDirectory = directory;
    Language.loadDefault(this);
    return this;
  }
 
  @Nullable
  public String getLanguageFileDirectory() {
    return languageFileDirectory;
  }
 
  @Nullable
  private File file = null;
 
  /**
   * @return The jar file of the plugin. The first invocation of this method uses reflection to invoke the protected method {@link JavaPlugin#getFile()} to get the plugin's jar
   *         file. The file is then cached and returned upon subsequent calls to this method to reduce usage of reflection.
   */
  @Nullable
  public File getFile() {
    if (file != null)
      return file;
    try {
      final Method getFile = JavaPlugin.class.getDeclaredMethod("getFile");
      getFile.setAccessible(true);
      file = (File) getFile.invoke(plugin);
      return file;
    } catch (final NoSuchMethodException e) {
      Skript.outdatedError(e);
    } catch (final IllegalArgumentException e) {
      Skript.outdatedError(e);
    } catch (final IllegalAccessException e) {
      assert false;
    } catch (final SecurityException e) {
      throw new RuntimeException(e);
    } catch (final InvocationTargetException e) {
      throw new RuntimeException(e.getCause());
    }
    return null;
  }
 
}
TOP

Related Classes of ch.njol.skript.SkriptAddon

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.