/* * Copyright (C) 2000 - 2011 TagServlet Ltd * * This file is part of Open BlueDragon (OpenBD) CFML Server Engine. * * OpenBD is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * Free Software Foundation,version 3. * * OpenBD 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 OpenBD. If not, see http://www.gnu.org/licenses/ * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining * it with any of the JARS listed in the README.txt (or a modified version of * (that library), containing parts covered by the terms of that JAR, the * licensors of this Program grant you additional permission to convey the * resulting work. * README.txt @ http://www.openbluedragon.org/license/README.txt * * http://www.openbluedragon.org/ * $Id: convert.java 2374 2013-06-10 22:14:24Z alan $ */ package org.alanwilliamson.lang.javascript; import java.util.HashMap; import org.m0zilla.javascript.Context; import org.m0zilla.javascript.Function; import org.m0zilla.javascript.FunctionObject; import org.m0zilla.javascript.IdScriptableObject; import org.m0zilla.javascript.NativeArray; import org.m0zilla.javascript.NativeObject; import org.m0zilla.javascript.Scriptable; import org.m0zilla.javascript.ScriptableObject; import org.m0zilla.javascript.Synchronizer; import com.naryx.tagfusion.cfm.engine.cfArrayData; import com.naryx.tagfusion.cfm.engine.cfComponentData; import com.naryx.tagfusion.cfm.engine.cfData; import com.naryx.tagfusion.cfm.engine.cfNullData; import com.naryx.tagfusion.cfm.engine.cfQueryResultData; import com.naryx.tagfusion.cfm.engine.cfSession; import com.naryx.tagfusion.cfm.engine.cfStructData; import com.naryx.tagfusion.cfm.file.cfFile; import com.naryx.tagfusion.cfm.tag.tagUtils; public class convert extends Object { public static Context getJavaScriptContextForSession(cfSession _Session, HashMap<String, JavascriptDefinedFunction> functions ) throws Exception { Context cx = (Context) _Session.getDataBin("jscontext"); if (cx == null) { cx = Context.enter(); cx.setOptimizationLevel(-1); cx.getWrapFactory().setJavaPrimitiveWrap(false); Scriptable scope = cx.initStandardObjects(); /* Setup the properties that we will let the JS block get at */ ScriptableObject.putProperty(scope, "$cf", Context.javaToJS(new cfmlBridge(_Session, functions), scope)); ScriptableObject.putProperty(scope, "variables", convert.cfDataConvert(_Session.getData("variables"))); ScriptableObject.putProperty(scope, "cgi", convert.cfDataConvert(_Session.getData("cgi"))); ScriptableObject.putProperty(scope, "form", convert.cfDataConvert(_Session.getData("form"))); ScriptableObject.putProperty(scope, "url", convert.cfDataConvert(_Session.getData("url"))); ScriptableObject.putProperty(scope, "application", convert.cfDataConvert(_Session.getData("application"))); ScriptableObject.putProperty(scope, "session", convert.cfDataConvert(_Session.getData("session"))); ScriptableObject.putProperty(scope, "client", convert.cfDataConvert(_Session.getData("client"))); /* Add in the Global methods load, sync, print */ Class[] signature = new Class[] {Context.class,Scriptable.class,Object[].class,Function.class}; FunctionObject f = new FunctionObject( "print", convert.class.getMethod("print", signature ), scope ); ScriptableObject.defineProperty(scope, "print", f, ScriptableObject.DONTENUM); f = new FunctionObject( "console", convert.class.getMethod("console", signature ), scope ); ScriptableObject.defineProperty(scope, "console", f, ScriptableObject.DONTENUM); f = new FunctionObject( "load", convert.class.getMethod("load", signature ), scope ); ScriptableObject.defineProperty(scope, "load", f, ScriptableObject.DONTENUM); f = new FunctionObject( "sync", convert.class.getMethod("sync", signature ), scope ); ScriptableObject.defineProperty(scope, "sync", f, ScriptableObject.DONTENUM); /* Execute the script block */ cx.putThreadLocal("scope", scope); cx.putThreadLocal("cfsession", _Session); _Session.setDataBin("jscontext", cx); } return cx; } public static Object sync(Context cx, Scriptable thisObj, Object[] args, Function funObj) throws Exception { if (args.length == 1 && args[0] instanceof Function) { return new Synchronizer((Function) args[0]); } else { throw new Exception("msg.sync.args"); } } public static Object load( Context cx, Scriptable thisObj, Object[] args, Function funObj) throws Exception { for (int i = 0; i < args.length; i++) { String filePath = Context.toString(args[i]); cfSession thisSession = (cfSession)cx.getThreadLocal("cfsession"); cfFile file = thisSession.getRealFile( filePath ); ScriptFactory.getScript( filePath, file.getFileBody()).exec(cx, (Scriptable) cx.getThreadLocal("scope")); } return Context.getUndefinedValue(); } public static Object print( Context cx, Scriptable thisObj, Object[] args, Function funObj){ cfSession thisSession = (cfSession)cx.getThreadLocal("cfsession"); thisSession.forceWrite( String.valueOf(args[0]) ); return Context.getUndefinedValue(); } public static Object console( Context cx, Scriptable thisObj, Object[] args, Function funObj){ System.out.println( args[0] ); return Context.getUndefinedValue(); } /* * Converts Javascript NativeObject into CFML; recursive call */ public static cfData jsConvert2cfData(IdScriptableObject obj) throws Exception { if (obj instanceof NativeObject) { cfStructData struct = new cfStructData(); NativeObject nobj = (NativeObject) obj; Object[] elements = nobj.getAllIds(); cfData cfdata; for (int x = 0; x < elements.length; x++) { Object jsObj = nobj.get(elements[x]); if (jsObj == null) cfdata = cfNullData.NULL; else if (jsObj instanceof NativeObject || jsObj instanceof NativeArray) cfdata = jsConvert2cfData((IdScriptableObject) jsObj); else if (jsObj instanceof cfData) cfdata = (cfData) jsObj; else cfdata = tagUtils.convertToCfData(jsObj); /* check for null; it may be intentional */ if (cfdata == null) cfdata = cfNullData.NULL; struct.setData((String) elements[x], cfdata); } return struct; } else if (obj instanceof NativeArray) { cfArrayData array = cfArrayData.createArray(1); NativeArray nobj = (NativeArray) obj; cfData cfdata; int len = (int) nobj.getLength(); for (int x = 0; x < len; x++) { Object jsObj = nobj.get(x); if (jsObj == null) cfdata = cfNullData.NULL; else if (jsObj instanceof NativeObject || jsObj instanceof NativeArray) cfdata = jsConvert2cfData((IdScriptableObject) jsObj); else if (jsObj instanceof cfData) cfdata = (cfData) jsObj; else cfdata = tagUtils.convertToCfData(jsObj); /* check for null; it may be intentional */ if (cfdata == null) cfdata = cfNullData.NULL; array.addElement(cfdata); } return array; } else { return null; } } /* * Takes a CFML object -> Java */ public static Object cfDataConvert(cfData data) throws Exception { if (data == null) { return null; } else if (data.getDataType() == cfData.CFSTRINGDATA) return data.getString(); else if (data.getDataType() == cfData.CFBOOLEANDATA) return data.getBoolean(); else if (data.getDataType() == cfData.CFSTRUCTDATA) return new cfStructDataScriptableObject((cfStructData) data); else if (data.getDataType() == cfData.CFARRAYDATA) return new cfArrayDataScriptableObject((cfArrayData) data); else if (data.getDataType() == cfData.CFCOMPONENTOBJECTDATA) return new cfComponentDataScriptableObject((cfComponentData) data); else if (data.getDataType() == cfData.CFQUERYRESULTDATA) return new cfQueryDataScriptableObject((cfQueryResultData) data); else if (data.getDataType() == cfData.CFNUMBERDATA) { String tmp = data.getString(); if (tmp.lastIndexOf(".") == -1) return Long.valueOf(tmp); else return Double.valueOf(tmp); } else return data.getString(); } }