Package scripting

Source Code of scripting.Script

/*
* @author Kyle Kemp
*/
package scripting;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.concurrent.ConcurrentSkipListSet;

import javax.script.Bindings;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.eclipse.swt.SWT;
import org.pircbotx.hooks.Event;

import connection.KEllyBot;

import lombok.Getter;
import lombok.Setter;

import shared.NSAlertBox;
import sun.org.mozilla.javascript.internal.NativeArray;

/**
* The Class Script.
*/
public final class Script implements Comparable<Script> {
 
  /** The Constant JAVASCRIPT. */
  public static final int JAVASCRIPT = 1;
 
  /** The Constant RUBY. */
  public static final int RUBY = 2;
 
  //XXX not supported yet
  /** The Constant PYTHON. */
  public static final int PYTHON = 3;
 
  /**
   * Gets the script type.
   *
   * @return the script type
   */
  @Getter
  private int scriptType=0;
 
  /**
   * Checks if is in use.
   *
   * @return true, if is in use
   */
  @Getter /**
  * Sets the in use.
  *
  * @param inUse the new in use
  */
@Setter
  private boolean inUse = true;
 
  /**
   * Gets the script.
   *
   * @return the script
   */
  @Getter
  private String script;
 
  /**
   * Gets the file reference.
   *
   * @return the reference
   */
  @Getter
  private File reference;
 
  /**
   * Gets the function list associated with this script.
   *
   * @return the functions
   */
  @Getter
  private ConcurrentSkipListSet<String> functions = new ConcurrentSkipListSet<String>();
 
  /**
   * Gets the descript version of the functions associated with this script.
   *
   * @return the descript functions
   */
  @Getter
  private ConcurrentSkipListSet<String> descriptFunctions = new ConcurrentSkipListSet<String>();
 
  /**
   * Gets the name of the script.
   *
   * @return the name
   */
  @Getter
  private String name;
 
  /** The newline constant. */
  private static final String nl = System.getProperty("line.separator");
 
  /** The manager. */
  private static ScriptEngineManager manager = new ScriptEngineManager();
 
  /** The js engine. */
  private static ScriptEngine jsEngine = manager.getEngineByName("JavaScript");
 
  /** The rb engine. */
  private static ScriptEngine rbEngine = manager.getEngineByName("jruby");
 
  /** The js invocable. */
  private static Invocable jsInvocable = (Invocable) jsEngine;
 
  /** The rb invocable. */
  private static Invocable rbInvocable = (Invocable) rbEngine;
 
  /** The bindings. */
  private static Bindings bindings = jsEngine.getBindings(ScriptContext.ENGINE_SCOPE);
 
  /** The rb base script. */
  private String rbBase = "require \"java\""+nl;
 
  /** The js base script. */
  private String jsBase = "importClass(org.eclipse.swt.SWT);" +nl+
              "importClass(Packages.hexapixel.notifier.NotificationType);" +nl+
              "importClass(Packages.org.pircbotx.Colors);" +nl+
              "importClass(java.lang.Thread);" +nl+
              "importClass(Packages.connection.KEllyBot);" +nl+
              "importPackage(org.pircbotx);" +nl+
              "importPackage(java.util);" +nl+
              "importPackage(java.lang);" +nl;
 
  /**
   * Instantiates a new script.
   *
   * @param f the f
   */
  public Script(File f) {
    this.reference = f;
    this.name = f.getName();
   
    String s = reference.getName().substring(reference.getName().indexOf('.'));

    if(s.equals(".js")){
      scriptType=JAVASCRIPT;
    } else if(s.equals(".rb")){
      scriptType=RUBY;
    }
   
    reset();
  }

  /**
   * Reset the script.
   */
  public void reset() {
    readScript();
   
    initBindings();
   
    initialize();
  }

  /**
   * Initialize.
   */
  private void initialize() {
    try {
      switch(scriptType){
      case JAVASCRIPT:
        jsEngine.eval(jsBase+script);
        break;
        //TODO fix ruby scripts breaking on windows
      case RUBY:
            rbEngine.eval(rbBase+script);
            break;
      }
    } catch (ScriptException e) {

      new NSAlertBox("Script Read Error", reference.getName()+" has an error. Due to error reporting methods, I can not help you narrow down the issue. Here is a stack trace:\n"+e.getMessage(), SWT.ICON_ERROR);

      org.apache.log4j.Logger fLog = org.apache.log4j.Logger.getLogger("log.script.scripts");
      fLog.error("Script initialization failed: "+reference.getName()+" at line #"+e.getLineNumber());
    } catch(Exception e) {
      org.apache.log4j.Logger fLog = org.apache.log4j.Logger.getLogger("log.script.scripts");
      fLog.error("Script initialization failed: "+e.getStackTrace());
    }
   
  }

  /**
   * Initialize the bindings.
   */
  private void initBindings() {
    bindings.put("global", new ScriptVars());
    bindings.put("util", new ScriptFunctions());
    bindings.put("gui", new ScriptGUI());
    bindings.put("sound", new SoundData());
  }

