diff --git a/README.md b/README.md
index 4d8c279..f4a14a4 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
# JavaForger
[](https://travis-ci.com/daanvdh/JavaForger)
+[](https://gitter.im/JavaForger/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
JavaForger can create source code from templates using existing java classes as input.
It reads field, methods and other class data to fill in variables in a template.
diff --git a/pom.xml b/pom.xml
index 19ee733..a3ea191 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
com.github.daanvdh.javaforger
JavaForger
- 2.0.2
+ 2.0.3
jar
JavaForger
@@ -150,7 +150,7 @@
junit
junit
- 4.12
+ 4.13.1
test
diff --git a/src/main/java/templateInput/ClassContainer.java b/src/main/java/templateInput/ClassContainer.java
index e5d57d0..0bea061 100644
--- a/src/main/java/templateInput/ClassContainer.java
+++ b/src/main/java/templateInput/ClassContainer.java
@@ -18,10 +18,15 @@
package templateInput;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
import templateInput.definition.ClassDefinition;
import templateInput.definition.MethodDefinition;
+import templateInput.definition.TypeDefinition;
import templateInput.definition.VariableDefinition;
/**
@@ -62,6 +67,14 @@ public void setMethods(List extends MethodDefinition> methods) {
this.methods = methods;
}
+ public List extends MethodDefinition> getGetters() {
+ return methods.stream().filter(this::isGetter).collect(Collectors.toList());
+ }
+
+ public List extends MethodDefinition> getSetters() {
+ return methods.stream().filter(this::isSetter).collect(Collectors.toList());
+ }
+
public List extends MethodDefinition> getConstructors() {
return constructors;
}
@@ -70,4 +83,32 @@ public void setConstructors(List constructors) {
this.constructors = constructors;
}
+ public List getFieldImports() {
+ return getTypeImports(fields);
+ }
+
+ public List getMethodImports() {
+ return getTypeImports(methods);
+ }
+
+ public Set getImports() {
+ Set set = new HashSet<>();
+ set.addAll(getMethodImports());
+ set.addAll(getFieldImports());
+ return set;
+ }
+
+ private List getTypeImports(final List extends TypeDefinition> methods2) {
+ return methods2.stream().map(TypeDefinition::getTypeImports).flatMap(Collection::stream).distinct().collect(Collectors.toList());
+ }
+
+ private boolean isGetter(MethodDefinition m) {
+ String n = m.getName().toString();
+ return n.startsWith("get") || n.startsWith("is");
+ }
+
+ private boolean isSetter(MethodDefinition m) {
+ return m.getName().toString().startsWith("set");
+ }
+
}
diff --git a/src/main/resources/templates/innerBuilder.javat b/src/main/resources/templates/innerBuilder.javat
index 1df1846..4801764 100644
--- a/src/main/resources/templates/innerBuilder.javat
+++ b/src/main/resources/templates/innerBuilder.javat
@@ -30,6 +30,18 @@
private Builder() {
// Builder should only be constructed via the parent class
}
+
+ public Builder copy(${class.name} original) {
+ <#list fields as field>
+ <#if field.collection >
+ this.${field.name}.clear();
+ this.${field.name}.addAll(original.get${field.name.upperFirst}());
+ <#else>
+ this.${field.name} = original.get${field.name.upperFirst}();
+ #if>
+ #list>
+ return this;
+ }
<#list fields as field>
public Builder ${field.name}(${field.type} ${field.name}) {
diff --git a/src/main/resources/templates/innerBuilderTest.javat b/src/main/resources/templates/innerBuilderTest.javat
index 86110b1..6bcb08e 100644
--- a/src/main/resources/templates/innerBuilderTest.javat
+++ b/src/main/resources/templates/innerBuilderTest.javat
@@ -25,7 +25,16 @@ import org.junit.Test;
@Test
public void test${class.name}_maximum() {
${class.name} ${class.name.lowerFirst} = createAndFillBuilder().build();
-
+ assertMaximum(${class.name.lowerFirst});
+ }
+
+ @Test
+ public void test${class.name}_Copy() {
+ ${class.name} ${class.name.lowerFirst} = ${class.name}.builder().copy(createAndFillBuilder().build()).build();
+ assertMaximum(${class.name.lowerFirst});
+ }
+
+ private void assertMaximum(${class.name} ${class.name.lowerFirst}) {
<#list fields as field>
<#if field.type == "boolean">
Assert.assertTrue("Unexpected ${field.name}", ${class.name.lowerFirst}.${field.getter}());
diff --git a/src/test/resources/templateTestOutcomes/verify-innerBuilder.java b/src/test/resources/templateTestOutcomes/verify-innerBuilder.java
index 7b410b1..113ba34 100644
--- a/src/test/resources/templateTestOutcomes/verify-innerBuilder.java
+++ b/src/test/resources/templateTestOutcomes/verify-innerBuilder.java
@@ -91,6 +91,15 @@ public static final class Builder {
private Builder() {
// Builder should only be constructed via the parent class
}
+
+ public Builder copy(ClassWithEverything original) {
+ this.prod.clear();
+ this.prod.addAll(original.getProd());
+ this.i = original.getI();
+ this.c = original.getC();
+ this.s = original.getS();
+ return this;
+ }
public Builder prod(Set prod) {
this.prod.clear();
diff --git a/src/test/resources/templateTestOutcomes/verify-innerBuilderTest.java b/src/test/resources/templateTestOutcomes/verify-innerBuilderTest.java
index 79bd509..04800dd 100644
--- a/src/test/resources/templateTestOutcomes/verify-innerBuilderTest.java
+++ b/src/test/resources/templateTestOutcomes/verify-innerBuilderTest.java
@@ -45,7 +45,14 @@ public void testClassWithEverything_minimum() {
@Test
public void testClassWithEverything_maximum() {
ClassWithEverything classWithEverything = createAndFillBuilder().build();
-
+ assertMaximum(classWithEverything);
+ }
+ @Test
+ public void testClassWithEverything_Copy() {
+ ClassWithEverything classWithEverything = ClassWithEverything.builder().copy(createAndFillBuilder().build()).build();
+ assertMaximum(classWithEverything);
+ }
+ private void assertMaximum(ClassWithEverything classWithEverything) {
Assert.assertEquals("Unexpected prod", PROD, classWithEverything.getProd());
Assert.assertEquals("Unexpected i", I, classWithEverything.getI());
Assert.assertEquals("Unexpected c", C, classWithEverything.getC());