package greencode.jscript; import java.util.HashMap; import java.util.Map; import javax.servlet.http.Part; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import greencode.exception.ConnectionLost; import greencode.exception.GreencodeError; import greencode.http.ViewSession; import greencode.jscript.JSExecutor.TYPE; import greencode.jscript.dom.FunctionHandle; import greencode.jscript.dom.Node; import greencode.jscript.dom.Window; import greencode.kernel.Console; import greencode.kernel.DOMScanner; import greencode.kernel.GreenContext; import greencode.util.ClassUtils; import greencode.util.GenericReflection; import greencode.util.LogMessage; public final class DOMHandle { public static enum UIDReference { MAIN_ELEMENT_ID, WINDOW_ID, DOCUMENT_ID, HEAD_ID, BODY_ID; } private DOMHandle() { } public static Integer getUID(DOM d) { return d.uid; } public static Window getWindow(DOM d) { return d.window; } public static void newInstance(DOM owner, String className, Object... parameters) { DOMScanner.registerExecution(new JSExecutor(new DOM[] { owner }, owner.window, className, TYPE.INSTANCE, parameters)); } public static void registerFunctionHandleByCommand(FunctionHandle ret, DOM owner, String name, Object... parameters) { DOMScanner.registerExecution(new JSExecutor(ret, owner, name, parameters)); } public static void registerReturnByVector(Node ret, DOM owner, int index) { DOMScanner.registerExecution(new JSExecutor(new DOM[] { ret }, owner, index + "", TYPE.VECTOR)); } public static void registerReturnByProperty(DOM ret, DOM owner, String name) { DOMScanner.registerExecution(new JSExecutor(new DOM[] { ret }, owner, name, TYPE.PROPERTY)); } public static void registerReturnByCommand(DOM ret, DOM owner, String name, Object... parameters) { DOMScanner.registerExecution(new JSExecutor(new DOM[] { ret }, owner, name, TYPE.METHOD, parameters)); } public static void registerReturnsByCommand(DOM[] rets, DOM owner, String name, Object... parameters) { assert (rets.length < 1); DOMScanner.registerExecution(new JSExecutor(rets, owner, null, name, TYPE.METHOD, parameters)); } public static void execCommand(DOM dom, String methodName, Object... args) { DOMScanner.registerExecution(new JSExecutor(dom, methodName, JSExecutor.TYPE.METHOD, args)); } public static void setProperty(DOM dom, String name, Object value) { dom.variables.put(name, value); DOMScanner.registerExecution(new JSExecutor(dom, name, TYPE.PROPERTY, value)); } public static String getDefaultIdToRegisterReturn(int uid) { return uid + "*ref"; } public static void deleteReference(DOM dom) { deleteReference(dom.window, dom.uid); } public static void deleteReference(Window window, int uid) { DOMHandle.execCommand(window, "Greencode.cache.remove", uid); } @SuppressWarnings("unchecked") public static <C> C getVariableValue(DOM owner, String varName, Class<C> cast) { return (C) owner.variables.get(varName); } public static void setVariableValue(DOM owner, String varName, Object value) { owner.variables.put(varName, value); } public static void removeVariable(DOM owner, String varName) { owner.variables.remove(varName); } public static boolean containVariableKey(DOM owner, String key) { return owner.variables.containsKey(key); } private static Object getSyncValue(GreenContext context, DOM owner, String varName, Class<?> cast, String name, JSExecutor.TYPE type, Object... parameters) { final ViewSession viewSession = owner.viewSession; synchronized (greencode.kernel.$GreenContext.isImmediateSync(context) ? owner : Thread.currentThread()) { JSExecutor jsCommand = new JSExecutor(owner, cast, name, type, parameters); try { greencode.kernel.$DOMScanner.setSync(context, owner.uid, varName, jsCommand); getDOMSync(viewSession).put(owner.uid, owner); Console.log("Synchronizing: [varName=" + varName + ", command={uid=" + owner.uid + ", name=" + name + ", parameters=" + context.gsonInstance.toJson(parameters) + "]"); if (greencode.kernel.$GreenContext.isImmediateSync(context)) { owner.flush(); owner.wait(120000); } } catch (Exception e) { throw new ConnectionLost(LogMessage.getMessage("green-0011")); } } return greencode.kernel.$GreenContext.isImmediateSync(context) ? owner.variables.get(varName) : null; } @SuppressWarnings("unchecked") private static <C> C getVariableValue(final DOM owner, final String varName, Class<C> cast, final String _name, JSExecutor.TYPE type, Object... parameters) { GreenContext context = GreenContext.getInstance(); if ((ClassUtils.isPrimitiveOrWrapper(cast) || ClassUtils.isParent(cast, JsonElement.class)) && (greencode.kernel.$GreenContext.isForcingSynchronization(context, owner, _name) || !owner.variables.containsKey(varName))) { Object v = getSyncValue(context, owner, varName, cast, _name, type, parameters); if (greencode.kernel.$GreenContext.isImmediateSync(context)) { return setVariableValue(context, owner, varName, cast, v); } return null; } return (C) owner.variables.get(varName); } @SuppressWarnings("unchecked") static <C> C setVariableValue(GreenContext context, final DOM owner, final String varName, Class<C> cast, Object v) { if (cast != null && !cast.equals(String.class) && !cast.equals(Part.class)) { if (ClassUtils.isPrimitiveOrWrapper(cast)) { try { v = GenericReflection.getDeclaredMethod(cast, "valueOf", String.class).invoke(null, v); } catch (Exception e) { throw new GreencodeError(e); } } else v = context.gsonInstance.fromJson((String) v, cast); } // Substitua o antigo valor String para o novo valor com o formato // certo. owner.variables.put(varName, v); return (C) v; } static Map<Integer, DOM> getDOMSync(ViewSession viewSession) { @SuppressWarnings("unchecked") Map<Integer, DOM> DOMList = (HashMap<Integer, DOM>) viewSession.getAttribute("DOM_SYNC"); if (DOMList == null) viewSession.setAttribute("DOM_SYNC", DOMList = new HashMap<Integer, DOM>()); return DOMList; } public static <C> C getVariableValueByCommand(DOM owner, String varName, Class<C> cast, String commandName, Object... parameters) { return getVariableValue(owner, varName, cast, commandName, JSExecutor.TYPE.METHOD, parameters); } public static <C> C getVariableValueByProperty(DOM owner, String varName, Class<C> cast, String propName) { return getVariableValue(owner, varName, cast, propName, JSExecutor.TYPE.PROPERTY); } public static <C> C getVariableValueByCommandNoCache(DOM owner, String varName, Class<C> cast, String commandName, Object... parameters) { C v = getVariableValue(owner, varName, cast, commandName, JSExecutor.TYPE.METHOD, parameters); DOMHandle.removeVariable(owner, varName); return v; } public static <C> C getVariableValueByPropertyNoCache(DOM owner, String varName, Class<C> cast, String propName) { C v = getVariableValue(owner, varName, cast, propName, JSExecutor.TYPE.PROPERTY); DOMHandle.removeVariable(owner, varName); return v; } public static JsonObject getJSONObjectByProperty(DOM owner, String varName, String propertyName, String... propertyNames) { return getVariableValue(owner, varName, JsonObject.class, propertyName, JSExecutor.TYPE.PROPERTY, (Object[]) propertyNames); } public static JsonArray getJSONArrayByProperty(DOM owner, String varName, String propertyName, String... propertyNames) { return getVariableValue(owner, varName, JsonArray.class, propertyName, JSExecutor.TYPE.VECTOR, (Object[]) propertyNames); } public static boolean isForcingSynchronization(GreenContext context, final DOM dom, String property) { return greencode.kernel.$GreenContext.isForcingSynchronization(context, dom, property); } }