  /**
   * Read script.
   */
  public void readScript() {

    //reset the functions list
    functions.clear();
    descriptFunctions.clear();
   
    //re-parse the script
    StringBuffer contents = new StringBuffer();
   
    BufferedReader reader = null;
    if(!reference.exists()) return;

    try {
      reader = new BufferedReader(new FileReader(reference));
      String text = null;
      while((text = reader.readLine())!=null){
        contents.append(text).append(System.getProperty("line.separator"));
        parseFunction(text);
      }
      reader.close();
    } catch (Exception e) {
      org.apache.log4j.Logger fLog = org.apache.log4j.Logger.getLogger("log.script.scripts");
      fLog.error("Script reading failed.", e);
    }
   
    script = contents.toString();
  }
 
  //check line-by-line for a function name
  /**
   * Parses the function.
   *
   * @param text the text
   */
  private void parseFunction(String text) {
    if(text.toLowerCase().contains("meta")) {
      parseMeta(text);
    }
    switch(scriptType){
    case JAVASCRIPT:
      if(!text.contains("function ")) return;
      String elFunction = text.substring(9).split("[{]")[0].trim();
      descriptFunctions.add(elFunction);
      String[] array = text.replaceAll("[(]", " ").split(" ");
      //function, onFunctionName, event), {
      functions.add(array[1].trim());
      break;
    case RUBY:
      if(!text.contains("def ")) return;
      String rbFunction = text.substring(4);
      descriptFunctions.add(rbFunction);
      String[] rbarray = text.replaceAll("[(]", " ").split(" ");
      //def function(var)
      functions.add(rbarray[1].trim());
      break;
    }
  }
 
  /**
   * Parses the metadata of a script.
   *
   * @param text the text
   */
  private void parseMeta(String text){
    //META<inuse=false>
    String[] cleanMeta = text.replaceAll("[<>]", " ").split(" ")[1].split("=");
    if(cleanMeta[0].equals("inuse")){
      this.inUse = Boolean.parseBoolean(cleanMeta[1]);
    }
  }
 
  //event invocation
  /**
   * Invoke a function on a script, using a specified invocation schema
   *
   * @param function the function
   * @param e the e
   */
  public void invoke(String function, Event<KEllyBot> e){
    if(!inUse)return;
    try {
      switch(scriptType){
      case JAVASCRIPT:
        jsInvocable.invokeFunction(function, e);
        break;
      case RUBY:
        rbInvocable.invokeFunction(function, e);
        break;
      }
    } catch (NoSuchMethodException e1) {
      org.apache.log4j.Logger fLog = org.apache.log4j.Logger.getLogger("log.script.scripts");
      fLog.error("Script invocation failed.", e1);
    } catch (ScriptException e1) {
      org.apache.log4j.Logger fLog = org.apache.log4j.Logger.getLogger("log.script.scripts");
      fLog.error("Script invocation failed.", e1);
    }
  }

  //open-ended invocation
  /**
   * Invoke with no expectation of returning a vlaue.
   *
   * @param command the command
   * @param args the args
   */
  public void invoke(String command, Object... args) {
    if(!inUse)return;
    try {
      switch(scriptType){
      case JAVASCRIPT:
        jsInvocable.invokeFunction(command, args);
        break;
      case RUBY:
        rbInvocable.invokeFunction(command, args);
        break;
      }
    } catch (NoSuchMethodException e1) {
      org.apache.log4j.Logger fLog = org.apache.log4j.Logger.getLogger("log.script.scripts");
      fLog.error("Script invocation failed.", e1);
    } catch (ScriptException e1) {
      org.apache.log4j.Logger fLog = org.apache.log4j.Logger.getLogger("log.script.scripts");
      fLog.error("Script invocation failed.", e1);
    }
  }
 
  /**
   * Invoke, and turn objects back into Java-accessible objects.
   *
   * @param command the command
   * @return the object[]
   */
  public Object[] invoke(String command) {
    Object[] rv = null;
    try {
      switch(scriptType){
      case JAVASCRIPT:
        NativeArray arr = (NativeArray) jsInvocable.invokeFunction(command);
        rv = new Object[(int)arr.getLength()];
       
        //get as object
        for(Object o : arr.getIds()) {
          int index = (Integer) o;
          rv[index] = arr.get(index, null);
        }
        break;
      case RUBY:
        rv = (Object[]) rbInvocable.invokeFunction(command);
      }
    } catch (NoSuchMethodException e) {
      org.apache.log4j.Logger fLog = org.apache.log4j.Logger.getLogger("log.script.scripts");
      fLog.error("Script invocation failed.", e);
    } catch (ScriptException e) {
      org.apache.log4j.Logger fLog = org.apache.log4j.Logger.getLogger("log.script.scripts");
      fLog.error("Script invocation failed.", e);
    }
    return rv;
  }
 
  /* (non-Javadoc)
   * @see java.lang.Comparable#compareTo(java.lang.Object)
   */
  @Override
  public int compareTo(Script o) {
    return reference.getName().compareTo(o.reference.getName());
  }
}
TOP

Related Classes of scripting.Script

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.