@Test public void emptyCustomBuilderNameIsNotValid() { when(buildableAnnotation.value()).thenReturn(""); boolean valid = buildableValidator.validate(element); verify(messager).printMessage(any(Kind.class), anyString(), any(Element.class), any(AnnotationMirror.class), any(AnnotationValue.class)); assertFalse(valid); }
public boolean validate(TypeElement element) { IsValid valid = new IsValid(); if (element.getKind() != ElementKind.CLASS) { valid.invalidate(); printBuildableError(element, "%s can only be used on class"); } if (element.getEnclosingElement().getKind() != ElementKind.PACKAGE) { valid.invalidate(); printBuildableError(element, "%s can only be used on a top-level class, no inner class please"); } if (element.getModifiers().contains(Modifier.ABSTRACT)) { valid.invalidate(); printBuildableError(element, "%s cannot be used on an abstract class"); } Buildable buildableAnnotation = element.getAnnotation(Buildable.class); String builderNameSuffix = buildableAnnotation.value(); if ("".equals(builderNameSuffix)) { valid.invalidate(); AnnotationMirror annotationMirror = findAnnotationMirror(element, Buildable.class); AnnotationValue annotationValue = annotationMirror.getElementValues().values().iterator().next(); processingEnv.getMessager().printMessage(Kind.ERROR, "The builder name suffix should not be an empty String", element, annotationMirror, annotationValue); } Set<ExecutableElement> constructors = elementHelper.findAccessibleConstructors(element); if (constructors.size() == 0) { valid.invalidate(); printBuildableError(element, "No accessible constructor found. Please provide at least one not private constructor."); } else { ExecutableElement builderConstructor = null; if (constructors.size() == 1) { builderConstructor = constructors.iterator().next(); } else { Set<ExecutableElement> builderConstructors = elementHelper.findBuilderConstructors(constructors); if (builderConstructors.size() == 0) { valid.invalidate(); String message = "Multiple constructor candidates found. Please use @" + Build.class.getSimpleName() + " annotation on the selected constructor."; printBuildableError(element, message); for (ExecutableElement constructor : constructors) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, constructor); } } else if (builderConstructors.size() > 1) { valid.invalidate(); for (ExecutableElement constructor : builderConstructors) { printBuildError(constructor, "%s should not be used more than once in a class."); } } else { builderConstructor = builderConstructors.iterator().next(); } } if (builderConstructor != null) { List<? extends TypeMirror> thrownTypes = builderConstructor.getThrownTypes(); if (thrownTypes.size() > 0) { Types typeUtils = processingEnv.getTypeUtils(); Elements elementUtils = processingEnv.getElementUtils(); TypeElement exceptionElement = elementUtils.getTypeElement(Exception.class.getName()); TypeMirror exceptionMirror = exceptionElement.asType(); for (TypeMirror thrownType : thrownTypes) { if (!typeUtils.isSubtype(thrownType, exceptionMirror)) { valid.invalidate(); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "The constructor used by the builder can only throw subtypes of Exception", builderConstructor); } } } } } return valid.isValid(); }
BuildableValidator { public boolean validate(TypeElement element) { IsValid valid = new IsValid(); if (element.getKind() != ElementKind.CLASS) { valid.invalidate(); printBuildableError(element, "%s can only be used on class"); } if (element.getEnclosingElement().getKind() != ElementKind.PACKAGE) { valid.invalidate(); printBuildableError(element, "%s can only be used on a top-level class, no inner class please"); } if (element.getModifiers().contains(Modifier.ABSTRACT)) { valid.invalidate(); printBuildableError(element, "%s cannot be used on an abstract class"); } Buildable buildableAnnotation = element.getAnnotation(Buildable.class); String builderNameSuffix = buildableAnnotation.value(); if ("".equals(builderNameSuffix)) { valid.invalidate(); AnnotationMirror annotationMirror = findAnnotationMirror(element, Buildable.class); AnnotationValue annotationValue = annotationMirror.getElementValues().values().iterator().next(); processingEnv.getMessager().printMessage(Kind.ERROR, "The builder name suffix should not be an empty String", element, annotationMirror, annotationValue); } Set<ExecutableElement> constructors = elementHelper.findAccessibleConstructors(element); if (constructors.size() == 0) { valid.invalidate(); printBuildableError(element, "No accessible constructor found. Please provide at least one not private constructor."); } else { ExecutableElement builderConstructor = null; if (constructors.size() == 1) { builderConstructor = constructors.iterator().next(); } else { Set<ExecutableElement> builderConstructors = elementHelper.findBuilderConstructors(constructors); if (builderConstructors.size() == 0) { valid.invalidate(); String message = "Multiple constructor candidates found. Please use @" + Build.class.getSimpleName() + " annotation on the selected constructor."; printBuildableError(element, message); for (ExecutableElement constructor : constructors) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, constructor); } } else if (builderConstructors.size() > 1) { valid.invalidate(); for (ExecutableElement constructor : builderConstructors) { printBuildError(constructor, "%s should not be used more than once in a class."); } } else { builderConstructor = builderConstructors.iterator().next(); } } if (builderConstructor != null) { List<? extends TypeMirror> thrownTypes = builderConstructor.getThrownTypes(); if (thrownTypes.size() > 0) { Types typeUtils = processingEnv.getTypeUtils(); Elements elementUtils = processingEnv.getElementUtils(); TypeElement exceptionElement = elementUtils.getTypeElement(Exception.class.getName()); TypeMirror exceptionMirror = exceptionElement.asType(); for (TypeMirror thrownType : thrownTypes) { if (!typeUtils.isSubtype(thrownType, exceptionMirror)) { valid.invalidate(); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "The constructor used by the builder can only throw subtypes of Exception", builderConstructor); } } } } } return valid.isValid(); } }
BuildableValidator { public boolean validate(TypeElement element) { IsValid valid = new IsValid(); if (element.getKind() != ElementKind.CLASS) { valid.invalidate(); printBuildableError(element, "%s can only be used on class"); } if (element.getEnclosingElement().getKind() != ElementKind.PACKAGE) { valid.invalidate(); printBuildableError(element, "%s can only be used on a top-level class, no inner class please"); } if (element.getModifiers().contains(Modifier.ABSTRACT)) { valid.invalidate(); printBuildableError(element, "%s cannot be used on an abstract class"); } Buildable buildableAnnotation = element.getAnnotation(Buildable.class); String builderNameSuffix = buildableAnnotation.value(); if ("".equals(builderNameSuffix)) { valid.invalidate(); AnnotationMirror annotationMirror = findAnnotationMirror(element, Buildable.class); AnnotationValue annotationValue = annotationMirror.getElementValues().values().iterator().next(); processingEnv.getMessager().printMessage(Kind.ERROR, "The builder name suffix should not be an empty String", element, annotationMirror, annotationValue); } Set<ExecutableElement> constructors = elementHelper.findAccessibleConstructors(element); if (constructors.size() == 0) { valid.invalidate(); printBuildableError(element, "No accessible constructor found. Please provide at least one not private constructor."); } else { ExecutableElement builderConstructor = null; if (constructors.size() == 1) { builderConstructor = constructors.iterator().next(); } else { Set<ExecutableElement> builderConstructors = elementHelper.findBuilderConstructors(constructors); if (builderConstructors.size() == 0) { valid.invalidate(); String message = "Multiple constructor candidates found. Please use @" + Build.class.getSimpleName() + " annotation on the selected constructor."; printBuildableError(element, message); for (ExecutableElement constructor : constructors) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, constructor); } } else if (builderConstructors.size() > 1) { valid.invalidate(); for (ExecutableElement constructor : builderConstructors) { printBuildError(constructor, "%s should not be used more than once in a class."); } } else { builderConstructor = builderConstructors.iterator().next(); } } if (builderConstructor != null) { List<? extends TypeMirror> thrownTypes = builderConstructor.getThrownTypes(); if (thrownTypes.size() > 0) { Types typeUtils = processingEnv.getTypeUtils(); Elements elementUtils = processingEnv.getElementUtils(); TypeElement exceptionElement = elementUtils.getTypeElement(Exception.class.getName()); TypeMirror exceptionMirror = exceptionElement.asType(); for (TypeMirror thrownType : thrownTypes) { if (!typeUtils.isSubtype(thrownType, exceptionMirror)) { valid.invalidate(); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "The constructor used by the builder can only throw subtypes of Exception", builderConstructor); } } } } } return valid.isValid(); } BuildableValidator(ProcessingEnvironment processingEnv, ElementHelper elementHelper); }
BuildableValidator { public boolean validate(TypeElement element) { IsValid valid = new IsValid(); if (element.getKind() != ElementKind.CLASS) { valid.invalidate(); printBuildableError(element, "%s can only be used on class"); } if (element.getEnclosingElement().getKind() != ElementKind.PACKAGE) { valid.invalidate(); printBuildableError(element, "%s can only be used on a top-level class, no inner class please"); } if (element.getModifiers().contains(Modifier.ABSTRACT)) { valid.invalidate(); printBuildableError(element, "%s cannot be used on an abstract class"); } Buildable buildableAnnotation = element.getAnnotation(Buildable.class); String builderNameSuffix = buildableAnnotation.value(); if ("".equals(builderNameSuffix)) { valid.invalidate(); AnnotationMirror annotationMirror = findAnnotationMirror(element, Buildable.class); AnnotationValue annotationValue = annotationMirror.getElementValues().values().iterator().next(); processingEnv.getMessager().printMessage(Kind.ERROR, "The builder name suffix should not be an empty String", element, annotationMirror, annotationValue); } Set<ExecutableElement> constructors = elementHelper.findAccessibleConstructors(element); if (constructors.size() == 0) { valid.invalidate(); printBuildableError(element, "No accessible constructor found. Please provide at least one not private constructor."); } else { ExecutableElement builderConstructor = null; if (constructors.size() == 1) { builderConstructor = constructors.iterator().next(); } else { Set<ExecutableElement> builderConstructors = elementHelper.findBuilderConstructors(constructors); if (builderConstructors.size() == 0) { valid.invalidate(); String message = "Multiple constructor candidates found. Please use @" + Build.class.getSimpleName() + " annotation on the selected constructor."; printBuildableError(element, message); for (ExecutableElement constructor : constructors) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, constructor); } } else if (builderConstructors.size() > 1) { valid.invalidate(); for (ExecutableElement constructor : builderConstructors) { printBuildError(constructor, "%s should not be used more than once in a class."); } } else { builderConstructor = builderConstructors.iterator().next(); } } if (builderConstructor != null) { List<? extends TypeMirror> thrownTypes = builderConstructor.getThrownTypes(); if (thrownTypes.size() > 0) { Types typeUtils = processingEnv.getTypeUtils(); Elements elementUtils = processingEnv.getElementUtils(); TypeElement exceptionElement = elementUtils.getTypeElement(Exception.class.getName()); TypeMirror exceptionMirror = exceptionElement.asType(); for (TypeMirror thrownType : thrownTypes) { if (!typeUtils.isSubtype(thrownType, exceptionMirror)) { valid.invalidate(); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "The constructor used by the builder can only throw subtypes of Exception", builderConstructor); } } } } } return valid.isValid(); } BuildableValidator(ProcessingEnvironment processingEnv, ElementHelper elementHelper); boolean validate(TypeElement element); }
BuildableValidator { public boolean validate(TypeElement element) { IsValid valid = new IsValid(); if (element.getKind() != ElementKind.CLASS) { valid.invalidate(); printBuildableError(element, "%s can only be used on class"); } if (element.getEnclosingElement().getKind() != ElementKind.PACKAGE) { valid.invalidate(); printBuildableError(element, "%s can only be used on a top-level class, no inner class please"); } if (element.getModifiers().contains(Modifier.ABSTRACT)) { valid.invalidate(); printBuildableError(element, "%s cannot be used on an abstract class"); } Buildable buildableAnnotation = element.getAnnotation(Buildable.class); String builderNameSuffix = buildableAnnotation.value(); if ("".equals(builderNameSuffix)) { valid.invalidate(); AnnotationMirror annotationMirror = findAnnotationMirror(element, Buildable.class); AnnotationValue annotationValue = annotationMirror.getElementValues().values().iterator().next(); processingEnv.getMessager().printMessage(Kind.ERROR, "The builder name suffix should not be an empty String", element, annotationMirror, annotationValue); } Set<ExecutableElement> constructors = elementHelper.findAccessibleConstructors(element); if (constructors.size() == 0) { valid.invalidate(); printBuildableError(element, "No accessible constructor found. Please provide at least one not private constructor."); } else { ExecutableElement builderConstructor = null; if (constructors.size() == 1) { builderConstructor = constructors.iterator().next(); } else { Set<ExecutableElement> builderConstructors = elementHelper.findBuilderConstructors(constructors); if (builderConstructors.size() == 0) { valid.invalidate(); String message = "Multiple constructor candidates found. Please use @" + Build.class.getSimpleName() + " annotation on the selected constructor."; printBuildableError(element, message); for (ExecutableElement constructor : constructors) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, constructor); } } else if (builderConstructors.size() > 1) { valid.invalidate(); for (ExecutableElement constructor : builderConstructors) { printBuildError(constructor, "%s should not be used more than once in a class."); } } else { builderConstructor = builderConstructors.iterator().next(); } } if (builderConstructor != null) { List<? extends TypeMirror> thrownTypes = builderConstructor.getThrownTypes(); if (thrownTypes.size() > 0) { Types typeUtils = processingEnv.getTypeUtils(); Elements elementUtils = processingEnv.getElementUtils(); TypeElement exceptionElement = elementUtils.getTypeElement(Exception.class.getName()); TypeMirror exceptionMirror = exceptionElement.asType(); for (TypeMirror thrownType : thrownTypes) { if (!typeUtils.isSubtype(thrownType, exceptionMirror)) { valid.invalidate(); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "The constructor used by the builder can only throw subtypes of Exception", builderConstructor); } } } } } return valid.isValid(); } BuildableValidator(ProcessingEnvironment processingEnv, ElementHelper elementHelper); boolean validate(TypeElement element);  }