You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by st...@apache.org on 2023/05/06 07:18:37 UTC
[openjpa] 12/17: OPENJPA-2909 more proxy generator fixes
This is an automated email from the ASF dual-hosted git repository.
struberg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openjpa.git
commit ec946b6789184a3be7ffe7d18f59bcac4238e08e
Author: Mark Struberg <st...@apache.org>
AuthorDate: Thu May 4 12:13:08 2023 +0200
OPENJPA-2909 more proxy generator fixes
---
.../org/apache/openjpa/util/ProxyManagerImpl.java | 153 ++++++++++++++++++++-
1 file changed, 152 insertions(+), 1 deletion(-)
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java
index 32d541d68..1c4e4e498 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java
@@ -747,7 +747,7 @@ public class ProxyManagerImpl
delegateConstructors(ct, type, superClassFileNname);
addInstanceVariables(ct);
addProxyMethods(ct, false, proxyClassDef, type);
- addProxyCollectionMethods(ct, proxyClassDef, type);
+ addProxyMapMethods(ct, proxyClassDef, type);
proxyRecognizedMethods(ct, proxyClassDef, type, ProxyMaps.class, ProxyMap.class);
proxySetters(ct, proxyClassDef, type);
addWriteReplaceMethod(ct, proxyClassDef, runtime);
@@ -1028,6 +1028,157 @@ public class ProxyManagerImpl
}
}
+
+ private void addProxyMapMethods(ClassWriterTracker ct, String proxyClassDef, Class type) {
+ // change tracker
+ {
+ ct.getCw().visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_TRANSIENT,
+ "changeTracker", Type.getDescriptor(MapChangeTracker.class), null, null).visitEnd();
+ MethodVisitor mv = ct.visitMethod(Modifier.PUBLIC, "getChangeTracker",
+ Type.getMethodDescriptor(Type.getType(ChangeTracker.class))
+ , null, null);
+ mv.visitCode();
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(Opcodes.GETFIELD, proxyClassDef, "changeTracker", Type.getDescriptor(MapChangeTracker.class));
+
+ mv.visitInsn(Opcodes.ARETURN);
+ mv.visitMaxs(-1, -1);
+ mv.visitEnd();
+ }
+
+ // Map copy
+ {
+ Constructor cons = findCopyConstructor(type);
+ if (cons == null && SortedMap.class.isAssignableFrom(type)) {
+ cons = findComparatorConstructor(type);
+ }
+ Class[] params = (cons == null) ? new Class[0]
+ : cons.getParameterTypes();
+
+ MethodVisitor mv = ct.visitMethod(Modifier.PUBLIC, "copy",
+ Type.getMethodDescriptor(TYPE_OBJECT, TYPE_OBJECT)
+ , null, null);
+ mv.visitCode();
+ mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(type));
+ mv.visitInsn(Opcodes.DUP);
+
+ if (params.length == 1) {
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ if (params[0] == Comparator.class) {
+ mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(SortedMap.class));
+ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(SortedMap.class), "comparator",
+ Type.getMethodDescriptor(Type.getType(Comparator.class)), true);
+ }
+ else {
+ // otherwise just pass the parameter
+ mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(params[0]));
+ }
+ }
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(type), "<init>",
+ Type.getMethodDescriptor(Type.VOID_TYPE, AsmHelper.getParamTypes(params)), false);
+
+ if (params.length == 0 || params[0] == Comparator.class) {
+ mv.visitInsn(Opcodes.DUP);
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(Collection.class));
+ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(type), "putAll",
+ Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.getType(Map.class)), false);
+ mv.visitInsn(Opcodes.POP);
+ }
+
+ mv.visitInsn(Opcodes.ARETURN);
+ mv.visitMaxs(-1, -1);
+ mv.visitEnd();
+ }
+
+ // key type
+ {
+ ct.getCw().visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_TRANSIENT,
+ "keyType", Type.getDescriptor(Class.class), null, null).visitEnd();
+
+ MethodVisitor mv = ct.visitMethod(Modifier.PUBLIC, "getKeyType",
+ Type.getMethodDescriptor(Type.getType(Class.class))
+ , null, null);
+ mv.visitCode();
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(Opcodes.GETFIELD, proxyClassDef, "keyType", Type.getDescriptor(Class.class));
+
+ mv.visitInsn(Opcodes.ARETURN);
+ mv.visitMaxs(-1, -1);
+ mv.visitEnd();
+ }
+
+ // value type
+ {
+ ct.getCw().visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_TRANSIENT,
+ "valueType", Type.getDescriptor(Class.class), null, null).visitEnd();
+
+ MethodVisitor mv = ct.visitMethod(Modifier.PUBLIC, "getValueType",
+ Type.getMethodDescriptor(Type.getType(Class.class))
+ , null, null);
+ mv.visitCode();
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(Opcodes.GETFIELD, proxyClassDef, "valueType", Type.getDescriptor(Class.class));
+
+ mv.visitInsn(Opcodes.ARETURN);
+ mv.visitMaxs(-1, -1);
+ mv.visitEnd();
+ }
+
+ // new instance factory
+ {
+ MethodVisitor mv = ct.visitMethod(Modifier.PUBLIC, "newInstance",
+ Type.getMethodDescriptor(Type.getType(ProxyMap.class),
+ Type.getType(Class.class), Type.getType(Class.class), Type.getType(Comparator.class),
+ Type.BOOLEAN_TYPE, Type.BOOLEAN_TYPE)
+ , null, null);
+ mv.visitCode();
+ mv.visitTypeInsn(Opcodes.NEW, proxyClassDef);
+ mv.visitInsn(Opcodes.DUP);
+
+ Constructor cons = findComparatorConstructor(type);
+ Class[] params = (cons == null) ? new Class[0] : cons.getParameterTypes();
+ if (params.length == 1) {
+ mv.visitVarInsn(Opcodes.ALOAD, 3);
+ }
+
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, proxyClassDef, "<init>",
+ Type.getMethodDescriptor(Type.VOID_TYPE, AsmHelper.getParamTypes(params)), false);
+
+ mv.visitVarInsn(Opcodes.ASTORE, 6);
+ mv.visitVarInsn(Opcodes.ALOAD, 6);
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitFieldInsn(Opcodes.PUTFIELD, proxyClassDef, "keyType", Type.getDescriptor(Class.class));
+
+ mv.visitVarInsn(Opcodes.ALOAD, 6);
+ mv.visitVarInsn(Opcodes.ALOAD, 2);
+ mv.visitFieldInsn(Opcodes.PUTFIELD, proxyClassDef, "valueType", Type.getDescriptor(Class.class));
+
+ mv.visitVarInsn(Opcodes.ILOAD, 4);
+ Label lNotTrack = new Label();
+ mv.visitJumpInsn(Opcodes.IFEQ, lNotTrack);
+ mv.visitVarInsn(Opcodes.ALOAD, 6);
+ mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(MapChangeTrackerImpl.class));
+
+ mv.visitInsn(Opcodes.DUP);
+ mv.visitVarInsn(Opcodes.ALOAD, 6);
+
+ mv.visitVarInsn(Opcodes.ILOAD, 5);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(MapChangeTrackerImpl.class), "<init>",
+ Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Map.class), Type.BOOLEAN_TYPE),
+ false);
+ mv.visitFieldInsn(Opcodes.PUTFIELD, proxyClassDef, "changeTracker", Type.getDescriptor(MapChangeTracker.class));
+
+ mv.visitLabel(lNotTrack);
+ mv.visitVarInsn(Opcodes.ALOAD, 6);
+
+ mv.visitInsn(Opcodes.ARETURN);
+ mv.visitMaxs(-1, -1);
+ mv.visitEnd();
+ }
+ }
+
+
private void proxyRecognizedMethods(ClassWriterTracker ct, String proxyClassDef, Class<?> type,
Class<?> helper, Class<?> proxyType) {
Method[] meths = type.getMethods();