Package com.scriptographer.script.rhino

Source Code of com.scriptographer.script.rhino.RhinoWrapFactory

/*
* 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 Apr 10, 2007.
*/

package com.scriptographer.script.rhino;

import java.util.IdentityHashMap;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.MemberBox;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;

import com.scratchdisk.script.rhino.ExtendedJavaObject;
import com.scriptographer.ai.Color;
import com.scriptographer.ai.RGBColor;
import com.scriptographer.ai.Style;
import com.scriptographer.script.EnumUtils;

/**
* @author lehni
*
*/
public class RhinoWrapFactory extends
    com.scratchdisk.script.rhino.RhinoWrapFactory {

  public Object wrap(Context cx, Scriptable scope, Object obj,
      Class<?> staticType) {
    // By default, Rhino converts chars to integers. In Scriptographer, we
    // want a string of length 1:
      if (staticType == Character.TYPE)
      return obj.toString();
    else if (obj instanceof Enum)
      // TODO: Could this be moved to wrapCustom?
      return EnumUtils.getScriptName((Enum) obj);
    return super.wrap(cx, scope, obj, staticType);
  }

  IdentityHashMap<Class, Function> mappedJavaClasses =
      new IdentityHashMap<Class, Function>();
 
  /**
   * Maps a Java class to a JavaScript prototype, so this can be used instead
   * for wrapping of returned java types. So far this is only used for
   * java.io.File in Scriptographer.
   */
  public void mapJavaClass(Class cls, Function ctor) {
    mappedJavaClasses.put(cls, ctor);
  }

  public Scriptable wrapCustom(Context cx, Scriptable scope,
      Object javaObj, Class<?> staticType, boolean newObject) {
    if (javaObj instanceof Style)
      return new StyleWrapper(scope, (Style) javaObj, staticType, true);
    else if (javaObj instanceof Color)
      return new ColorWrapper(scope, (Color) javaObj, staticType, true);
    else if (javaObj instanceof java.awt.Color)
      return new ColorWrapper(scope, new RGBColor(
          (java.awt.Color) javaObj), staticType, true);
    else {
      Function ctor = mappedJavaClasses.get(staticType);
      if (ctor != null) {
        // If this native object was explicitly created from JS,
        // lets wrap it in a uncached ExtendedJavaObject.
        if (newObject)
          return null;
        scope = ScriptableObject.getTopLevelScope(scope);
        // Do not go through Context.javaToJS as this would again
        // end up here in wrapCustom for a native object.
        // Just wrap it as an ExtendedJavaObject.
        return ctor.construct(cx, scope, new Object[] {
          new ExtendedJavaObject(scope, javaObj, javaObj.getClass(),
              false)
        });
      }
    }
    return new ExtendedJavaObject(scope, javaObj, staticType, true);
  }

  public int calculateConversionWeight(Object from, Object unwrapped,
      Class<?> to, int defaultWeight) {
    int weight = super.calculateConversionWeight(from, unwrapped, to,
        defaultWeight);
    if (weight == defaultWeight) {
      if (unwrapped instanceof String
          && (Enum.class.isAssignableFrom(to) || to.isArray()))
        weight = CONVERSION_TRIVIAL + 1;
      else if (unwrapped instanceof Color
          && java.awt.Color.class.equals(to))
        weight = CONVERSION_TRIVIAL;
      else if (unwrapped instanceof java.awt.Color
          && Color.class.equals(to))
        weight = CONVERSION_TRIVIAL;
    }
    return weight;
  }

  @SuppressWarnings("unchecked")
  public Object coerceType(Class<?> type, Object value, Object unwrapped) {
    Object res = super.coerceType(type, value, unwrapped);
    if (res == null) {
      if (unwrapped instanceof String) {
        if (Enum.class.isAssignableFrom(type)) {
          return EnumUtils.get((Class<Enum>) type,
              (String) unwrapped);
        } else if (type.isArray()) {
          // Convert a string to an array by splitting into words
          // and trying to convert each to the desired type
          String[] parts = ((String) unwrapped).split("\\s");
          Class componentType = type.getComponentType();
          Object[] values = (Object[])
              java.lang.reflect.Array.newInstance(
                  componentType, parts.length);
          for (int i = 0; i < values.length; i++) {
            String part = parts[i];
            values[i] = coerceType(componentType, part, part);
          }
          return values;
        }
      } else if (unwrapped instanceof java.awt.Color
          && Color.class.equals(type)) {
        return new RGBColor((java.awt.Color) unwrapped);
      } else if (unwrapped instanceof Color
          && java.awt.Color.class.equals(type)) {
        return ((Color) unwrapped).toAWTColor();
      }
    }
    return res;
  }

  public boolean shouldAddBean(Class<?> cls, boolean isStatic,
      MemberBox getter, MemberBox setter) {
    Package pkg = cls.getPackage();
    // Only control adding of beans if we're inside com.scriptographer
    // packages. Outside, we always add the bean. Inside, we add it except
    // if it's a read-only bean of which the getter name starts with is, to
    // force isMethodName() style methods to be called as methods.
    return getter != null && !(pkg != null
        && pkg.getName().startsWith("com.scriptographer."))
        || setter != null || !getter.getName().startsWith("is");
  }

  public boolean shouldRemoveGetterSetter(Class<?> cls, boolean isStatic,
      MemberBox getter, MemberBox setter) {
    Package pkg = cls.getPackage();
    // Only remove getter / setters of beans that were added within
    // com.scriptographer packages. Outside we use the old convention of
    // never removing them.
    return pkg != null && pkg.getName().startsWith("com.scriptographer.");
  }
}
TOP

Related Classes of com.scriptographer.script.rhino.RhinoWrapFactory

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.