diff --git a/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/ArrayIT.java b/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/ArrayIT.java index 8fabc43..cf31cbd 100644 --- a/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/ArrayIT.java +++ b/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/ArrayIT.java @@ -10,6 +10,10 @@ import uk.gov.justice.generation.pojo.core.ClassNameProvider; import uk.gov.justice.generation.pojo.core.NameGenerator; import uk.gov.justice.generation.pojo.generators.JavaGeneratorFactory; +import uk.gov.justice.generation.pojo.generators.plugin.EventAnnotationGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.FieldAndMethodGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.PluginClassGeneratable; +import uk.gov.justice.generation.pojo.generators.plugin.SerializableGenerator; import uk.gov.justice.generation.pojo.integration.utils.ClassCompiler; import uk.gov.justice.generation.pojo.visitable.VisitableSchema; import uk.gov.justice.generation.pojo.visitable.VisitableSchemaFactory; @@ -73,8 +77,13 @@ public void shouldAnArraySchemaDocumentWithAnArrayOfItemSchemas() throws Excepti final List> newClasses = new ArrayList<>(); + final List plugins = asList( + new EventAnnotationGenerator(), + new SerializableGenerator(), + new FieldAndMethodGenerator()); + javaGeneratorFactory - .createClassGeneratorsFor(definitionBuilderVisitor.getDefinitions()) + .createClassGeneratorsFor(definitionBuilderVisitor.getDefinitions(), plugins) .forEach(classGeneratable -> { sourceWriter.write(classGeneratable, sourceOutputDirectory.toPath()); final Class newClass = classCompiler.compile(classGeneratable, sourceOutputDirectory, classesOutputDirectory); diff --git a/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/ClassGeneratorIT.java b/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/ClassGeneratorIT.java index bc62bea..b07c974 100644 --- a/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/ClassGeneratorIT.java +++ b/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/ClassGeneratorIT.java @@ -11,6 +11,10 @@ import uk.gov.justice.generation.pojo.dom.ClassName; import uk.gov.justice.generation.pojo.dom.FieldDefinition; import uk.gov.justice.generation.pojo.generators.JavaGeneratorFactory; +import uk.gov.justice.generation.pojo.generators.plugin.EventAnnotationGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.FieldAndMethodGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.PluginClassGeneratable; +import uk.gov.justice.generation.pojo.generators.plugin.SerializableGenerator; import uk.gov.justice.generation.pojo.integration.utils.ClassCompiler; import uk.gov.justice.generation.pojo.write.SourceWriter; import uk.gov.justice.services.common.converter.ZonedDateTimes; @@ -61,9 +65,13 @@ public void shouldGenerateJavaClassSourceCode() throws Exception { final ClassDefinition addressDefinition = addressDefinition(packageName); final ClassDefinition employeeDefinition = employeeDefinition(packageName, addressDefinition); + final List plugins = asList( + new EventAnnotationGenerator(), + new SerializableGenerator(), + new FieldAndMethodGenerator()); final List> classes = javaGeneratorFactory - .createClassGeneratorsFor(asList(addressDefinition, employeeDefinition)) + .createClassGeneratorsFor(asList(addressDefinition, employeeDefinition), plugins) .stream() .map(classGenerator -> { sourceWriter.write(classGenerator, sourceOutputDirectory.toPath()); diff --git a/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/CombinedSchemaIT.java b/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/CombinedSchemaIT.java index b28e22a..2143d27 100644 --- a/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/CombinedSchemaIT.java +++ b/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/CombinedSchemaIT.java @@ -1,6 +1,7 @@ package uk.gov.justice.generation.pojo.integration.test; import static com.jayway.jsonassert.JsonAssert.with; +import static java.util.Arrays.asList; import static org.apache.commons.io.FileUtils.cleanDirectory; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; @@ -10,6 +11,10 @@ import uk.gov.justice.generation.pojo.core.ClassNameProvider; import uk.gov.justice.generation.pojo.core.NameGenerator; import uk.gov.justice.generation.pojo.generators.JavaGeneratorFactory; +import uk.gov.justice.generation.pojo.generators.plugin.EventAnnotationGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.FieldAndMethodGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.PluginClassGeneratable; +import uk.gov.justice.generation.pojo.generators.plugin.SerializableGenerator; import uk.gov.justice.generation.pojo.integration.utils.ClassCompiler; import uk.gov.justice.generation.pojo.visitable.VisitableSchema; import uk.gov.justice.generation.pojo.visitable.VisitableSchemaFactory; @@ -72,9 +77,13 @@ public void shouldParseAVeryComplexSchemaDocument() throws Exception { visitableSchema.accept(fieldName, definitionBuilderVisitor); final List> newClasses = new ArrayList<>(); + final List plugins = asList( + new EventAnnotationGenerator(), + new SerializableGenerator(), + new FieldAndMethodGenerator()); javaGeneratorFactory - .createClassGeneratorsFor(definitionBuilderVisitor.getDefinitions()) + .createClassGeneratorsFor(definitionBuilderVisitor.getDefinitions(), plugins) .forEach(classGeneratable -> { sourceWriter.write(classGeneratable, sourceOutputDirectory.toPath()); final Class newClass = classCompiler.compile(classGeneratable, sourceOutputDirectory, classesOutputDirectory); diff --git a/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/ComplexSchemaIT.java b/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/ComplexSchemaIT.java index 27dcd40..54702da 100644 --- a/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/ComplexSchemaIT.java +++ b/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/ComplexSchemaIT.java @@ -1,11 +1,16 @@ package uk.gov.justice.generation.pojo.integration.test; +import static java.util.Arrays.asList; import static org.apache.commons.io.FileUtils.cleanDirectory; import uk.gov.justice.generation.io.files.loader.SchemaLoader; import uk.gov.justice.generation.pojo.core.ClassNameProvider; import uk.gov.justice.generation.pojo.core.NameGenerator; import uk.gov.justice.generation.pojo.generators.JavaGeneratorFactory; +import uk.gov.justice.generation.pojo.generators.plugin.EventAnnotationGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.FieldAndMethodGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.PluginClassGeneratable; +import uk.gov.justice.generation.pojo.generators.plugin.SerializableGenerator; import uk.gov.justice.generation.pojo.integration.utils.ClassCompiler; import uk.gov.justice.generation.pojo.visitable.VisitableSchema; import uk.gov.justice.generation.pojo.visitable.VisitableSchemaFactory; @@ -15,6 +20,7 @@ import uk.gov.justice.generation.pojo.write.SourceWriter; import java.io.File; +import java.util.List; import org.everit.json.schema.Schema; import org.junit.Before; @@ -57,11 +63,15 @@ public void shouldParseAVeryComplexSchemaDocument() throws Exception { final DefinitionBuilderVisitor definitionBuilderVisitor = new DefinitionBuilderVisitor("uk.gov.justice.pojo.complex.schema", definitionFactory); final VisitableSchemaFactory visitableSchemaFactory = new VisitableSchemaFactory(); final VisitableSchema visitableSchema = visitableSchemaFactory.createWith(schema, new DefaultAcceptorFactory(visitableSchemaFactory)); + final List plugins = asList( + new EventAnnotationGenerator(), + new SerializableGenerator(), + new FieldAndMethodGenerator()); visitableSchema.accept(fieldName, definitionBuilderVisitor); javaGeneratorFactory - .createClassGeneratorsFor(definitionBuilderVisitor.getDefinitions()) + .createClassGeneratorsFor(definitionBuilderVisitor.getDefinitions(), plugins) .forEach(classGeneratable -> { sourceWriter.write(classGeneratable, sourceOutputDirectory.toPath()); classCompiler.compile(classGeneratable, sourceOutputDirectory, classesOutputDirectory); diff --git a/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/DefinitionBuilderIT.java b/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/DefinitionBuilderIT.java index d142ef6..099d1b8 100644 --- a/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/DefinitionBuilderIT.java +++ b/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/DefinitionBuilderIT.java @@ -1,6 +1,7 @@ package uk.gov.justice.generation.pojo.integration.test; import static com.jayway.jsonassert.JsonAssert.with; +import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.apache.commons.io.FileUtils.cleanDirectory; import static org.hamcrest.CoreMatchers.is; @@ -12,6 +13,10 @@ import uk.gov.justice.generation.pojo.dom.ClassDefinition; import uk.gov.justice.generation.pojo.generators.ClassGeneratable; import uk.gov.justice.generation.pojo.generators.JavaGeneratorFactory; +import uk.gov.justice.generation.pojo.generators.plugin.EventAnnotationGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.FieldAndMethodGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.PluginClassGeneratable; +import uk.gov.justice.generation.pojo.generators.plugin.SerializableGenerator; import uk.gov.justice.generation.pojo.integration.utils.ClassCompiler; import uk.gov.justice.generation.pojo.visitable.VisitableSchema; import uk.gov.justice.generation.pojo.visitable.VisitableSchemaFactory; @@ -24,6 +29,7 @@ import java.io.File; import java.lang.reflect.Constructor; import java.math.BigDecimal; +import java.util.List; import com.fasterxml.jackson.databind.ObjectMapper; import org.everit.json.schema.Schema; @@ -71,9 +77,13 @@ public void shouldBuildTypeSpecFromSchema() throws Exception { visitableSchema.accept(fieldName, definitionBuilderVisitor); final ClassDefinition personClassDefinition = (ClassDefinition) definitionBuilderVisitor.getDefinitions().get(0); + final List plugins = asList( + new EventAnnotationGenerator(), + new SerializableGenerator(), + new FieldAndMethodGenerator()); final ClassGeneratable personClassGenerator = new JavaGeneratorFactory() - .createClassGeneratorsFor(singletonList(personClassDefinition)) + .createClassGeneratorsFor(singletonList(personClassDefinition), plugins) .get(0); sourceWriter.write(personClassGenerator, sourceOutputDirectory.toPath()); diff --git a/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/EnumGeneratorIT.java b/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/EnumGeneratorIT.java index 6ae9ea7..97895b4 100644 --- a/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/EnumGeneratorIT.java +++ b/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/EnumGeneratorIT.java @@ -12,6 +12,10 @@ import uk.gov.justice.generation.pojo.dom.EnumDefinition; import uk.gov.justice.generation.pojo.dom.FieldDefinition; import uk.gov.justice.generation.pojo.generators.JavaGeneratorFactory; +import uk.gov.justice.generation.pojo.generators.plugin.EventAnnotationGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.FieldAndMethodGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.PluginClassGeneratable; +import uk.gov.justice.generation.pojo.generators.plugin.SerializableGenerator; import uk.gov.justice.generation.pojo.integration.utils.ClassCompiler; import uk.gov.justice.generation.pojo.write.SourceWriter; import uk.gov.justice.services.common.converter.jackson.ObjectMapperProducer; @@ -57,9 +61,13 @@ public void shouldGenerateJavaClassSourceCode() throws Exception { final ClassDefinition studentDefinition = studentDefinition(packageName); final EnumDefinition colourDefinition = colourDefinition(packageName); + final List plugins = asList( + new EventAnnotationGenerator(), + new SerializableGenerator(), + new FieldAndMethodGenerator()); final List> classes = javaGeneratorFactory - .createClassGeneratorsFor(asList(colourDefinition, studentDefinition)) + .createClassGeneratorsFor(asList(colourDefinition, studentDefinition), plugins) .stream() .map(classGenerator -> { sourceWriter.write(classGenerator, sourceOutputDirectory.toPath()); diff --git a/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/SourceWriterIT.java b/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/SourceWriterIT.java index 740423e..add1119 100644 --- a/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/SourceWriterIT.java +++ b/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/SourceWriterIT.java @@ -1,6 +1,7 @@ package uk.gov.justice.generation.pojo.integration.test; import static com.jayway.jsonassert.JsonAssert.with; +import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.apache.commons.io.FileUtils.cleanDirectory; import static org.hamcrest.CoreMatchers.is; @@ -11,12 +12,17 @@ import uk.gov.justice.generation.pojo.dom.FieldDefinition; import uk.gov.justice.generation.pojo.generators.ClassGeneratable; import uk.gov.justice.generation.pojo.generators.JavaGeneratorFactory; +import uk.gov.justice.generation.pojo.generators.plugin.EventAnnotationGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.FieldAndMethodGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.PluginClassGeneratable; +import uk.gov.justice.generation.pojo.generators.plugin.SerializableGenerator; import uk.gov.justice.generation.pojo.integration.utils.ClassCompiler; import uk.gov.justice.generation.pojo.write.SourceWriter; import uk.gov.justice.services.common.converter.jackson.ObjectMapperProducer; import java.io.File; import java.lang.reflect.Constructor; +import java.util.List; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; @@ -51,9 +57,13 @@ public void shouldWriteASingleSourceFile() throws Exception { final String packageName = "org.bloggs.fred"; final ClassDefinition addressDefinition = addressDefinition(packageName); + final List plugins = asList( + new EventAnnotationGenerator(), + new SerializableGenerator(), + new FieldAndMethodGenerator()); final ClassGeneratable addressGenerator = new JavaGeneratorFactory() - .createClassGeneratorsFor(singletonList(addressDefinition)) + .createClassGeneratorsFor(singletonList(addressDefinition), plugins) .get(0); sourceWriter.write(addressGenerator, sourceOutputDirectory.toPath()); diff --git a/pojo-generator-core/src/main/java/uk/gov/justice/generation/SchemaPojoGenerator.java b/pojo-generator-core/src/main/java/uk/gov/justice/generation/SchemaPojoGenerator.java index b3fb2ce..b07cb7f 100644 --- a/pojo-generator-core/src/main/java/uk/gov/justice/generation/SchemaPojoGenerator.java +++ b/pojo-generator-core/src/main/java/uk/gov/justice/generation/SchemaPojoGenerator.java @@ -1,10 +1,17 @@ package uk.gov.justice.generation; +import static java.util.Arrays.asList; + import uk.gov.justice.generation.io.files.loader.SchemaLoader; import uk.gov.justice.generation.pojo.core.ClassNameProvider; import uk.gov.justice.generation.pojo.core.GenerationContext; import uk.gov.justice.generation.pojo.core.NameGenerator; +import uk.gov.justice.generation.pojo.generators.ClassGeneratable; import uk.gov.justice.generation.pojo.generators.JavaGeneratorFactory; +import uk.gov.justice.generation.pojo.generators.plugin.EventAnnotationGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.FieldAndMethodGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.PluginClassGeneratable; +import uk.gov.justice.generation.pojo.generators.plugin.SerializableGenerator; import uk.gov.justice.generation.pojo.validation.FileNameValidator; import uk.gov.justice.generation.pojo.visitable.VisitableSchemaFactory; import uk.gov.justice.generation.pojo.visitable.acceptor.DefaultAcceptorFactory; @@ -17,6 +24,7 @@ import uk.gov.justice.maven.generator.io.files.parser.core.GeneratorConfig; import java.io.File; +import java.util.List; import org.everit.json.schema.Schema; import org.slf4j.Logger; @@ -45,13 +53,17 @@ public void run(final File source, final GeneratorConfig generatorConfig) { final DefinitionBuilderVisitor definitionBuilderVisitor = constructDefinitionBuilderVisitor(source, generatorConfig.getBasePackageName()); final DefaultAcceptorFactory jsonSchemaAcceptorFactory = new DefaultAcceptorFactory(visitableSchemaFactory); + final List plugins = asList( + new EventAnnotationGenerator(), + new SerializableGenerator(), + new FieldAndMethodGenerator()); visitableSchemaFactory.createWith(schema, jsonSchemaAcceptorFactory) .accept(fieldName, definitionBuilderVisitor); - javaGeneratorFactory - .createClassGeneratorsFor(definitionBuilderVisitor.getDefinitions()) - .forEach(classGeneratable -> writer.write(classGeneratable, generationContext)); + final List classGenerators = javaGeneratorFactory.createClassGeneratorsFor(definitionBuilderVisitor.getDefinitions(), plugins); + + classGenerators.forEach(classGeneratable -> writer.write(classGeneratable, generationContext)); } private DefinitionBuilderVisitor constructDefinitionBuilderVisitor(final File source, final String basePackageName) { diff --git a/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/ClassGenerator.java b/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/ClassGenerator.java index 18c5fc3..76459a9 100644 --- a/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/ClassGenerator.java +++ b/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/ClassGenerator.java @@ -1,110 +1,43 @@ package uk.gov.justice.generation.pojo.generators; -import static com.squareup.javapoet.MethodSpec.constructorBuilder; -import static com.squareup.javapoet.TypeName.LONG; import static com.squareup.javapoet.TypeSpec.classBuilder; -import static java.util.stream.Collectors.toList; -import static javax.lang.model.element.Modifier.FINAL; -import static javax.lang.model.element.Modifier.PRIVATE; import static javax.lang.model.element.Modifier.PUBLIC; -import static javax.lang.model.element.Modifier.STATIC; -import uk.gov.justice.domain.annotation.Event; import uk.gov.justice.generation.pojo.dom.ClassDefinition; import uk.gov.justice.generation.pojo.dom.ClassName; -import uk.gov.justice.generation.pojo.dom.Definition; +import uk.gov.justice.generation.pojo.generators.plugin.PluginClassGeneratable; -import java.io.Serializable; import java.util.List; -import com.squareup.javapoet.AnnotationSpec; -import com.squareup.javapoet.CodeBlock; -import com.squareup.javapoet.FieldSpec; -import com.squareup.javapoet.MethodSpec; -import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.TypeSpec; public class ClassGenerator implements ClassGeneratable { - private static final String SERIAL_VERSION_FIELD_NAME = "serialVersionUID"; - private static final String SERIAL_VERSION_VALUE = "1L"; - private final ClassDefinition classDefinition; private final JavaGeneratorFactory javaGeneratorFactory; - private final DefinitionToTypeNameConverter definitionToTypeNameConverter = new DefinitionToTypeNameConverter(); + private final List plugins; - public ClassGenerator(final ClassDefinition classDefinition, final JavaGeneratorFactory javaGeneratorFactory) { + public ClassGenerator(final ClassDefinition classDefinition, final JavaGeneratorFactory javaGeneratorFactory, final List plugins) { this.classDefinition = classDefinition; this.javaGeneratorFactory = javaGeneratorFactory; + this.plugins = plugins; } @Override public TypeSpec generate() { - final String className = classDefinition.getClassName().getSimpleName(); - final List definitions = classDefinition.getFieldDefinitions(); - - final List generators = definitions - .stream() - .map(javaGeneratorFactory::createGeneratorFor) - .collect(toList()); - - final List fields = generators - .stream() - .map(ElementGeneratable::generateField) - .collect(toList()); - - final List methods = generators - .stream() - .flatMap(ElementGeneratable::generateMethods) - .collect(toList()); final TypeSpec.Builder typeSpecBuilder = classBuilder(className) - .addModifiers(PUBLIC) - .addSuperinterface(Serializable.class) - .addField(FieldSpec - .builder(LONG, SERIAL_VERSION_FIELD_NAME, PRIVATE, STATIC, FINAL) - .initializer(SERIAL_VERSION_VALUE) - .build()); + .addModifiers(PUBLIC); - classDefinition.getEventName().ifPresent(eventName -> - typeSpecBuilder.addAnnotation(AnnotationSpec.builder(Event.class) - .addMember("value", "$S", eventName) - .build())); + plugins.forEach(generator -> + generator.generateWith(typeSpecBuilder, classDefinition, javaGeneratorFactory)); - return typeSpecBuilder.addMethod(buildConstructor(definitions)) - .addFields(fields) - .addMethods(methods) - .build(); + return typeSpecBuilder.build(); } @Override public ClassName getClassName() { return classDefinition.getClassName(); } - - private MethodSpec buildConstructor(final List definitions) { - final List fieldNames = definitions.stream().map(Definition::getFieldName).collect(toList()); - - return constructorBuilder() - .addModifiers(PUBLIC) - .addParameters(constructorParameters(definitions)) - .addCode(constructorStatements(fieldNames)) - .build(); - } - - private CodeBlock constructorStatements(final List names) { - final CodeBlock.Builder builder = CodeBlock.builder(); - - names.forEach(fieldName -> builder.addStatement("this.$N = $N", fieldName, fieldName)); - - return builder.build(); - } - - private List constructorParameters(final List definitions) { - return definitions.stream() - .map(definition -> ParameterSpec.builder(definitionToTypeNameConverter.getTypeName(definition), definition.getFieldName(), FINAL).build()) - .collect(toList()); - } - } diff --git a/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/JavaGeneratorFactory.java b/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/JavaGeneratorFactory.java index 03b8de2..b290b30 100644 --- a/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/JavaGeneratorFactory.java +++ b/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/JavaGeneratorFactory.java @@ -6,6 +6,7 @@ import uk.gov.justice.generation.pojo.dom.Definition; import uk.gov.justice.generation.pojo.dom.EnumDefinition; import uk.gov.justice.generation.pojo.dom.FieldDefinition; +import uk.gov.justice.generation.pojo.generators.plugin.PluginClassGeneratable; import java.util.List; @@ -20,7 +21,7 @@ public ElementGeneratable createGeneratorFor(final Definition definition) { return new FieldGenerator((FieldDefinition) definition); } - public List createClassGeneratorsFor(final List definitions) { + public List createClassGeneratorsFor(final List definitions, final List plugins) { return definitions.stream() .filter(definition -> EnumDefinition.class.isInstance(definition) || ClassDefinition.class.isInstance(definition)) .map(definition -> { @@ -28,7 +29,7 @@ public List createClassGeneratorsFor(final List de return new EnumGenerator((EnumDefinition) definition); } - return new ClassGenerator((ClassDefinition) definition, this); + return new ClassGenerator((ClassDefinition) definition, this, plugins); }) .collect(toList()); } diff --git a/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/plugin/EventAnnotationGenerator.java b/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/plugin/EventAnnotationGenerator.java new file mode 100644 index 0000000..56de22d --- /dev/null +++ b/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/plugin/EventAnnotationGenerator.java @@ -0,0 +1,24 @@ +package uk.gov.justice.generation.pojo.generators.plugin; + +import uk.gov.justice.domain.annotation.Event; +import uk.gov.justice.generation.pojo.dom.ClassDefinition; +import uk.gov.justice.generation.pojo.generators.JavaGeneratorFactory; + +import com.squareup.javapoet.AnnotationSpec; +import com.squareup.javapoet.TypeSpec; + +public class EventAnnotationGenerator implements PluginClassGeneratable { + + @Override + public TypeSpec.Builder generateWith(final TypeSpec.Builder typeSpecBuilder, + final ClassDefinition classDefinition, + final JavaGeneratorFactory javaGeneratorFactory) { + + classDefinition.getEventName().ifPresent(eventName -> + typeSpecBuilder.addAnnotation(AnnotationSpec.builder(Event.class) + .addMember("value", "$S", eventName) + .build())); + + return typeSpecBuilder; + } +} diff --git a/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/plugin/FieldAndMethodGenerator.java b/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/plugin/FieldAndMethodGenerator.java new file mode 100644 index 0000000..058f451 --- /dev/null +++ b/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/plugin/FieldAndMethodGenerator.java @@ -0,0 +1,78 @@ +package uk.gov.justice.generation.pojo.generators.plugin; + +import static com.squareup.javapoet.MethodSpec.constructorBuilder; +import static java.util.stream.Collectors.toList; +import static javax.lang.model.element.Modifier.FINAL; +import static javax.lang.model.element.Modifier.PUBLIC; + +import uk.gov.justice.generation.pojo.dom.ClassDefinition; +import uk.gov.justice.generation.pojo.dom.Definition; +import uk.gov.justice.generation.pojo.generators.DefinitionToTypeNameConverter; +import uk.gov.justice.generation.pojo.generators.ElementGeneratable; +import uk.gov.justice.generation.pojo.generators.JavaGeneratorFactory; + +import java.util.List; + +import com.squareup.javapoet.CodeBlock; +import com.squareup.javapoet.FieldSpec; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterSpec; +import com.squareup.javapoet.TypeSpec; + +public class FieldAndMethodGenerator implements PluginClassGeneratable { + + private final DefinitionToTypeNameConverter definitionToTypeNameConverter = new DefinitionToTypeNameConverter(); + + @Override + public TypeSpec.Builder generateWith(final TypeSpec.Builder typeSpecBuilder, + final ClassDefinition classDefinition, + final JavaGeneratorFactory javaGeneratorFactory) { + + final List fieldDefinitions = classDefinition.getFieldDefinitions(); + + final List fieldGenerators = fieldDefinitions + .stream() + .map(javaGeneratorFactory::createGeneratorFor) + .collect(toList()); + + final List fields = fieldGenerators + .stream() + .map(ElementGeneratable::generateField) + .collect(toList()); + + final List methods = fieldGenerators + .stream() + .flatMap(ElementGeneratable::generateMethods) + .collect(toList()); + + typeSpecBuilder.addMethod(buildConstructor(fieldDefinitions)) + .addFields(fields) + .addMethods(methods); + + return typeSpecBuilder; + } + + private MethodSpec buildConstructor(final List definitions) { + final List fieldNames = definitions.stream().map(Definition::getFieldName).collect(toList()); + + return constructorBuilder() + .addModifiers(PUBLIC) + .addParameters(constructorParameters(definitions)) + .addCode(constructorStatements(fieldNames)) + .build(); + } + + private CodeBlock constructorStatements(final List names) { + final CodeBlock.Builder builder = CodeBlock.builder(); + + names.forEach(fieldName -> builder.addStatement("this.$N = $N", fieldName, fieldName)); + + return builder.build(); + } + + private List constructorParameters(final List definitions) { + return definitions.stream() + .map(definition -> ParameterSpec.builder(definitionToTypeNameConverter.getTypeName(definition), definition.getFieldName(), FINAL).build()) + .collect(toList()); + } +} diff --git a/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/plugin/PluginClassGeneratable.java b/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/plugin/PluginClassGeneratable.java new file mode 100644 index 0000000..3b2584f --- /dev/null +++ b/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/plugin/PluginClassGeneratable.java @@ -0,0 +1,11 @@ +package uk.gov.justice.generation.pojo.generators.plugin; + +import uk.gov.justice.generation.pojo.dom.ClassDefinition; +import uk.gov.justice.generation.pojo.generators.JavaGeneratorFactory; + +import com.squareup.javapoet.TypeSpec; + +public interface PluginClassGeneratable { + + TypeSpec.Builder generateWith(final TypeSpec.Builder typeSpecBuilder, final ClassDefinition classDefinition, final JavaGeneratorFactory javaGeneratorFactory); +} diff --git a/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/plugin/SerializableGenerator.java b/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/plugin/SerializableGenerator.java new file mode 100644 index 0000000..4f20737 --- /dev/null +++ b/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/generators/plugin/SerializableGenerator.java @@ -0,0 +1,34 @@ +package uk.gov.justice.generation.pojo.generators.plugin; + +import static com.squareup.javapoet.TypeName.LONG; +import static javax.lang.model.element.Modifier.FINAL; +import static javax.lang.model.element.Modifier.PRIVATE; +import static javax.lang.model.element.Modifier.STATIC; + +import uk.gov.justice.generation.pojo.dom.ClassDefinition; +import uk.gov.justice.generation.pojo.generators.JavaGeneratorFactory; + +import java.io.Serializable; + +import com.squareup.javapoet.FieldSpec; +import com.squareup.javapoet.TypeSpec; + +public class SerializableGenerator implements PluginClassGeneratable { + + private static final String SERIAL_VERSION_FIELD_NAME = "serialVersionUID"; + private static final String SERIAL_VERSION_VALUE = "1L"; + + @Override + public TypeSpec.Builder generateWith(final TypeSpec.Builder typeSpecBuilder, + final ClassDefinition classDefinition, + final JavaGeneratorFactory javaGeneratorFactory) { + + typeSpecBuilder.addSuperinterface(Serializable.class) + .addField(FieldSpec + .builder(LONG, SERIAL_VERSION_FIELD_NAME, PRIVATE, STATIC, FINAL) + .initializer(SERIAL_VERSION_VALUE) + .build()); + + return typeSpecBuilder; + } +} diff --git a/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/generators/ClassGeneratorTest.java b/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/generators/ClassGeneratorTest.java index aae37f7..df7d227 100644 --- a/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/generators/ClassGeneratorTest.java +++ b/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/generators/ClassGeneratorTest.java @@ -4,6 +4,9 @@ import static com.squareup.javapoet.FieldSpec.builder; import static com.squareup.javapoet.MethodSpec.constructorBuilder; import static com.squareup.javapoet.MethodSpec.methodBuilder; +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; import static javax.lang.model.element.Modifier.FINAL; import static javax.lang.model.element.Modifier.PRIVATE; import static javax.lang.model.element.Modifier.PUBLIC; @@ -19,6 +22,9 @@ import uk.gov.justice.generation.pojo.dom.ClassDefinition; import uk.gov.justice.generation.pojo.dom.ClassName; import uk.gov.justice.generation.pojo.dom.FieldDefinition; +import uk.gov.justice.generation.pojo.generators.plugin.EventAnnotationGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.FieldAndMethodGenerator; +import uk.gov.justice.generation.pojo.generators.plugin.SerializableGenerator; import java.io.Serializable; import java.util.stream.Stream; @@ -44,14 +50,14 @@ public void shouldGenerateTypeSpecForClassDefinitionWithNoFields() throws Except final ClassName className = new ClassName("org.something", "Address"); final ClassDefinition classDefinition = new ClassDefinition("address", className); - final ClassGenerator classGenerator = new ClassGenerator(classDefinition, javaGeneratorFactory); + final ClassGenerator classGenerator = new ClassGenerator(classDefinition, javaGeneratorFactory, singletonList(new FieldAndMethodGenerator())); final TypeSpec typeSpec = classGenerator.generate(); assertThat(typeSpec.annotations.isEmpty(), is(true)); assertThat(typeSpec.name, is("Address")); assertThat(typeSpec.modifiers.size(), is(1)); assertThat(typeSpec.modifiers, hasItem(PUBLIC)); - assertThat(typeSpec.fieldSpecs.size(), is(1)); + assertThat(typeSpec.fieldSpecs.size(), is(0)); assertThat(typeSpec.methodSpecs.size(), is(1)); assertThat(typeSpec.methodSpecs, hasItem(constructorBuilder().addModifiers(PUBLIC).build())); } @@ -61,7 +67,7 @@ public void shouldGenerateTypeSpecForClassDefinitionWithEventAnnotation() throws final ClassName className = new ClassName("org.something", "Address"); final ClassDefinition classDefinition = new ClassDefinition("address", className, "example.events.address"); - final ClassGenerator classGenerator = new ClassGenerator(classDefinition, javaGeneratorFactory); + final ClassGenerator classGenerator = new ClassGenerator(classDefinition, javaGeneratorFactory, asList(new EventAnnotationGenerator(), new FieldAndMethodGenerator())); final TypeSpec typeSpec = classGenerator.generate(); assertThat(typeSpec.annotations.size(), is(1)); @@ -71,7 +77,7 @@ public void shouldGenerateTypeSpecForClassDefinitionWithEventAnnotation() throws assertThat(typeSpec.name, is("Address")); assertThat(typeSpec.modifiers.size(), is(1)); assertThat(typeSpec.modifiers, hasItem(PUBLIC)); - assertThat(typeSpec.fieldSpecs.size(), is(1)); + assertThat(typeSpec.fieldSpecs.size(), is(0)); assertThat(typeSpec.methodSpecs.size(), is(1)); assertThat(typeSpec.methodSpecs, hasItem(constructorBuilder().addModifiers(PUBLIC).build())); } @@ -96,13 +102,13 @@ public void shouldGenerateTypeSpecForClassDefinitionWithOneField() throws Except when(fieldGenerator.generateField()).thenReturn(fieldSpec); when(fieldGenerator.generateMethods()).thenReturn(Stream.of(methodSpec)); - final ClassGenerator classGenerator = new ClassGenerator(classDefinition, javaGeneratorFactory); + final ClassGenerator classGenerator = new ClassGenerator(classDefinition, javaGeneratorFactory, singletonList(new FieldAndMethodGenerator())); final TypeSpec typeSpec = classGenerator.generate(); assertThat(typeSpec.name, is("Address")); assertThat(typeSpec.modifiers.size(), is(1)); assertThat(typeSpec.modifiers, hasItem(PUBLIC)); - assertThat(typeSpec.fieldSpecs.size(), is(2)); + assertThat(typeSpec.fieldSpecs.size(), is(1)); assertThat(typeSpec.fieldSpecs, hasItem(fieldSpec)); assertThat(typeSpec.methodSpecs.size(), is(2)); assertThat(typeSpec.methodSpecs, hasItems( @@ -120,7 +126,7 @@ public void shouldGenerateSerializableTypeSpec() throws Exception { final ClassName className = new ClassName("org.something", "Address"); final ClassDefinition classDefinition = new ClassDefinition("address", className); - final ClassGenerator classGenerator = new ClassGenerator(classDefinition, javaGeneratorFactory); + final ClassGenerator classGenerator = new ClassGenerator(classDefinition, javaGeneratorFactory, singletonList(new SerializableGenerator())); final TypeSpec typeSpec = classGenerator.generate(); assertThat(typeSpec.superinterfaces.size(), is(1)); @@ -135,7 +141,7 @@ public void shouldReturnClassName() throws Exception { final ClassName className = new ClassName("org.something", "Address"); final ClassDefinition classDefinition = new ClassDefinition("address", className); - final ClassGenerator classGenerator = new ClassGenerator(classDefinition, javaGeneratorFactory); + final ClassGenerator classGenerator = new ClassGenerator(classDefinition, javaGeneratorFactory, emptyList()); assertThat(classGenerator.getClassName(), is(className)); } diff --git a/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/generators/JavaGeneratorFactoryTest.java b/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/generators/JavaGeneratorFactoryTest.java index 666f073..e9811a1 100644 --- a/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/generators/JavaGeneratorFactoryTest.java +++ b/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/generators/JavaGeneratorFactoryTest.java @@ -51,7 +51,7 @@ public void shouldReturnListOfClassGeneratorAndEnumGeneratorForClassDefintionAnd new ClassDefinition("test1", mock(ClassName.class)), new EnumDefinition("test2", mock(ClassName.class), emptyList())); - final List classGeneratables = new JavaGeneratorFactory().createClassGeneratorsFor(classDefinitions); + final List classGeneratables = new JavaGeneratorFactory().createClassGeneratorsFor(classDefinitions, emptyList()); assertThat(classGeneratables.size(), is(2)); assertThat(classGeneratables, hasItems(instanceOf(ClassGenerator.class), instanceOf(EnumGenerator.class))); @@ -59,7 +59,7 @@ public void shouldReturnListOfClassGeneratorAndEnumGeneratorForClassDefintionAnd @Test public void shouldReturnEmptyListForEmptyListOfDefinitions() throws Exception { - final List classGeneratables = new JavaGeneratorFactory().createClassGeneratorsFor(emptyList()); + final List classGeneratables = new JavaGeneratorFactory().createClassGeneratorsFor(emptyList(), emptyList()); assertThat(classGeneratables.isEmpty(), is(true)); } @@ -74,7 +74,7 @@ public void shouldIgnoreDefinitionsThatAreNotClassDefinitionOrEnumDefinition() t new FieldDefinition("field2", mock(ClassName.class)) ); - final List classGeneratables = new JavaGeneratorFactory().createClassGeneratorsFor(classDefinitions); + final List classGeneratables = new JavaGeneratorFactory().createClassGeneratorsFor(classDefinitions, emptyList()); assertThat(classGeneratables.size(), is(2)); assertThat(classGeneratables, hasItems(instanceOf(ClassGenerator.class), instanceOf(EnumGenerator.class))); diff --git a/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/write/SourceWriterTest.java b/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/write/SourceWriterTest.java index d48b051..4399d13 100644 --- a/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/write/SourceWriterTest.java +++ b/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/write/SourceWriterTest.java @@ -1,5 +1,6 @@ package uk.gov.justice.generation.pojo.write; +import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static org.apache.commons.io.FileUtils.cleanDirectory; import static org.hamcrest.CoreMatchers.instanceOf; @@ -42,7 +43,7 @@ public void shouldWriteASingleSourceFile() throws Exception { final ClassDefinition addressDefinition = addressDefinition(packageName); new JavaGeneratorFactory() - .createClassGeneratorsFor(singletonList(addressDefinition)) + .createClassGeneratorsFor(singletonList(addressDefinition), emptyList()) .forEach(classGeneratable -> sourceWriter.write(classGeneratable, sourceOutputDirectory.toPath())); assertThat(sourceOutputDirectory.toPath().resolve("org/bloggs/fred/Address.java").toFile().exists(), is(true)); @@ -58,7 +59,7 @@ public void shouldThrowExceptionIfUnableToWriteJavaFile() throws Exception { try { new JavaGeneratorFactory() - .createClassGeneratorsFor(singletonList(addressDefinition)) + .createClassGeneratorsFor(singletonList(addressDefinition), emptyList()) .forEach(classGeneratable -> sourceWriter.write(classGeneratable, sourceOutputDirectory.toPath())); fail();