Java tutorial
/* * JEF - Copyright 2009-2010 Jiyi (mr.jiyi@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jef.jre5support.script; import java.util.HashMap; import javax.script.Bindings; import javax.script.ScriptEngine; import javax.script.ScriptException; import jef.common.log.LogUtil; import jef.script.javascript.RhinoScriptEngineFactory; import jef.tools.ArrayUtils; import jef.tools.IOUtils; import jef.tools.StringUtils; import jef.tools.XMLUtils; import jef.tools.ZipUtils; import org.apache.commons.lang.ObjectUtils; import org.mozilla.javascript.Context; import org.mozilla.javascript.Decompiler; import org.mozilla.javascript.NativeArray; import org.mozilla.javascript.NativeFunction; import org.mozilla.javascript.ScriptRuntime; import org.mozilla.javascript.ScriptableObject; import org.mozilla.javascript.UintMap; import org.mozilla.javascript.Undefined; import org.mozilla.javascript.UniqueTag; import org.mozilla.javascript.Wrapper; public class JavaScriptUtil { private static RhinoScriptEngineFactory fac = new RhinoScriptEngineFactory(); public synchronized static ScriptEngine newEngine() { return fac.getScriptEngine(); } private static final String printSource = "function echo(str) { \n" + " if (typeof(str) == 'undefined') { \n" + " str = 'undefined'; \n" + " } else if (str == null) { \n" + " str = 'null'; \n" + " } \n" + " LogUtil.show(str) \n" + "}"; public static void initEngine(ScriptEngine e, Bindings... b) { importClass(e, LogUtil.class, b); importClass(e, StringUtils.class, b); importClass(e, ArrayUtils.class, b); importClass(e, XMLUtils.class, b); importClass(e, IOUtils.class, b); importClass(e, ZipUtils.class, b); try { if (b.length > 0) { e.eval(printSource, b[0]); } else { e.eval(printSource); } } catch (ScriptException ex) { LogUtil.exception(ex); } } public static void importPackage(ScriptEngine e, Package pkg, Bindings... b) { try { if (b.length == 0) { e.eval("importPackage(Packages." + pkg.getName() + ")"); } else { e.eval("importPackage(Packages." + pkg.getName() + ")", b[0]); } } catch (ScriptException e1) { throw new RuntimeException(e1); } } public static void importClass(ScriptEngine e, Class<?> pkg, Bindings... b) { try { if (b.length == 0) { e.eval("importClass(Packages." + pkg.getName() + ")"); } else { e.eval("importClass(Packages." + pkg.getName() + ")", b[0]); } } catch (ScriptException e1) { throw new RuntimeException(e1); } } /** * Native?String * * @Title: toStringArray * @Description: TODO(????) * @param ? * @return String[] * @throws */ public static String[] toStringArray(NativeArray nv) { String[] result = new String[(int) nv.getLength()]; for (int i = 0; i < result.length; i++) { result[i] = StringUtils.toString(nv.get(i, null)); } return result; } /** * NativeArray?int[] * * @Title: toIntArray * @Description: TODO(????) * @param ? * @return int[] * @throws */ public static int[] toIntArray(NativeArray nv) { int[] result = new int[(int) nv.getLength()]; for (int i = 0; i < result.length; i++) { Object obj = nv.get(i, null); if (obj instanceof Number) { result[i] = ((Number) obj).intValue(); } else { result[i] = StringUtils.toInt(StringUtils.toString(obj), 0); } } return result; } /** * RhinoJavaScript??Java * <p> * wraped java object unwrap scriptable object, ? * java object * </p> * * @param jsObj * ??Java * @param context * * @return return ??Javanull */ public static Object jsToJava(Object jsObj) { return jsToJava(jsObj, Context.enter()); } private static Object jsToJava(Object jsObj, Context context) { try { if (jsObj == null || jsObj == Undefined.instance || jsObj == ScriptableObject.NOT_FOUND) return null; if (jsObj instanceof Wrapper) return ((Wrapper) jsObj).unwrap(); // Rhino JavaScript ScriptableObject if (jsObj instanceof ScriptableObject) { final ScriptableObject scriptObj = (ScriptableObject) jsObj; return scriptableToJava(scriptObj, context); } else { // Java Object return jsObj; } } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (NoSuchFieldException e) { throw new RuntimeException(e); } } /** * Scriptable??Java * <p> * ???ArrayMap ??Java?Map * </p> * * @param scriptObj * ??Scriptable * @param context * * @return return ??Java */ @SuppressWarnings({ "rawtypes", "unchecked" }) private static Object scriptableToJava(ScriptableObject scriptObj, Context context) throws IllegalAccessException, NoSuchFieldException { // Array & Arguments if (ScriptRuntime.isArrayObject(scriptObj)) { final Object[] arrayElements = (Object[]) context.getElements(scriptObj); // If scriptObj is a associative arry, arrayElements.length will // always 0 // So if scriptObj is empty or index array, return true, else return // false if (scriptObj.getIds().length == 0 || arrayElements.length == scriptObj.getIds().length) { for (int i = 0; i < arrayElements.length; i++) { arrayElements[i] = jsToJava(arrayElements[i], context); } return arrayElements; } else { final Object[] ids = scriptObj.getIds(); final HashMap map = new HashMap(); for (int i = 0; i < ids.length; i++) { final String key = ids[i].toString(); Object value = scriptObj.get(key, scriptObj); // if value is UniqueTag, means index is numeric, // should get its value by index if (value.getClass().equals(UniqueTag.class)) { value = scriptObj.get(Integer.parseInt(key), scriptObj); } map.put(ids[i], jsToJava(value, context)); } return map; } } else { final String jsClassName = scriptObj.getClassName(); // If jsClassName is 'Object', means scriptObj could't directly // convert to a normal java object, in this case we // return a map contains all properties in this scriptable object. if ("Object".equals(jsClassName)) { final Object[] ids = scriptObj.getIds(); final HashMap map = new HashMap(); for (int i = 0; i < ids.length; i++) { final String key = ids[i].toString(); final Object value = scriptObj.get(key, scriptObj); map.put(key, jsToJava(value, context)); } return map; } // If jsClassName is 'Funtion' & instanceof NativeFunction, // means scriptObj is a function defined in script, // in this case we return a String present source of this function else if ("Function".equals(jsClassName) && scriptObj instanceof NativeFunction) { final NativeFunction func = (NativeFunction) scriptObj; return Decompiler.decompile(func.getEncodedSource(), Decompiler.TO_SOURCE_FLAG, new UintMap()); } // Else, we can covert it to a desired java object by // Context.jsToJava() else { final Class clazz = (Class) ScriptRuntime.class.getDeclaredField(jsClassName + "Class") .get(scriptObj); return Context.jsToJava(scriptObj, clazz); } } } }