resolve getters
This commit is contained in:
@@ -9,29 +9,43 @@ import org.objectweb.asm.Opcodes;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.invoke.SerializedLambda;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
@Getter
|
||||
public class AsmParser {
|
||||
private final Serializable lambda;
|
||||
private final Method method;
|
||||
|
||||
public AsmParser(SerializablePredicate<?> predicate) {
|
||||
this.lambda = predicate;
|
||||
this.method = null;
|
||||
}
|
||||
|
||||
public AsmParser(SerializableFunction<?, ?> function) {
|
||||
this.lambda = function;
|
||||
this.method = null;
|
||||
}
|
||||
|
||||
public AsmParser(Method method) {
|
||||
this.lambda = null;
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public AsmParseResult parse() throws AsmParseException {
|
||||
try {
|
||||
return parseExpression();
|
||||
if (this.lambda != null) {
|
||||
return parseLambdaExpression();
|
||||
} else if (this.method != null) {
|
||||
return parseMethodExpression();
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
} catch (Exception e) {
|
||||
throw new AsmParseException("PredicateParser: failed to parse expression: " + e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private AsmParseResult parseExpression() throws Exception {
|
||||
private AsmParseResult parseLambdaExpression() throws Exception {
|
||||
var cls = lambda.getClass();
|
||||
var loader = cls.getClassLoader();
|
||||
InputStream is;
|
||||
@@ -53,4 +67,21 @@ public class AsmParser {
|
||||
|
||||
return visiter.getResult();
|
||||
}
|
||||
|
||||
private AsmParseResult parseMethodExpression() throws Exception {
|
||||
var cls = method.getClass();
|
||||
var loader = cls.getClassLoader();
|
||||
InputStream is = loader.getResourceAsStream(cls.getName().replace(".", "/") + ".class");
|
||||
Object[] args = new Object[0];//TODO capturing args here? or maybe not supported since this will only be user by getter evaluation
|
||||
|
||||
return parseCommon(is, method.getName(), args);
|
||||
}
|
||||
|
||||
private AsmParseResult parseCommon(InputStream classIs, String methodname, Object[] args) throws Exception {
|
||||
var cr = new ClassReader(classIs);
|
||||
var visiter = new FilterClassVisitor(Opcodes.ASM9, methodname, args);
|
||||
cr.accept(visiter, 0);
|
||||
|
||||
return visiter.getResult();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import jef.serializable.SerializableFunction;
|
||||
import jef.serializable.SerializablePredicate;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@Getter
|
||||
public class OptimizedAsmParser extends AsmParser {
|
||||
|
||||
@@ -18,6 +20,10 @@ public class OptimizedAsmParser extends AsmParser {
|
||||
super(function);
|
||||
}
|
||||
|
||||
public OptimizedAsmParser(Method method) {
|
||||
super(method);
|
||||
}
|
||||
|
||||
public AsmParseResult parse() throws AsmParseException {
|
||||
var result = super.parse();
|
||||
var expr = result.getExpression();
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package jef.model;
|
||||
|
||||
import jef.asm.OptimizedAsmParser;
|
||||
import jef.model.annotations.ForeignKey;
|
||||
import jef.serializable.SerializableObject;
|
||||
import jef.util.Util;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@@ -31,26 +33,34 @@ class ForeignKeyExposeInitializer {//TODO testcases for this class
|
||||
if (anno.entity() != SerializableObject.class) { // not a foreign key exposure
|
||||
return false;
|
||||
}
|
||||
return f.getField().getName().equals(anno.getterOrField());//TODO support getters
|
||||
var fieldname = anno.getterOrField(); //TODO test
|
||||
|
||||
//if getter, extract getter field
|
||||
var method = Util.tryGet(() -> entityBuilder.type().orElseThrow().getMethod(anno.getterOrField())); //TODO test
|
||||
if (method.isPresent()) {
|
||||
var res = new OptimizedAsmParser(method.get()).parse();
|
||||
fieldname = res.getAccessedFields().stream().findFirst().orElseThrow().getName();
|
||||
}
|
||||
return f.getField().getName().equals(fieldname);
|
||||
}
|
||||
//only allow fields with same prefix
|
||||
if (!e.getField().getName().startsWith(f.getField().getName())) {
|
||||
return false;
|
||||
}
|
||||
//match id field which ends in Id or Fk
|
||||
if (e.getField().getName().equals(f.getField().getName() + "Id")
|
||||
|| e.getField().getName().equals(f.getField().getName() + "ID")
|
||||
|| e.getField().getName().equals(f.getField().getName() + "Fk")
|
||||
|| e.getField().getName().equals(f.getField().getName() + "FK")) {
|
||||
if (e.getField().getName().equals(f.getField().getName() + "Id") //TODO test
|
||||
|| e.getField().getName().equals(f.getField().getName() + "ID") //TODO test
|
||||
|| e.getField().getName().equals(f.getField().getName() + "Fk") //TODO test
|
||||
|| e.getField().getName().equals(f.getField().getName() + "FK")) { //TODO test
|
||||
return true;
|
||||
}
|
||||
//match id field which ends in the name of the primary key field of the referenced entity
|
||||
var other = mb.getEntity(f.getField().getTypeName());
|
||||
var other = mb.getEntity(f.getField().getTypeName()); //TODO test
|
||||
if (other == null || other.getPrimaryKey() == null) {
|
||||
return false;
|
||||
}
|
||||
//assumption: initializing from models only has primary keys with 1 field (no composite keys)
|
||||
var x = other.getPrimaryKey().getFields().get(0).getName();
|
||||
var x = other.getPrimaryKey().getFields().get(0).getName(); //TODO test
|
||||
x = x.substring(0, 1).toUpperCase(Locale.ROOT) + x.substring(1);
|
||||
return e.getField().getName().equals(f.getField().getName() + x);
|
||||
}).toList();
|
||||
|
||||
Reference in New Issue
Block a user