All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.amygdalum.testrecorder.serializers.ProxySerializer Maven / Gradle / Ivy

package net.amygdalum.testrecorder.serializers;

import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;
import static net.amygdalum.testrecorder.util.Types.isPrimitive;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import java.util.stream.Stream.Builder;

import net.amygdalum.testrecorder.types.SerializedValue;
import net.amygdalum.testrecorder.types.Serializer;
import net.amygdalum.testrecorder.types.SerializerSession;
import net.amygdalum.testrecorder.values.SerializedImmutable;
import net.amygdalum.testrecorder.values.SerializedObject;
import net.amygdalum.testrecorder.values.SerializedProxy;

public class ProxySerializer extends AbstractCompositeSerializer implements Serializer {

	public ProxySerializer() {
	}

	@Override
	public List> getMatchingClasses() {
		return emptyList();
	}

	@Override
	public Stream components(Object object, SerializerSession session) {
		Builder components = Stream.builder();

		if (!session.facades(object)) {
			InvocationHandler invocationHandler = Proxy.getInvocationHandler(object);
			components.add(invocationHandler);

			Class objectClass = object.getClass();
			while (objectClass != Proxy.class && objectClass != Object.class && !session.excludes(objectClass)) {
				for (Field f : objectClass.getDeclaredFields()) {
					if (!session.excludes(f) && !session.facades(f)) {
						if (!isPrimitive(f.getType())) {
							components.add(fieldOf(object, f));
						}
					}
				}
				objectClass = objectClass.getSuperclass();
			}
		}

		return components.build();
	}

	@Override
	public SerializedProxy generate(Class type, SerializerSession session) {
		return new SerializedProxy(type);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public void populate(SerializedProxy serializedProxy, Object object, SerializerSession session) {
		Class[] interfaces = object.getClass().getInterfaces();
		List>> serializedInterfaces = Arrays.stream(interfaces)
			.map(interfaceClass -> (SerializedImmutable>) (SerializedImmutable) new SerializedImmutable<>(Class.class).withValue(interfaceClass))
			.collect(toList());
		serializedProxy.setInterfaces(serializedInterfaces);

		if (session.facades(object)) {
			SerializedValue serializedInvocationHandler = new SerializedObject(InvocationHandler.class);
			serializedProxy.setInvocationHandler(serializedInvocationHandler);

			return;
		}

		InvocationHandler invocationHandler = Proxy.getInvocationHandler(object);
		SerializedValue serializedInvocationHandler = resolvedValueOf(session, InvocationHandler.class, invocationHandler);
		serializedProxy.setInvocationHandler(serializedInvocationHandler);

		Class objectClass = object.getClass();
		while (objectClass != Proxy.class && objectClass != Object.class && !session.excludes(objectClass)) {
			for (Field f : objectClass.getDeclaredFields()) {
				if (!session.excludes(f)) {
					serializedProxy.addField(resolvedFieldOf(session, object, f));
				}
			}
			objectClass = objectClass.getSuperclass();
		}

	}

}