/** * {@inheritDoc} */ public FieldDefinition.Optional<S> defineProperty(String name, TypeDefinition type, boolean readOnly) { if (name.length() == 0) { throw new IllegalArgumentException("A bean property cannot have an empty name"); } else if (type.represents(void.class)) { throw new IllegalArgumentException("A bean property cannot have a void type"); } DynamicType.Builder<S> builder = this; FieldManifestation fieldManifestation; if (!readOnly) { builder = builder .defineMethod("set" + Character.toUpperCase(name.charAt(0)) + name.substring(1), void.class, Visibility.PUBLIC) .withParameters(type) .intercept(FieldAccessor.ofField(name)); fieldManifestation = FieldManifestation.PLAIN; } else { fieldManifestation = FieldManifestation.FINAL; } return builder .defineMethod((type.represents(boolean.class) || type.represents(Boolean.class) ? "is" : "get") + Character.toUpperCase(name.charAt(0)) + name.substring(1), type, Visibility.PUBLIC) .intercept(FieldAccessor.ofField(name)) .defineField(name, type, Visibility.PRIVATE, fieldManifestation); }
/** * {@inheritDoc} */ public DynamicType make(String auxiliaryTypeName, ClassFileVersion classFileVersion, MethodAccessorFactory methodAccessorFactory) { Implementation.Composable constructor = MethodCall.invoke(DEFAULT_CONSTRUCTOR).andThen(FieldAccessor.ofField(TYPE_FIELD).setsArgumentAt(0)); int index = 1; for (String field : fields.keySet()) { constructor = constructor.andThen(FieldAccessor.ofField(field).setsArgumentAt(index++)); } DynamicType.Builder<?> builder = new ByteBuddy(classFileVersion) .with(TypeValidation.DISABLED) .subclass(PrivilegedExceptionAction.class, ConstructorStrategy.Default.NO_CONSTRUCTORS) .name(auxiliaryTypeName) .modifiers(DEFAULT_TYPE_MODIFIER) .defineConstructor(Visibility.PUBLIC) .withParameters(CompoundList.of(Class.class, new ArrayList<Class<?>>(fields.values()))) .intercept(constructor) .method(named("run")) .intercept(MethodCall.invoke(methodDescription) .onField(TYPE_FIELD) .withField(fields.keySet().toArray(new String[fields.size()]))) .defineField(TYPE_FIELD, Class.class, Visibility.PRIVATE); for (Map.Entry<String, Class<?>> entry : fields.entrySet()) { builder = builder.defineField(entry.getKey(), entry.getValue(), Visibility.PRIVATE); } return builder.make(); } }
.defineField("$spock_interceptor", IProxyBasedMockInterceptor.class, Visibility.PRIVATE) .make() .load(classLoader, strategy)
private static BiFunction<StateNode, BeanModelType<?>, Object> createProxyConstructor( ClassLoader classLoader, Builder<?> proxyBuilder, String classFqn) { String proxyClassName = generateProxyClassName(classFqn, classLoader); Class<?> proxyType = proxyBuilder // Handle bean methods (and abstract methods for error handling) .method(method -> isAccessor(method) || method.isAbstract()) .intercept(MethodDelegation.to(proxyHandler)) // Handle internal $stateNode methods .defineField("$stateNode", StateNode.class) .method(method -> "$stateNode".equals(method.getName())) .intercept(FieldAccessor.ofField("$stateNode")) // Handle internal $modelType methods .defineField("$modelType", BeanModelType.class) .method(method -> "$modelType".equals(method.getName())) .intercept(FieldAccessor.ofField("$modelType")) // Create the class .name(proxyClassName).make() .load(classLoader, ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); return (node, modelType) -> { Object instance = ReflectTools.createProxyInstance(proxyType, modelType.getProxyType()); ModelProxy modelProxy = (ModelProxy) instance; modelProxy.$stateNode(node); modelProxy.$modelType(modelType); modelType.createInitialValues(node); return instance; }; }
private static BiFunction<StateNode, BeanModelType<?>, Object> createProxyConstructor( ClassLoader classLoader, Builder<?> proxyBuilder) { Class<?> proxyType = proxyBuilder // Handle bean methods (and abstract methods for error handling) .method(method -> isAccessor(method) || method.isAbstract()) .intercept(MethodDelegation.to(proxyHandler)) // Handle internal $stateNode methods .defineField("$stateNode", StateNode.class) .method(method -> "$stateNode".equals(method.getName())) .intercept(FieldAccessor.ofField("$stateNode")) // Handle internal $modelType methods .defineField("$modelType", BeanModelType.class) .method(method -> "$modelType".equals(method.getName())) .intercept(FieldAccessor.ofField("$modelType")) // Create the class .make().load(classLoader, ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); return (node, modelType) -> { Object instance = ReflectTools.createInstance(proxyType); ModelProxy modelProxy = (ModelProxy) instance; modelProxy.$stateNode(node); modelProxy.$modelType(modelType); return instance; }; }
@SuppressWarnings({ "unchecked", "rawtypes" }) public Class buildProxy( final Class persistentClass, final Class[] interfaces) { Set<Class<?>> key = new HashSet<Class<?>>(); if ( interfaces.length == 1 ) { key.add( persistentClass ); } key.addAll( Arrays.<Class<?>>asList( interfaces ) ); return byteBuddyState.loadProxy( persistentClass, new TypeCache.SimpleKey(key), byteBuddy -> byteBuddy .ignore( byteBuddyState.getProxyDefinitionHelpers().getGroovyGetMetaClassFilter() ) .with( new NamingStrategy.SuffixingRandom( PROXY_NAMING_SUFFIX, new NamingStrategy.SuffixingRandom.BaseNameResolver.ForFixedValue( persistentClass.getName() ) ) ) .subclass( interfaces.length == 1 ? persistentClass : Object.class, ConstructorStrategy.Default.IMITATE_SUPER_CLASS_OPENING ) .implement( (Type[]) interfaces ) .method( byteBuddyState.getProxyDefinitionHelpers().getVirtualNotFinalizerFilter() ) .intercept( byteBuddyState.getProxyDefinitionHelpers().getDelegateToInterceptorDispatcherMethodDelegation() ) .method( byteBuddyState.getProxyDefinitionHelpers().getHibernateGeneratedMethodFilter() ) .intercept( SuperMethodCall.INSTANCE ) .defineField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME, ProxyConfiguration.Interceptor.class, Visibility.PRIVATE ) .implement( ProxyConfiguration.class ) .intercept( byteBuddyState.getProxyDefinitionHelpers().getInterceptorFieldAccessor() ) ); }
@SuppressWarnings({ "unchecked", "rawtypes" }) public Class buildProxy( final Class persistentClass, final Class[] interfaces) { Set<Class<?>> key = new HashSet<Class<?>>(); if ( interfaces.length == 1 ) { key.add( persistentClass ); } key.addAll( Arrays.<Class<?>>asList( interfaces ) ); return byteBuddyState.loadProxy( persistentClass, new TypeCache.SimpleKey(key), byteBuddy -> byteBuddy .ignore( byteBuddyState.getProxyDefinitionHelpers().getGroovyGetMetaClassFilter() ) .with( new NamingStrategy.SuffixingRandom( PROXY_NAMING_SUFFIX, new NamingStrategy.SuffixingRandom.BaseNameResolver.ForFixedValue( persistentClass.getName() ) ) ) .subclass( interfaces.length == 1 ? persistentClass : Object.class, ConstructorStrategy.Default.IMITATE_SUPER_CLASS_OPENING ) .implement( (Type[]) interfaces ) .method( byteBuddyState.getProxyDefinitionHelpers().getVirtualNotFinalizerFilter() ) .intercept( byteBuddyState.getProxyDefinitionHelpers().getDelegateToInterceptorDispatcherMethodDelegation() ) .method( byteBuddyState.getProxyDefinitionHelpers().getHibernateGeneratedMethodFilter() ) .intercept( SuperMethodCall.INSTANCE ) .defineField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME, ProxyConfiguration.Interceptor.class, Visibility.PRIVATE ) .implement( ProxyConfiguration.class ) .intercept( byteBuddyState.getProxyDefinitionHelpers().getInterceptorFieldAccessor() ) ); }