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

net.amygdalum.testrecorder.codeserializer.CodeSerializer Maven / Gradle / Ivy

package net.amygdalum.testrecorder.codeserializer;

import static java.util.stream.Collectors.joining;
import static net.amygdalum.testrecorder.deserializers.Templates.assignLocalVariableStatement;
import static net.amygdalum.testrecorder.profile.ConfigurationLoader.defaultClassLoader;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

import net.amygdalum.testrecorder.ConfigurableSerializerFacade;
import net.amygdalum.testrecorder.DefaultPerformanceProfile;
import net.amygdalum.testrecorder.DefaultSerializationProfile;
import net.amygdalum.testrecorder.DefaultSnapshotConsumer;
import net.amygdalum.testrecorder.deserializers.CustomAnnotation;
import net.amygdalum.testrecorder.deserializers.DefaultDeserializerContext;
import net.amygdalum.testrecorder.deserializers.Deserializer;
import net.amygdalum.testrecorder.deserializers.DeserializerFactory;
import net.amygdalum.testrecorder.deserializers.DeserializerTypeManager;
import net.amygdalum.testrecorder.deserializers.builder.SetupGenerators;
import net.amygdalum.testrecorder.generator.DefaultTestGeneratorProfile;
import net.amygdalum.testrecorder.generator.TestGeneratorProfile;
import net.amygdalum.testrecorder.profile.AgentConfiguration;
import net.amygdalum.testrecorder.profile.ClassPathConfigurationLoader;
import net.amygdalum.testrecorder.profile.DefaultPathConfigurationLoader;
import net.amygdalum.testrecorder.profile.PerformanceProfile;
import net.amygdalum.testrecorder.profile.SerializationProfile;
import net.amygdalum.testrecorder.profile.SnapshotConsumer;
import net.amygdalum.testrecorder.serializers.SerializerFacade;
import net.amygdalum.testrecorder.types.Computation;
import net.amygdalum.testrecorder.types.LocalVariableNameGenerator;
import net.amygdalum.testrecorder.types.SerializedValue;
import net.amygdalum.testrecorder.types.SerializerSession;
import net.amygdalum.testrecorder.types.TypeManager;

public class CodeSerializer {

	private TestGeneratorProfile generatorProfile;
	private SerializerFacade facade;
	private SerializerSession session;
	private TypeManager types;
	private DeserializerFactory deserializers;

	public CodeSerializer() {
		this("", ConfigurableSerializerFacade::new, SetupGenerators::new);
	}

	public CodeSerializer(String pkg) {
		this(pkg, defaultClassLoader(CodeSerializer.class), ConfigurableSerializerFacade::new, SetupGenerators::new);
	}

	public CodeSerializer(String pkg, Function facade, Function deserializers) {
		this(pkg, defaultClassLoader(CodeSerializer.class), facade, deserializers);
	}

	public CodeSerializer(String pkg, ClassLoader loader, Function facade, Function deserializers) {
		this(pkg, new AgentConfiguration(new ClassPathConfigurationLoader(loader), new DefaultPathConfigurationLoader(loader))
			.withDefaultValue(SerializationProfile.class, DefaultSerializationProfile::new)
			.withDefaultValue(PerformanceProfile.class, DefaultPerformanceProfile::new)
			.withDefaultValue(SnapshotConsumer.class, DefaultSnapshotConsumer::new), facade, deserializers);
	}

	public CodeSerializer(String pkg, AgentConfiguration config, Function facade, Function deserializers) {
		this.generatorProfile = config.loadOptionalConfiguration(TestGeneratorProfile.class)
			.orElseGet(DefaultTestGeneratorProfile::new);
		this.facade = facade.apply(config);
		this.session = this.facade.newSession();
		this.deserializers = deserializers.apply(config);
		this.types = new DeserializerTypeManager(pkg);
	}

	public TypeManager getTypes() {
		return types;
	}

	public String serialize(Object value) {
		return serialize(value.getClass(), value);
	}

	public String serialize(Type type, Object value) {
		SerializedValue serializedValue = facade.serialize(type, value, session);

		return new Generator(serializedValue).generateCode();
	}

	private class Generator {

		private LocalVariableNameGenerator locals;
		private SerializedValue value;
		private List statements;
		private Deserializer deserializer;

		Generator(SerializedValue value) {
			this.value = value;
			this.locals = new LocalVariableNameGenerator();
			this.statements = new ArrayList<>();

			this.deserializer = deserializers.newGenerator(newContext(locals));
		}

		private DefaultDeserializerContext newContext(LocalVariableNameGenerator locals) {
			DefaultDeserializerContext context = new DefaultDeserializerContext(types, locals);
			for (CustomAnnotation annotation : generatorProfile.annotations()) {
				context.addHint(annotation.getTarget(), annotation.getAnnotation());
			}
			return context;
		}

		public String generateCode() {
			Computation serialized = value.accept(deserializer);

			statements.addAll(serialized.getStatements());
			if (!serialized.isStored()) {
				String name = locals.fetchName(value.getClass());
				String type = types.getVariableTypeName(serialized.getType());
				statements.add(assignLocalVariableStatement(type, name, serialized.getValue()));
			}

			return statements.stream()
				.collect(joining("\n"));
		}

	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy