mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
Add convertObjectToJava to code executors - for converting language objects to java objects
This commit is contained in:
@ -27,6 +27,10 @@ import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.kingsrook.qqq.backend.core.actions.scripts.QCodeExecutor;
|
||||
import com.kingsrook.qqq.backend.core.actions.scripts.logging.QCodeExecutionLoggerInterface;
|
||||
@ -36,8 +40,10 @@ import com.kingsrook.qqq.backend.core.utils.ExceptionUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||
import org.apache.commons.lang.NotImplementedException;
|
||||
import org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory;
|
||||
import org.openjdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import org.openjdk.nashorn.internal.runtime.ECMAException;
|
||||
import org.openjdk.nashorn.internal.runtime.ParserException;
|
||||
import org.openjdk.nashorn.internal.runtime.Undefined;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -59,6 +65,59 @@ public class QJavaScriptExecutor implements QCodeExecutor
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public Object convertObjectToJava(Object object)
|
||||
{
|
||||
if(object == null || object instanceof String || object instanceof Boolean || object instanceof Integer || object instanceof Long || object instanceof BigDecimal)
|
||||
{
|
||||
return (object);
|
||||
}
|
||||
else if(object instanceof Float f)
|
||||
{
|
||||
return (new BigDecimal(f));
|
||||
}
|
||||
else if(object instanceof Double d)
|
||||
{
|
||||
return (new BigDecimal(d));
|
||||
}
|
||||
else if(object instanceof Undefined)
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// well, we always said we wanted javascript to treat null & undefined the same way... here's our chance //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
return (null);
|
||||
}
|
||||
|
||||
if(object instanceof ScriptObjectMirror scriptObjectMirror)
|
||||
{
|
||||
if(scriptObjectMirror.isArray())
|
||||
{
|
||||
List<Object> result = new ArrayList<>();
|
||||
for(String key : scriptObjectMirror.keySet())
|
||||
{
|
||||
result.add(Integer.parseInt(key), convertObjectToJava(scriptObjectMirror.get(key)));
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
else
|
||||
{
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
for(String key : scriptObjectMirror.keySet())
|
||||
{
|
||||
result.put(key, convertObjectToJava(scriptObjectMirror.get(key)));
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
|
||||
return QCodeExecutor.super.convertObjectToJava(object);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
@ -23,7 +23,12 @@ package com.kingsrook.qqq.languages.javascript;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.kingsrook.qqq.backend.core.actions.scripts.ExecuteCodeAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.scripts.QCodeExecutor;
|
||||
import com.kingsrook.qqq.backend.core.actions.scripts.QCodeExecutorAware;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QCodeException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.scripts.ExecuteCodeInput;
|
||||
@ -31,6 +36,7 @@ import com.kingsrook.qqq.backend.core.model.actions.scripts.ExecuteCodeOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeType;
|
||||
import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
|
||||
@ -241,10 +247,50 @@ class ExecuteCodeActionTest extends BaseTest
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testConvertObjectToJava() throws QException
|
||||
{
|
||||
TestQCodeExecutorAware converter = new TestQCodeExecutorAware();
|
||||
testOne(1, """
|
||||
converter.convertObject("one", 1);
|
||||
converter.convertObject("two", "two");
|
||||
converter.convertObject("true", true);
|
||||
converter.convertObject("null", null);
|
||||
converter.convertObject("undefined", undefined);
|
||||
converter.convertObject("flatMap", {"a": 1, "b": "c"});
|
||||
converter.convertObject("flatList", ["a", 1, "b", "c"]);
|
||||
converter.convertObject("mixedMap", {"a": [1, {"2": "3"}], "b": {"c": ["d"]}});
|
||||
""", MapBuilder.of("converter", converter));
|
||||
|
||||
assertEquals(1, converter.getConvertedObject("one"));
|
||||
assertEquals("two", converter.getConvertedObject("two"));
|
||||
assertEquals(true, converter.getConvertedObject("true"));
|
||||
assertNull(converter.getConvertedObject("null"));
|
||||
assertNull(converter.getConvertedObject("undefined"));
|
||||
assertEquals(Map.of("a", 1, "b", "c"), converter.getConvertedObject("flatMap"));
|
||||
assertEquals(List.of("a", 1, "b", "c"), converter.getConvertedObject("flatList"));
|
||||
assertEquals(Map.of("a", List.of(1, Map.of("2", "3")), "b", Map.of("c", List.of("d"))), converter.getConvertedObject("mixedMap"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private OneTestOutput testOne(Integer inputValueC, String code) throws QException
|
||||
{
|
||||
return (testOne(inputValueC, code, null));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private OneTestOutput testOne(Integer inputValueC, String code, Map<String, Serializable> additionalContext) throws QException
|
||||
{
|
||||
System.out.println();
|
||||
QInstance instance = TestUtils.defineInstance();
|
||||
@ -259,6 +305,14 @@ class ExecuteCodeActionTest extends BaseTest
|
||||
input.withContext("input", testInput);
|
||||
input.withContext("output", testOutput);
|
||||
|
||||
if(additionalContext != null)
|
||||
{
|
||||
for(Map.Entry<String, Serializable> entry : additionalContext.entrySet())
|
||||
{
|
||||
input.withContext(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
ExecuteCodeOutput output = new ExecuteCodeOutput();
|
||||
|
||||
ExecuteCodeAction executeCodeAction = new ExecuteCodeAction();
|
||||
@ -269,6 +323,49 @@ class ExecuteCodeActionTest extends BaseTest
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static class TestQCodeExecutorAware implements QCodeExecutorAware, Serializable
|
||||
{
|
||||
private QCodeExecutor qCodeExecutor;
|
||||
|
||||
private Map<String, Object> convertedObjectMap = new HashMap<>();
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void setQCodeExecutor(QCodeExecutor qCodeExecutor)
|
||||
{
|
||||
this.qCodeExecutor = qCodeExecutor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void convertObject(String name, Object inputObject)
|
||||
{
|
||||
convertedObjectMap.put(name, qCodeExecutor.convertObjectToJava(inputObject));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Object getConvertedObject(String name)
|
||||
{
|
||||
return (convertedObjectMap.get(name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
Reference in New Issue
Block a user