Skip to content

Commit

Permalink
support SimpleExpression, e.g. "new org.docksidestage.Sea()" #43
Browse files Browse the repository at this point in the history
  • Loading branch information
jflute committed Sep 27, 2024
1 parent 3ccfd56 commit 9597e8f
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,18 @@ public interface ExpressionPlainHook {
String COLON = ":";
String DQ = "\"";
String SQ = "'";

String EXISTS_BEGIN = LdiResourceUtil.class.getName() + ".exists('";
String EXISTS_END = "')";

String TYPE_BEGIN = "@"; // compatible with OGNL e.g. @org.dbflute.Entity@class, and for minor domain
String TYPE_END = "@"; // me too
String TYPE_END_CLASS = TYPE_END + "class"; // me too

String NEW_PREFIX = "new ";
String METHOD_MARK = "()";
String DQ_NEW_PREFIX = DQ + "new ";
String DQ_METHOD_SUFFIX = "()" + DQ;

// e.g. provider.config().getJdbcUrl()
String PROVIDER_CONFIG = "provider.config()";
Expand All @@ -53,8 +58,14 @@ public interface ExpressionPlainHook {

Object NULL_RETURN = new Object();

// ===================================================================================
// Hook
// ======
Object hookPlainly(String exp, Map<String, ? extends Object> contextMap, LaContainer container, Class<?> resultType);

// ===================================================================================
// for Caller
// ==========
static Object resolveHookedReturn(Object hooked) {
return NULL_RETURN.equals(hooked) ? null : hooked;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ protected boolean isValidHatenaColonElement(String determinationExp, String firs
// ==============
protected Object resolveSimpleString(String exp, LaContainer container, Class<?> resultType) {
if (exp.startsWith(DQ) && exp.endsWith(DQ) && exp.length() > DQ.length()) {
if (mayBeDoubleQuotedStatement(exp)) { // except e.g. "new ...Sea()" @since 1.0.0
return null; // treated as statement (not simple string)
}
final String unquoted = exp.substring(DQ.length(), exp.length() - DQ.length());
if (!unquoted.contains(DQ)) { // simple string e.g. "sea"
return unquoted;
Expand All @@ -189,6 +192,12 @@ protected Object resolveSimpleString(String exp, LaContainer container, Class<?>
return null;
}

protected boolean mayBeDoubleQuotedStatement(String exp) {
// not use resultType determination because of compatible for expected rare cases
// will be incrementaly added if new pattern is found
return isDoubleQuotedNewExp(exp);
}

protected Object resolveSimpleNumber(String exp, LaContainer container, Class<?> resultType) {
if (LdiStringUtil.isNumber(exp)) {
if (exp.length() > 9) {
Expand Down Expand Up @@ -223,7 +232,7 @@ protected Object resolveSimpleEqualEqual(String exp, LaContainer container, Clas
// Simple New
// ==========
protected Object resolveSimpleNewExp(String exp, LaContainer container, Class<?> resultType) { // @since 1.0.0
if (exp.startsWith(NEW_PREFIX) && exp.endsWith(METHOD_MARK)) {
if (canBeSimpleNewExp(exp)) {
final String rear = LdiSrl.substringFirstRear(exp, NEW_PREFIX); // e.g. org.docksidestage.Sea()
final String fqcn = LdiSrl.substringLastFront(rear, METHOD_MARK); // e.g. org.docksidestage.Sea
final Class<Object> clazz;
Expand All @@ -245,25 +254,43 @@ protected Object resolveSimpleNewExp(String exp, LaContainer container, Class<?>
return null;
}

protected boolean canBeSimpleNewExp(String exp) {
if (isPlainNewExp(exp)) { // no quoted
return true;
}
if (mayBeDoubleQuotedStatement(exp)) { // e.g. "new ...Sea()"
return true; // Nashorn treats it as statement
}
return false;
}

protected boolean isPlainNewExp(String exp) {
return exp.startsWith(NEW_PREFIX) && exp.endsWith(METHOD_MARK);
}

protected boolean isDoubleQuotedNewExp(String exp) {
return exp.startsWith(DQ_NEW_PREFIX) && exp.endsWith(DQ_METHOD_SUFFIX);
}

// ===================================================================================
// Simple Type Expression
// ======================
protected Object resolveSimpleTypeExp(String exp, LaContainer container, Class<?> resultType) {
if (exp.startsWith(TYPE_BEGIN) && exp.endsWith(TYPE_END_CLASS)) { // @org.docksidestage.Sea@class
if (exp.startsWith(TYPE_BEGIN) && exp.endsWith(TYPE_END_CLASS)) { // e.g. @org.docksidestage.Sea@class
// mainly for OGNL compatibility
final String className = exp.substring(TYPE_BEGIN.length(), exp.lastIndexOf(TYPE_END_CLASS));
return LdiClassUtil.forName(className);
}
if (exp.startsWith(TYPE_BEGIN) && exp.contains(TYPE_END)) { // @org.docksidestage.Sea@call()
if (exp.startsWith(TYPE_BEGIN) && exp.contains(TYPE_END)) { // e.g. @org.docksidestage.Sea@call() or @FIELD
// minor domain, e.g. jp, cannot be parsed by Nashon so original logic here
final String className = exp.substring(TYPE_BEGIN.length(), exp.lastIndexOf(TYPE_END));
final String rear = exp.substring(exp.lastIndexOf(TYPE_END) + TYPE_END.length());
final Class<?> clazz = LdiClassUtil.forName(className);
if (rear.endsWith(METHOD_MARK)) {
if (rear.endsWith(METHOD_MARK)) { // e.g. @org.docksidestage.Sea@call()
final String methodName = rear.substring(0, rear.lastIndexOf(METHOD_MARK));
final Method method = LdiReflectionUtil.getMethod(clazz, methodName, (Class<?>[]) null);
return LdiReflectionUtil.invoke(method, null, (Object[]) null);
} else {
} else { // e.g. @org.docksidestage.Sea@FIELD
final Field field = LdiReflectionUtil.getField(clazz, rear);
return LdiReflectionUtil.getValue(field, null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Map;

import org.lastaflute.di.core.LaContainer;
import org.lastaflute.di.core.LastaDiProperties;
import org.lastaflute.di.core.meta.impl.LaContainerImpl;
import org.lastaflute.di.unit.UnitLastaDiTestCase;
import org.lastaflute.jta.core.LaTransaction;
Expand All @@ -29,6 +30,26 @@
*/
public class SimpleExpressionPlainHookTest extends UnitLastaDiTestCase {

// ===================================================================================
// Basic Handling
// ==============
public void test_hookPlainly_simpleString_basic() {
// ## Arrange ##
SimpleExpressionPlainHook hook = new SimpleExpressionPlainHook();
String exp = "\"sea\"";
Map<String, Object> contextMap = new HashMap<>();
LaContainer container = createContainer();
Class<?> resultType = Object.class; // unused

// ## Act ##
Object result = hook.hookPlainly(exp, contextMap, container, resultType);

// ## Assert ##
assertNotNull(result);
assertTrue(result instanceof String);
assertEquals("sea", result);
}

// ===================================================================================
// Simple new
// ==========
Expand All @@ -48,6 +69,22 @@ public void test_hookPlainly_simpleNew_basic() {
assertTrue(result instanceof LaTransaction);
}

public void test_hookPlainly_simpleNew_doubleQuoted() {
// ## Arrange ##
SimpleExpressionPlainHook hook = new SimpleExpressionPlainHook();
String exp = "\"new org.lastaflute.jta.core.LaTransaction()\"";
Map<String, Object> contextMap = new HashMap<>();
LaContainer container = createContainer();
Class<?> resultType = Object.class; // unused

// ## Act ##
Object result = hook.hookPlainly(exp, contextMap, container, resultType);

// ## Assert ##
assertNotNull(result);
assertTrue(result instanceof LaTransaction);
}

// ===================================================================================
// Simple Type
// ===========
Expand All @@ -67,6 +104,23 @@ public void test_hookPlainly_simpleType_class_basic() {
assertTrue(LjtTimeoutManager.class.equals(result));
}

public void test_hookPlainly_simpleType_field_basic() {
// ## Arrange ##
SimpleExpressionPlainHook hook = new SimpleExpressionPlainHook();
String exp = "@org.lastaflute.di.core.LastaDiProperties@LASTA_DI_PROPERTIES";
Map<String, Object> contextMap = new HashMap<>();
LaContainer container = createContainer();
Class<?> resultType = Object.class; // unused

// ## Act ##
Object result = hook.hookPlainly(exp, contextMap, container, resultType);

// ## Assert ##
assertNotNull(result);
assertTrue(result instanceof String);
assertEquals(LastaDiProperties.LASTA_DI_PROPERTIES, result);
}

public void test_hookPlainly_simpleType_method_basic() {
// ## Arrange ##
SimpleExpressionPlainHook hook = new SimpleExpressionPlainHook();
Expand Down

0 comments on commit 9597e8f

Please sign in to comment.