/*******************************************************************************
* Copyright (c) 2011-2014 Fernando Petrola
*
* This file is part of Dragome SDK.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
******************************************************************************/
package com.dragome.web.debugging;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.dragome.commons.javascript.ScriptHelperInterface;
import com.dragome.services.interfaces.ServiceFactory;
import com.dragome.web.debugging.interfaces.CrossExecutionCommandProcessor;
import com.dragome.web.debugging.interfaces.CrossExecutionResult;
import com.dragome.web.enhancers.jsdelegate.JsCast;
public class RemoteScriptHelper implements ScriptHelperInterface
{
private static final String SCRIPTHELPER_METHOD_NAME= "scripthelper-method-name";
protected CrossExecutionCommandProcessor crossExecutionCommandProcessor;
public RemoteScriptHelper(ServiceFactory remoteObjectsService)
{
crossExecutionCommandProcessor= remoteObjectsService.createFixedSyncService(CrossExecutionCommandProcessor.class);
}
public void put(String name, double value, Object caller)
{
String methodName= getMethodName();
crossExecutionCommandProcessor.processNoResult(new JsVariableCreationInMethod(new ReferenceHolder(caller), name, new ReferenceHolder(Math.round(value) + ""), methodName));
}
private String getMethodName()
{
String methodName= System.getProperty(SCRIPTHELPER_METHOD_NAME);
if (methodName == null)
{
StackTraceElement[] stackTrace= Thread.currentThread().getStackTrace();
StackTraceElement stackTraceElement= stackTrace[4];
methodName= stackTraceElement.getMethodName();
}
return methodName;
}
public void put(String name, boolean value, Object caller)
{
String methodName= getMethodName();
crossExecutionCommandProcessor.processNoResult(new JsVariableCreationInMethod(new ReferenceHolder(caller), name, new ReferenceHolder(value), methodName));
}
public void put(String name, Object value, Object caller)
{
String methodName= getMethodName();
crossExecutionCommandProcessor.processNoResult(new JsVariableCreationInMethod(new ReferenceHolder(caller), name, new ReferenceHolder(value), methodName));
}
public long evalLong(String jsCode, Object caller)
{
return evalInt(jsCode, caller);
}
public int evalInt(String script, Object caller)
{
String methodName= getMethodName();
CrossExecutionResult crossExecutionResult= crossExecutionCommandProcessor.process(new JsEvalIntegerInMethod(new ReferenceHolder(caller), script, methodName));
return Integer.parseInt(crossExecutionResult.getResult() + "");
}
public float evalFloat(String jsCode, Object caller)
{
return evalInt(jsCode, caller);
}
public double evalDouble(String jsCode, Object caller)
{
return evalFloat(jsCode, caller);
}
public char evalChar(String jsCode, Object caller)
{
return eval(jsCode, caller).toString().charAt(0);
}
public boolean evalBoolean(String script, Object caller)
{
String methodName= getMethodName();
CrossExecutionResult crossExecutionResult= crossExecutionCommandProcessor.process(new JsEvalBooleanInMethod(new ReferenceHolder(caller), script, methodName));
return Boolean.parseBoolean(crossExecutionResult.getResult() + "");
}
public Object eval(String script, Object caller)
{
Object result;
String methodName= getMethodName();
CrossExecutionResult crossExecutionResult= crossExecutionCommandProcessor.process(new JsEvalInMethod(new ReferenceHolder(caller), script, methodName));
String stringResult= crossExecutionResult.getResult();
if (stringResult.startsWith("js-ref:"))
if (stringResult.equals("js-ref:0"))
result= null;
else
result= new JavascriptReference(stringResult.substring("js-ref".length() + 1));
else
result= stringResult;
return result;
}
public void evalNoResult(String script, Object caller)
{
String methodName= getMethodName();
crossExecutionCommandProcessor.processNoResult(new JsEvalInMethod(new ReferenceHolder(caller), script, methodName));
}
@SuppressWarnings("unchecked")
public <T> T putMethodReference(final String name, final Class<? extends T> declaringClass, final Object callerInstance)
{
final String methodName= getMethodName();
Class[] interfaces= declaringClass.isInterface() ? new Class[] { declaringClass } : declaringClass.getInterfaces();
return (T) Proxy.newProxyInstance(getClass().getClassLoader(), interfaces, new InvocationHandler()
{
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
crossExecutionCommandProcessor.processNoResult(new JsMethodReferenceCreationInMethod(new ReferenceHolder(callerInstance), name, method.getName(), methodName, declaringClass.getName()));
return null;
}
});
}
public <T> T evalCasting(String script, Class<? extends T> castType, Object callerInstance)
{
System.setProperty(SCRIPTHELPER_METHOD_NAME, getMethodName());
Object result= eval(script, callerInstance);
T castTo= JsCast.castTo(result, castType, callerInstance);
System.clearProperty(SCRIPTHELPER_METHOD_NAME);
return castTo;
}
}