public static <S> byte[] createInstantiator(final String className, final Class<?> sourceClass, final ExecutableInstantiatorDefinition instantiatorDefinition, final Map<Parameter, Getter<? super S, ?>> injections) throws Exception { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); Class<?> targetClass= TypeHelper.toClass(BiInstantiatorBuilder.getTargetType(instantiatorDefinition)); String targetType = AsmUtils.toAsmType(targetClass); String sourceType = AsmUtils.toWrapperType(sourceClass); String classType = AsmUtils.toAsmType(className); String instantiatorType = AsmUtils.toAsmType(Instantiator.class); cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, classType, "Ljava/lang/Object;L" + instantiatorType + "<L" + targetType + ";>;", "java/lang/Object", new String[] { instantiatorType }); Parameter[] parameters = instantiatorDefinition.getParameters(); appendGetters(injections, cw); appendInit(injections, cw, sourceType, classType); appendNewInstanceBuilderOnMethod(sourceClass, instantiatorDefinition, injections, cw, targetType, sourceType, classType, parameters); appendBridgeMethod(cw, targetType, sourceType, classType); appendToString(injections, cw, parameters); cw.visitEnd(); return AsmUtils.writeClassToFile(className, cw.toByteArray()); }
@SuppressWarnings("unchecked") public <S, T> Instantiator<S, T> createInstantiator(final Class<S> source, final InstantiatorDefinition instantiatorDefinition, final Map<Parameter, Getter<? super S, ?>> injections, boolean builderIgnoresNullValues) throws Exception { InstantiatorKey<S> instantiatorKey = new InstantiatorKey<S>(instantiatorDefinition, injections, source); Class<? extends Instantiator<?, ?>> instantiator = instantiatorCache.get(instantiatorKey); Instantiator<Void, ?> builderInstantiator = null; if (instantiator == null) { final String className = generateClassNameForInstantiator(instantiatorKey); final byte[] bytes; if (instantiatorDefinition instanceof ExecutableInstantiatorDefinition) { bytes = InstantiatorBuilder.createInstantiator(className, source, (ExecutableInstantiatorDefinition)instantiatorDefinition, injections); } else { builderInstantiator = createInstantiator(Void.class, ((BuilderInstantiatorDefinition)instantiatorDefinition).getBuilderInstantiator(), new HashMap<Parameter, Getter<? super Void, ?>>(), builderIgnoresNullValues); bytes = InstantiatorBuilder.createInstantiator( className, source, (BuilderInstantiatorDefinition)instantiatorDefinition, injections, builderIgnoresNullValues); } instantiator = (Class<? extends Instantiator<?, ?>>) createClass(className, bytes, instantiatorKey.getDeclaringClass().getClassLoader()); instantiatorCache.put(instantiatorKey, instantiator); } Map<String, Getter<? super S, ?>> getterPerName = new HashMap<String, Getter<? super S, ?>>(); for(Entry<Parameter, Getter<? super S, ?>> e : injections.entrySet()) { getterPerName.put(e.getKey().getName(), e.getValue()); } if (instantiatorDefinition instanceof ExecutableInstantiatorDefinition) { return (Instantiator<S, T>) instantiator.getConstructor(Map.class).newInstance(getterPerName); } else { return (Instantiator<S, T>) instantiator.getConstructor(Map.class, Instantiator.class).newInstance(getterPerName, builderInstantiator); } }
public static <S> byte[] createInstantiator(final String className, final Class<?> sourceClass, final BuilderInstantiatorDefinition instantiatorDefinition, final Map<Parameter, Getter<? super S, ?>> injections, boolean ignoreNullValues) throws Exception { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); Class<?> targetClass= TypeHelper.toClass(BiInstantiatorBuilder.getTargetType(instantiatorDefinition)); String targetType = AsmUtils.toAsmType(targetClass); String sourceType = AsmUtils.toWrapperType(sourceClass); String classType = AsmUtils.toAsmType(className); String instantiatorType = AsmUtils.toAsmType(Instantiator.class); cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, classType, "Ljava/lang/Object;L" + instantiatorType + "<L" + targetType + ";>;", "java/lang/Object", new String[] { instantiatorType }); { FieldVisitor fv = cw.visitField( ACC_FINAL, "builderInstantiator", "L" + AsmUtils.toAsmType(Instantiator.class) + ";", "L" + AsmUtils.toAsmType(Instantiator.class) + "<Ljava/lang/Void;L" + AsmUtils.toAsmType(BiInstantiatorBuilder.getTargetType(instantiatorDefinition.getBuilderInstantiator())) + ";>;", null); fv.visitEnd(); } appendGetters(injections, cw); appendInitBuilder(injections, cw, sourceType, classType, instantiatorDefinition); appendNewInstanceBuilderOnBuilder(sourceClass, instantiatorDefinition, injections, cw, targetType, sourceType, classType, instantiatorDefinition.getSetters(), ignoreNullValues); appendBridgeMethod(cw, targetType, sourceType, classType); appendToString(injections, cw, instantiatorDefinition.getParameters()); cw.visitEnd(); return AsmUtils.writeClassToFile(className, cw.toByteArray()); }
private static <S> void invokeGetter(Parameter p, Getter<? super S, ?> getter, String classType, Class<?> sourceClass, MethodVisitor mv, Consumer<MethodVisitor> consumer, boolean ignoreNullValues) throws NoSuchMethodException { GetterCall getterCall = getGetterCall(p.getType(), getter.getClass()); changeToPrimitiveIfNeeded(p, mv, wrapperClass, ignoreNullValues); if (consumer != null) { consumer.accept(mv);
private static <S> void appendInit(Map<Parameter, Getter<? super S, ?>> injections, ClassWriter cw, String sourceType, String classType) { MethodVisitor mv; mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/util/Map;)V", "(Ljava/util/Map<Ljava.lang.String;L" + AsmUtils.toAsmType(Getter.class) +"<" + AsmUtils.toTargetTypeDeclaration(sourceType) + "*>;>;)V", null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); appendInitGetters(injections, classType, mv); mv.visitInsn(RETURN); mv.visitMaxs(3, 2); mv.visitEnd(); }
public static <S> byte[] createInstantiator(final String className, final Class<?> sourceClass, final BuilderInstantiatorDefinition instantiatorDefinition, final Map<Parameter, Getter<? super S, ?>> injections, boolean ignoreNullValues) throws Exception { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); Class<?> targetClass= TypeHelper.toClass(BiInstantiatorBuilder.getTargetType(instantiatorDefinition)); String targetType = AsmUtils.toAsmType(targetClass); String sourceType = AsmUtils.toWrapperType(sourceClass); String classType = AsmUtils.toAsmType(className); String instantiatorType = AsmUtils.toAsmType(Instantiator.class); cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, classType, "Ljava/lang/Object;L" + instantiatorType + "<L" + targetType + ";>;", "java/lang/Object", new String[] { instantiatorType }); { FieldVisitor fv = cw.visitField( ACC_FINAL, "builderInstantiator", "L" + AsmUtils.toAsmType(Instantiator.class) + ";", "L" + AsmUtils.toAsmType(Instantiator.class) + "<Ljava/lang/Void;L" + AsmUtils.toAsmType(BiInstantiatorBuilder.getTargetType(instantiatorDefinition.getBuilderInstantiator())) + ";>;", null); fv.visitEnd(); } appendGetters(injections, cw); appendInitBuilder(injections, cw, sourceType, classType, instantiatorDefinition); appendNewInstanceBuilderOnBuilder(sourceClass, instantiatorDefinition, injections, cw, targetType, sourceType, classType, instantiatorDefinition.getSetters(), ignoreNullValues); appendBridgeMethod(cw, targetType, sourceType, classType); appendToString(injections, cw, instantiatorDefinition.getParameters()); cw.visitEnd(); return AsmUtils.writeClassToFile(className, cw.toByteArray()); }
private static <S> void invokeGetter(Parameter p, Getter<? super S, ?> getter, String classType, Class<?> sourceClass, MethodVisitor mv, Consumer<MethodVisitor> consumer, boolean ignoreNullValues) throws NoSuchMethodException { GetterCall getterCall = getGetterCall(p.getType(), getter.getClass()); changeToPrimitiveIfNeeded(p, mv, wrapperClass, ignoreNullValues); if (consumer != null) { consumer.accept(mv);
private static <S> void appendInit(Map<Parameter, Getter<? super S, ?>> injections, ClassWriter cw, String sourceType, String classType) { MethodVisitor mv; mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/util/Map;)V", "(Ljava/util/Map<Ljava.lang.String;L" + AsmUtils.toAsmType(Getter.class) +"<" + AsmUtils.toTargetTypeDeclaration(sourceType) + "*>;>;)V", null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); appendInitGetters(injections, classType, mv); mv.visitInsn(RETURN); mv.visitMaxs(3, 2); mv.visitEnd(); }
public static <S> byte[] createInstantiator(final String className, final Class<?> sourceClass, final ExecutableInstantiatorDefinition instantiatorDefinition, final Map<Parameter, Getter<? super S, ?>> injections) throws Exception { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); Class<?> targetClass= TypeHelper.toClass(BiInstantiatorBuilder.getTargetType(instantiatorDefinition)); String targetType = AsmUtils.toAsmType(targetClass); String sourceType = AsmUtils.toWrapperType(sourceClass); String classType = AsmUtils.toAsmType(className); String instantiatorType = AsmUtils.toAsmType(Instantiator.class); cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, classType, "Ljava/lang/Object;L" + instantiatorType + "<L" + targetType + ";>;", "java/lang/Object", new String[] { instantiatorType }); Parameter[] parameters = instantiatorDefinition.getParameters(); appendGetters(injections, cw); appendInit(injections, cw, sourceType, classType); appendNewInstanceBuilderOnMethod(sourceClass, instantiatorDefinition, injections, cw, targetType, sourceType, classType, parameters); appendBridgeMethod(cw, targetType, sourceType, classType); appendToString(injections, cw, parameters); cw.visitEnd(); return AsmUtils.writeClassToFile(className, cw.toByteArray()); }
private static <S> void appendInitBuilder(Map<Parameter, Getter<? super S, ?>> injections, ClassWriter cw, String sourceType, String classType, BuilderInstantiatorDefinition instantiatorDefinition) { MethodVisitor mv; mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/util/Map;L" + AsmUtils.toAsmType(Instantiator.class) + ";)V", "(Ljava/util/Map<Ljava.lang.String;L" + AsmUtils.toAsmType(Getter.class) +"<" + AsmUtils.toTargetTypeDeclaration(sourceType) + "*>;>;" + "L" + AsmUtils.toAsmType(Instantiator.class) + "<Ljava/lang/Void;L" + AsmUtils.toAsmType(BiInstantiatorBuilder.getTargetType(instantiatorDefinition.getBuilderInstantiator())) +";>;)V", null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 2); mv.visitFieldInsn(PUTFIELD, classType, "builderInstantiator", "L" + AsmUtils.toAsmType(Instantiator.class) + ";"); appendInitGetters(injections, classType, mv); mv.visitInsn(RETURN); mv.visitMaxs(3, 2); mv.visitEnd(); }
@SuppressWarnings("unchecked") public <S, T> Instantiator<S, T> createInstantiator(final Class<S> source, final InstantiatorDefinition instantiatorDefinition, final Map<Parameter, Getter<? super S, ?>> injections, boolean builderIgnoresNullValues) throws Exception { InstantiatorKey<S> instantiatorKey = new InstantiatorKey<S>(instantiatorDefinition, injections, source); Class<? extends Instantiator<?, ?>> instantiator = instantiatorCache.get(instantiatorKey); Instantiator<Void, ?> builderInstantiator = null; if (instantiator == null) { final String className = generateClassNameForInstantiator(instantiatorKey); final byte[] bytes; if (instantiatorDefinition instanceof ExecutableInstantiatorDefinition) { bytes = InstantiatorBuilder.createInstantiator(className, source, (ExecutableInstantiatorDefinition)instantiatorDefinition, injections); } else { builderInstantiator = createInstantiator(Void.class, ((BuilderInstantiatorDefinition)instantiatorDefinition).getBuilderInstantiator(), new HashMap<Parameter, Getter<? super Void, ?>>(), builderIgnoresNullValues); bytes = InstantiatorBuilder.createInstantiator( className, source, (BuilderInstantiatorDefinition)instantiatorDefinition, injections, builderIgnoresNullValues); } instantiator = (Class<? extends Instantiator<?, ?>>) createClass(className, bytes, instantiatorKey.getDeclaringClass().getClassLoader()); instantiatorCache.put(instantiatorKey, instantiator); } Map<String, Getter<? super S, ?>> getterPerName = new HashMap<String, Getter<? super S, ?>>(); for(Entry<Parameter, Getter<? super S, ?>> e : injections.entrySet()) { getterPerName.put(e.getKey().getName(), e.getValue()); } if (instantiatorDefinition instanceof ExecutableInstantiatorDefinition) { return (Instantiator<S, T>) instantiator.getConstructor(Map.class).newInstance(getterPerName); } else { return (Instantiator<S, T>) instantiator.getConstructor(Map.class, Instantiator.class).newInstance(getterPerName, builderInstantiator); } }
private static <S> void appendInitBuilder(Map<Parameter, Getter<? super S, ?>> injections, ClassWriter cw, String sourceType, String classType, BuilderInstantiatorDefinition instantiatorDefinition) { MethodVisitor mv; mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/util/Map;L" + AsmUtils.toAsmType(Instantiator.class) + ";)V", "(Ljava/util/Map<Ljava.lang.String;L" + AsmUtils.toAsmType(Getter.class) +"<" + AsmUtils.toTargetTypeDeclaration(sourceType) + "*>;>;" + "L" + AsmUtils.toAsmType(Instantiator.class) + "<Ljava/lang/Void;L" + AsmUtils.toAsmType(BiInstantiatorBuilder.getTargetType(instantiatorDefinition.getBuilderInstantiator())) +";>;)V", null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 2); mv.visitFieldInsn(PUTFIELD, classType, "builderInstantiator", "L" + AsmUtils.toAsmType(Instantiator.class) + ";"); appendInitGetters(injections, classType, mv); mv.visitInsn(RETURN); mv.visitMaxs(3, 2); mv.visitEnd(); }