Package com.scratchdisk.script.rhino

Source Code of com.scratchdisk.script.rhino.TopLevel

/*
* Scriptographer
*
* This file is part of Scriptographer, a Scripting Plugin for Adobe Illustrator
* http://scriptographer.org/
*
* Copyright (c) 2002-2010, Juerg Lehni
* http://scratchdisk.com/
*
* All rights reserved. See LICENSE file for details.
*
* File created on 06.03.2005.
*/

package com.scratchdisk.script.rhino;

import java.lang.reflect.Method;
import java.util.Date;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.EvaluatorException;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.ImporterTopLevel;
import org.mozilla.javascript.LazilyLoadedCtor;
import org.mozilla.javascript.NativeJavaObject;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.Undefined;
import org.mozilla.javascript.Wrapper;

import com.scratchdisk.script.ScriptEngine;
/**
* @author lehni
*/
public class TopLevel extends ImporterTopLevel {

  public TopLevel() {
  }

  public TopLevel(Context context, boolean sealed) {
    super(context, sealed);
  }

  public TopLevel(Context context) {
    super(context, false);
  }

  protected static final String[] topPackages = {
    "Packages",    "com.scratchdisk.script.rhino.ExtendedJavaTopPackage",
    "java",      "com.scratchdisk.script.rhino.ExtendedJavaTopPackage",
    "javax",    "com.scratchdisk.script.rhino.ExtendedJavaTopPackage",
    "org",      "com.scratchdisk.script.rhino.ExtendedJavaTopPackage",
    "com",      "com.scratchdisk.script.rhino.ExtendedJavaTopPackage",
    "edu",      "com.scratchdisk.script.rhino.ExtendedJavaTopPackage",
    "net",      "com.scratchdisk.script.rhino.ExtendedJavaTopPackage",
//     "getClass",    "com.scratchdisk.script.rhino.ExtendedJavaTopPackage"
  };

  public void initStandardObjects(Context cx, boolean sealed) {
    super.initStandardObjects(cx, sealed);
    // Override the class loading objects with our own extended classes

    for (int i = 0; i != topPackages.length; i += 2)
      new LazilyLoadedCtor(this, topPackages[i], topPackages[i + 1], false);

    // define some global functions and objects:
    String[] names = { "print", "evaluate" };
    defineFunctionProperties(names, TopLevel.class,
      ScriptableObject.DONTENUM);

    ScriptableObject objProto = (ScriptableObject) getObjectPrototype(this);
    objProto.defineFunctionProperties(new String[] {
        "dontEnum", "toJava", "print", "evaluate"
        }, TopLevel.class, DONTENUM);
  }

  public static void defineProperty(ScriptableObject obj, String name,
      String getter, String setter) throws SecurityException, NoSuchMethodException {
    Class<? extends ScriptableObject> cls = obj.getClass();
    Method getterMethod = getter != null ?
      cls.getDeclaredMethod(getter,
        new Class[] { Scriptable.class }) : null;
    Method setterMethod = setter != null ?
      cls.getDeclaredMethod(setter, new Class[] {
        Scriptable.class, Object.class }) : null;
    obj.defineProperty(name, null, getterMethod, setterMethod,
      ScriptableObject.DONTENUM);
  }

  /**
   * Set DONTENUM attributes on the given properties in this object.
   * This is set on the JavaScript Object prototype.
   */
  public static Object dontEnum(Context cx, Scriptable thisObj,
      Object[] args, Function funObj) {

    // Don't throw error for now if dontEnum cannot do anything on this object.
    // e.g. if it is a NativeJavaObject.
    // TODO: This needs to change in the future.
    // But since dontEnum will go away in favor of something the standard
    // Object.defineProperty() method described in the EcmaScript 3.1,
    // this is fine for now.
//    if (!(thisObj instanceof ScriptableObject)) {
//      throw new EvaluatorException(
//          "dontEnum() called on non-ScriptableObject");
//    }

    if (thisObj instanceof ScriptableObject) {
      ScriptableObject obj = (ScriptableObject) thisObj;
      for (int i = 0; i < args.length; i++) {
        if (!(args[i] instanceof String)) {
          throw new EvaluatorException(
              "dontEnum() called with non-String argument");
        }
        String str = (String) args[i];
        if (obj.has(str, obj)) {
          int attr = obj.getAttributes(str);
          if ((attr & PERMANENT) == 0)
            obj.setAttributes(str, attr | DONTENUM);
        }
      }
    }
    return null;
  }

  /**
   * Convert an object into a wrapper that exposes the java methods of the
   * object to JavaScript. This is useful for treating native numbers,
   * strings, etc as their java counterpart such as java.lang.Double,
   * java.lang.String etc.
   *
   * @param thisObj a java object that is wrapped in a special way Rhino
   * @return the object wrapped as NativeJavaObject, exposing the public
   *         methods of the underlying class.
   */
  public static Object toJava(Context cx, Scriptable thisObj,
      Object[] args, Function funObj) {
    if (thisObj == null || thisObj instanceof NativeJavaObject
        || thisObj == Undefined.instance) {
      return thisObj;
    }
    Scriptable topLevel = ScriptRuntime.getTopCallScope(cx);
    Object obj = thisObj;
    if (thisObj instanceof Wrapper) {
      obj = ((Wrapper) thisObj).unwrap();
    } else {
      if ("Date".equals(thisObj.getClassName())) {
        return new NativeJavaObject(topLevel,
            new Date((long) ScriptRuntime.toNumber(thisObj)), null);
      }
    }
    return new NativeJavaObject(topLevel, obj, null);
  }

  public String getClassName() {
    return "global";
  }

  /**
   * Print the string values of its arguments.
   *
   * This method is defined as a JavaScript function. Note that its arguments
   * are of the "varargs" form, which allows it to handle an arbitrary number
   * of arguments supplied to the JavaScript function.
   *
   */
  public static void print(Context cx, Scriptable thisObj, Object[] args,
      Function funObj) {
    for (int i = 0; i < args.length; i++) {
      if (i > 0)
        System.out.print(" ");

      // Convert the arbitrary JavaScript value into a string form.
      String s = Context.toString(args[i]);
      System.out.print(s);
    }
    System.out.println();
  }

  /**
   * Evaluates the given JavaScript string in the current scope. Similar to
   * eval(), but it allows the use of another object than the global scope:
   * e.g.:
   * <code>
   * var obj = {
   *     eval: evaluate
   * };
   * obj.eval("print(this);");
   * </code>
   */
  public static void evaluate(Context cx, Scriptable thisObj, Object[] args,
      Function funObj) {
    ScriptEngine engine = ScriptEngine.getEngineByName("JavaScript");
    engine.evaluate(Context.toString(args[0]), "evaluate",
        engine.getScope(thisObj));
  }
}
TOP

Related Classes of com.scratchdisk.script.rhino.TopLevel

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.