Created
May 18, 2017 14:35
-
-
Save AnEmortalKid/32118ec89b6b97dcd730b30203016160 to your computer and use it in GitHub Desktop.
prints some builder code into the console
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.lang.reflect.Field; | |
import java.lang.reflect.ParameterizedType; | |
import java.lang.reflect.Type; | |
import java.text.MessageFormat; | |
import java.util.Collection; | |
public class BuilderGeneratorPrinter | |
{ | |
public static void printBuilderForClass (final String internalObjectName, final Class<?> classToCreateBuilderFor) | |
{ | |
final String header = "public static class Builder {"; | |
System.out.println(header); | |
final String isFinalizedDeclaration = " private boolean finalized = false;"; | |
System.out.println(isFinalizedDeclaration); | |
final String classSimpleName = classToCreateBuilderFor.getSimpleName(); | |
System.out.println("private " + classSimpleName + " " + internalObjectName + ";"); | |
final StringBuilder create = new StringBuilder(); | |
create.append("public static Builder create()"); | |
create.append("{"); | |
create.append("return new Builder();"); | |
create.append("}"); | |
System.out.println(create.toString()); | |
final StringBuilder constructor = new StringBuilder(); | |
constructor.append("private Builder()"); | |
constructor.append("{"); | |
constructor.append(internalObjectName + " = " + " new " + classSimpleName + "();"); | |
constructor.append("}"); | |
System.out.println(constructor); | |
final Field[] fields = classToCreateBuilderFor.getDeclaredFields(); | |
for (final Field field : fields) | |
{ | |
System.out.println(generateWith(internalObjectName, field)); | |
} | |
final StringBuilder vnfs = new StringBuilder(); | |
vnfs.append("private void verifyNotFinalizedState() {"); | |
vnfs.append("\t if(finalized) {"); | |
vnfs.append("\t\t throw new IllegalStateException(\"This builder is finalized and cannot be modified further\");"); | |
vnfs.append("\t}"); | |
vnfs.append("}"); | |
System.out.println(vnfs.toString()); | |
final StringBuilder build = new StringBuilder(); | |
build.append("public " + classSimpleName + " build() {"); | |
build.append(" if (!finalized)"); | |
build.append("\t{"); | |
build.append("\t\t finalized = true;"); | |
build.append("\t}"); | |
build.append(" return " + internalObjectName + ";"); | |
build.append("}"); | |
System.out.println(build.toString()); | |
System.out.println("}"); | |
} | |
private static String generateWith (final String internalItem, final Field field) | |
{ | |
final String fieldName = field.getName(); | |
final Class<?> fieldType = field.getType(); | |
final String methodNameTemplate = "{0}{1}"; | |
final String propertyNameFirstCap = Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1); | |
String methodName = MessageFormat.format(methodNameTemplate, "with", propertyNameFirstCap); | |
String argType = fieldType.getSimpleName(); | |
String returnType = argType; | |
String argName = field.getName(); | |
String assignmentLine = internalItem + "." + fieldName + " = " + fieldName + ";"; | |
if (Collection.class.isAssignableFrom(fieldType)) | |
{ | |
final Type genericType = field.getGenericType(); | |
final ParameterizedType paramType = (ParameterizedType) genericType; | |
final Type firstArg = paramType.getActualTypeArguments()[0]; | |
final Class firstArgClass = (Class) firstArg; | |
final String firstArgName = firstArgClass.getSimpleName(); | |
returnType = returnType + "<" + firstArgName + ">"; | |
final String noS = propertyNameFirstCap.substring(0, propertyNameFirstCap.length() - 1); | |
methodName = MessageFormat.format(methodNameTemplate, "add", noS); | |
argType = firstArgName; | |
argName = noS; | |
assignmentLine = internalItem + "." + fieldName + ".add(" + argName + ");"; | |
} | |
final StringBuilder withMethodBuilder = new StringBuilder(); | |
withMethodBuilder.append("public Builder " + methodName + "(final " + argType + " " + argName + ")"); | |
withMethodBuilder.append("{"); | |
withMethodBuilder.append("verifyNotFinalizedState();"); | |
withMethodBuilder.append(assignmentLine); | |
withMethodBuilder.append(" return this;"); | |
withMethodBuilder.append("}"); | |
return withMethodBuilder.toString(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment