FieldDSLMethodBuilder.java
/**
* Powerunit - A JDK1.8 test framework
* Copyright (C) 2014 Mathieu Boretti.
*
* This file is part of Powerunit
*
* Powerunit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Powerunit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Powerunit. If not, see <http://www.gnu.org/licenses/>.
*/
package ch.powerunit.extensions.matchers.provideprocessor.fields;
import static java.util.Arrays.stream;
import static java.util.stream.Collectors.joining;
import java.util.Optional;
import ch.powerunit.extensions.matchers.provideprocessor.fields.lang.BuilderDeclaration;
import ch.powerunit.extensions.matchers.provideprocessor.fields.lang.BuilderImplementation;
import ch.powerunit.extensions.matchers.provideprocessor.fields.lang.BuilderJavadoc;
public class FieldDSLMethodBuilder {
private static final String MATCHERS = "org.hamcrest.Matchers";
private static final String DEFAULT_JAVADOCFORMAT = "/**\n" + " * %1$s\n" + " * <p>\n" + " *\n" + " * <i>%2$s</i>\n"
+ " * <p>\n"
+ " * <b>In case method specifing a matcher on a fields are used several times, only the last setted matcher will be used.</b> \n"
+ " * When several control must be done on a single field, hamcrest itself provides a way to combine several matchers.\n"
+ " * (See for instance {@link " + MATCHERS + "#both(org.hamcrest.Matcher)}.\n" + " *\n" + "%3$s"
+ " * @return the DSL to continue the construction of the matcher.\n" + "%4$s */";
public static BuilderDeclaration of(AbstractFieldDescription fieldDescription) {
return new Builder(fieldDescription);
}
public static class Builder implements BuilderDeclaration, BuilderJavadoc, BuilderImplementation {
private final AbstractFieldDescription fieldDescription;
private String declaration;
private String javadoc;
private Builder(AbstractFieldDescription fieldDescription) {
this.fieldDescription = fieldDescription;
}
@Override
public BuilderImplementation withJavaDoc(Optional<String> addToDescription, Optional<String> param,
Optional<String> see) {
javadoc = getJavaDocFor(fieldDescription, addToDescription, param, see);
return this;
}
@Override
public FieldDSLMethod havingDefault(String innerMatcher) {
return new FieldDSLMethod(buildDefaultDsl(fieldDescription, javadoc, declaration, innerMatcher), "");
}
@Override
public FieldDSLMethod havingImplementation(String body) {
return new FieldDSLMethod(buildDsl(javadoc, declaration), buildImplementation(declaration, body));
}
@Override
public BuilderJavadoc withExplicitDeclaration(String declaration) {
this.declaration = declaration;
return this;
}
@Override
public BuilderJavadoc withGenericDeclaration(String generic, String postFix, String arguments) {
this.declaration = generic + " " + String.format("%1$s %2$s%3$s(%4$s)",
fieldDescription.getDefaultReturnMethod(), fieldDescription.getFieldName(), postFix, arguments);
return this;
}
@Override
public FieldDSLMethod withExplicitDeclarationJavadocAndImplementation(String declaration,
String addToDescription, String body) {
return withExplicitDeclaration(declaration).withJavaDoc(addToDescription).havingImplementation(body);
}
@Override
public FieldDSLMethod withJavaDocAndDefault(String addToDescription, String innerMatcher) {
return withJavaDoc(addToDescription).havingDefault(innerMatcher);
}
@Override
public FieldDSLMethod withSuffixDeclarationJavadocAndDefault(String declaration, String addToDescription,
String innerMatcher) {
return withSuffixDeclaration(declaration).withJavaDocAndDefault(addToDescription, innerMatcher);
}
}
public static String getJavaDocFor(AbstractFieldDescription fieldDescription, Optional<String> addToDescription,
Optional<String> param, Optional<String> see) {
String linkToAccessor = String.format("{@link %1$s#%2$s This field is accessed by using this approach}.",
fieldDescription.getFullyQualifiedNameEnclosingClassOfField(), fieldDescription.getFieldAccessor());
String title = String.format("Add a validation on the field `%1$s`%2$s.", fieldDescription.getFieldName(),
addToDescription.map(s -> " " + s).orElse(""));
String paramString = param
.map(t -> stream(t.split("\n")).map(l -> " * @param " + l + ".\n").collect(joining()))
.orElse("");
String seeString = see.map(s -> " * @see " + s + "\n").orElse("");
return String.format(DEFAULT_JAVADOCFORMAT, title, linkToAccessor, paramString, seeString);
}
public static String buildImplementation(String declaration, String body) {
return String.format("@Override\npublic %1$s {\n %2$s\n}\n", declaration, body.replaceAll("\\R", "\n" + " "));
}
public static String buildDsl(String javadoc, String declaration) {
return String.format("%1$s\n%2$s;\n", javadoc.replaceAll("\\R", "\n"), declaration);
}
public static String buildDefaultDsl(AbstractFieldDescription fieldDescription, String javadoc, String declaration,
String innerMatcher) {
return String.format("%1$s\ndefault %2$s{\n return %3$s(%4$s);\n}", javadoc.replaceAll("\\R", "\n"),
declaration, fieldDescription.getFieldName(), innerMatcher);
}
}