OPENJPA-2911 streamline validateProperties
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
index c644c09..ff74358 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
@@ -598,7 +598,6 @@
_log.trace(_loc.get("enhance-start", type));
}
- pc = AsmHelper.toClassNode(_pc);
configureBCs();
@@ -606,6 +605,7 @@
// we build up a record of backing fields, etc
if (isPropertyAccess(_meta)) {
validateProperties();
+ AsmHelper.readIntoBCClass(pc, _pc);
if (getCreateSubclass()) {
addAttributeTranslation();
}
@@ -643,7 +643,6 @@
}
private void configureBCs() {
- final ClassNode classNode = pc.getClassNode();
if (!_bcsConfigured) {
if (getRedefine()) {
if (_managedType.getAttribute(REDEFINED_ATTRIBUTE) == null) {
@@ -655,7 +654,7 @@
}
if (getCreateSubclass()) {
- PCSubclassValidator val = new PCSubclassValidator(_meta, classNode, _log, _fail);
+ PCSubclassValidator val = new PCSubclassValidator(_meta, managedType.getClassNode(), _log, _fail);
val.assertCanSubclass();
_pc = _managedType.getProject().loadClass(toPCSubclassName(_managedType.getType()));
@@ -669,6 +668,7 @@
else {
_isAlreadySubclassed = true;
}
+ pc = AsmHelper.toClassNode(_pc);
}
_bcsConfigured = true;
@@ -727,7 +727,7 @@
* property's backing field.
*/
private void validateProperties() {
- final ClassNode classNode = pc.getClassNode();
+ final ClassNode classNode = managedType.getClassNode();
FieldMetaData[] fmds;
if (getCreateSubclass()) {
fmds = _meta.getFields();
@@ -735,16 +735,11 @@
else {
fmds = _meta.getDeclaredFields();
}
- Method meth;
-
- BCMethod bcGetter, bcSetter;
- BCField bcReturned = null;
Method getter, setter;
Field returned, assigned = null;
for (FieldMetaData fmd : fmds) {
-
if (!(fmd.getBackingMember() instanceof Method)) {
// If not mixed access is not defined, flag the field members,
// otherwise do not process them because they are valid
@@ -757,19 +752,13 @@
continue;
}
- meth = (Method) fmd.getBackingMember();
+ getter = (Method) fmd.getBackingMember();
- // ##### this will fail if we override and don't call super.
- BCClass declaringType = _managedType.getProject()
- .loadClass(fmd.getDeclaringType());
- bcGetter = declaringType.getDeclaredMethod(meth.getName(),
- meth.getParameterTypes());
- if (bcGetter == null) {
+ if (getter == null) {
addViolation("property-no-getter", new Object[]{fmd},
true);
continue;
}
- getter = meth;
returned = getReturnedField(classNode, getter);
@@ -777,7 +766,7 @@
registerBackingFieldInfo(fmd, getter, returned);
}
- setter = getMethod(meth.getDeclaringClass(), getSetterName(fmd), fmd.getDeclaredType());
+ setter = getMethod(getter.getDeclaringClass(), getSetterName(fmd), fmd.getDeclaredType());
if (setter == null) {
if (returned == null) {
@@ -948,9 +937,7 @@
return null;
}
- final MethodNode methodNode = classNode.methods.stream()
- .filter(mn -> mn.name.equals(meth.getName()) && mn.desc.equals(Type.getMethodDescriptor(meth)))
- .findAny().get();
+ final MethodNode methodNode = findMethodNode(classNode, meth);
Field field = null;
Field cur;
@@ -1015,6 +1002,14 @@
return field;
}
+ private static MethodNode findMethodNode(ClassNode classNode, Method meth) {
+ final MethodNode methodNode = classNode.methods.stream()
+ .filter(mn -> mn.name.equals(meth.getName()) && mn.desc.equals(Type.getMethodDescriptor(meth)))
+ .findAny().get();
+ return methodNode;
+ }
+
+
private static Field getField(Class<?> clazz, String fieldName) {
try {
return clazz.getDeclaredField(fieldName);
@@ -1027,6 +1022,42 @@
}
}
+ /**
+ * get the Method with the given methodName and params from the given classNode or clazz
+ * @param classNodeTracker
+ * @param methodName
+ */
+ private static MethodNode getMethod(ClassNodeTracker classNodeTracker, String methodName, Class<?> returnType, Class<?>... paramTypes) {
+ Type[] parms = Arrays.stream(paramTypes)
+ .map(c -> Type.getType(c))
+ .toArray(Type[]::new);
+
+ String methodDescription = Type.getMethodDescriptor(Type.getType(returnType), parms);
+
+ final Optional<MethodNode> methodNode = classNodeTracker.getClassNode().methods.stream()
+ .filter(mn -> mn.name.equals(methodName) && mn.desc.equals(methodDescription))
+ .findAny();
+ if (methodNode.isPresent()) {
+ return methodNode.get();
+ }
+
+ // otherwise look up the parent class hierarchy
+ final String superName = classNodeTracker.getClassNode().superName;
+ if (superName == null || superName.equals("java/lang/Object")) {
+ // no need to dig further
+ return null;
+ }
+ try {
+ final Class<?> parentClass = classNodeTracker.getClassLoader().loadClass(superName.replace("/", "."));
+ Method m = getMethod(parentClass, methodName, paramTypes);
+ return new MethodNode(m.getModifiers(), m.getName(), Type.getMethodDescriptor(m), null, null);
+ }
+ catch (ClassNotFoundException e) {
+ throw new RuntimeException("Illegal superclass in ClassNode " + classNodeTracker.getClassNode().name, e);
+ }
+
+ }
+
private static Method getMethod(Class<?> clazz, String methodName, Class<?>... paramTypes) {
try {
return clazz.getDeclaredMethod(methodName, paramTypes);