Skip to content

Commit

Permalink
Removed checks for lombok specific annotations in BeanUtils (Lombok m…
Browse files Browse the repository at this point in the history
…ust take care itself that its Java standard comform)
  • Loading branch information
tobiasstamann committed Jan 9, 2024
1 parent 1387732 commit 76af93e
Show file tree
Hide file tree
Showing 15 changed files with 140 additions and 994 deletions.
9 changes: 1 addition & 8 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@
<junit.version>4.13.2</junit.version>
<hamcrest.version>2.2</hamcrest.version>
<mockito.version>4.3.1</mockito.version>
<lombok.version>1.18.30</lombok.version>

<!-- sonatype url-->
<sonatype-oss-dist-mgmt-snapshots-url>https://oss.sonatype.org/content/repositories/snapshots/
Expand Down Expand Up @@ -689,13 +688,7 @@

<dependencies>

<!-- compile support of lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>



<!-- Test dependencies -->
Expand Down
125 changes: 44 additions & 81 deletions tools/src/main/java/io/toolisticon/aptk/tools/BeanUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.toolisticon.aptk.tools.corematcher.AptkCoreMatchers;
import io.toolisticon.aptk.tools.fluentfilter.FluentElementFilter;
import io.toolisticon.aptk.tools.fluentvalidator.FluentElementValidator;
import io.toolisticon.aptk.tools.wrapper.TypeElementWrapper;
import io.toolisticon.aptk.tools.wrapper.VariableElementWrapper;

import javax.lang.model.element.ElementKind;
Expand All @@ -15,7 +16,10 @@
import javax.lang.model.type.TypeMirror;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;

/**
Expand Down Expand Up @@ -166,7 +170,7 @@ public static boolean isDefaultNoargConstructor(ExecutableElement element) {
return false;
}

return Pattern.compile("^\\s*super\\(\\)[;]{0,1}\\s*$").matcher(statements.get(0).toString()).matches();
return Pattern.compile("^\\s*super\\(\\);?\\s*$").matcher(statements.get(0).toString()).matches();

}

Expand All @@ -176,12 +180,21 @@ public static boolean isAttribute(VariableElement field) {

}

public static AttributeResult[] getAttributesWithInheritance(TypeElement typeElement) {
List<AttributeResult> resultList = new ArrayList<>(Arrays.asList(GetAttributesCommand.INSTANCE.execute(typeElement)));
public static AttributeResult[] getAttributesWithInheritance(TypeElement typeElement, TypeMirrorWrapper... typeArguments) {


// this doesn't support getting generic fields in parent classes
List<AttributeResult> resultList = new ArrayList<>(Arrays.asList(GetAttributesCommand.createCommand().execute(typeElement)));

// process super types
for (TypeElement superTypeElement : ElementUtils.AccessTypeHierarchy.getSuperTypeElementsOfKindType(typeElement)) {
resultList.addAll(Arrays.asList(GetAttributesCommand.INSTANCE.execute(superTypeElement)));
TypeElementWrapper wrappedSuperTypeElement = TypeElementWrapper.wrap(superTypeElement);
Map<String, TypeMirrorWrapper> resolvedTypeArgumentMap = new HashMap<>();
if (wrappedSuperTypeElement.hasTypeParameters()) {
List<TypeMirrorWrapper> resolvedTypeArgumentTypes = InterfaceUtils.getResolvedTypeArgumentOfSuperTypeOrInterface(TypeElementWrapper.wrap(typeElement), TypeMirrorWrapper.wrap(superTypeElement), typeArguments);
resolvedTypeArgumentMap = InterfaceUtils.mapTypeVars(wrappedSuperTypeElement, resolvedTypeArgumentTypes.toArray(new TypeMirrorWrapper[0]));
}
resultList.addAll(Arrays.asList(GetAttributesCommand.createCommand(resolvedTypeArgumentMap).execute(superTypeElement)));
}

return resultList.toArray(new AttributeResult[0]);
Expand All @@ -204,18 +217,18 @@ public static AttributeResult[] getAttributes(TypeElement typeElement) {

for (VariableElement field : fields) {

AttributeResult attributeResult = new AttributeResult();
attributeResult.setField(VariableElementWrapper.wrap(field));

String getterMethodName = BeanUtils.getGetterMethodName(field);
attributeResult.setGetterMethodName(BeanUtils.getGetterMethodName(field));
attributeResult.setSetterMethodName(BeanUtils.getSetterMethodName(field));


// just add those fields with both getters and setters
if (attributeResult.hasGetter() && attributeResult.hasSetter()) {
Optional<String> getterMethodName = BeanUtils.getGetterMethodName(field);
Optional<String> setterMethodName = BeanUtils.getSetterMethodName(field);
if (getterMethodName.isPresent() && setterMethodName.isPresent()) {

AttributeResult attributeResult = new AttributeResult();
attributeResult.setField(VariableElementWrapper.wrap(field));
attributeResult.setGetterMethodName(getterMethodName.get());
attributeResult.setSetterMethodName(setterMethodName.get());
result.add(attributeResult);
}

}

return result.toArray(new AttributeResult[0]);
Expand All @@ -236,14 +249,10 @@ public static boolean checkHasGetter(VariableElement field) {
return false;
}

TypeElement typeElement = ElementUtils.AccessEnclosingElements.<TypeElement>getFirstEnclosingElementOfKind(field, ElementKind.CLASS);
TypeElement typeElement = ElementUtils.AccessEnclosingElements.getFirstEnclosingElementOfKind(field, ElementKind.CLASS);


return checkLombokDataAnnotation(typeElement)
|| checkLombokGetterAnnotationOnType(typeElement)
|| checkLombokGetterAnnotationOnField(field)
|| checkHasGetterMethod(field, typeElement)
;
return checkHasGetterMethod(field, typeElement);

}

Expand All @@ -260,84 +269,38 @@ public static boolean checkHasSetter(VariableElement field) {
return false;
}

TypeElement typeElement = ElementUtils.AccessEnclosingElements.<TypeElement>getFirstEnclosingElementOfKind(field, ElementKind.CLASS);
TypeElement typeElement = ElementUtils.AccessEnclosingElements.getFirstEnclosingElementOfKind(field, ElementKind.CLASS);


return checkLombokDataAnnotation(typeElement)
|| checkLombokSetterAnnotationOnType(typeElement)
return checkLombokSetterAnnotationOnType(typeElement)
|| checkLombokSetterAnnotationOnField(field)
|| checkHasSetterMethod(field, typeElement)
;

}

/**
* Checks if lombok.Data annotation is present on passed TypeElement.
*
* @param typeElement the TypeElement to check
* @return true if Data annotation can be found on passed typeElement otherwise false
*/
public static boolean checkLombokDataAnnotation(TypeElement typeElement) {

return AnnotationUtils.getAnnotationMirror(typeElement, "lombok.Data") != null;

}

/**
* Checks if lombok.Getter annotation is present on passed TypeElement.
*
* @param typeElement the TypeElement to check
* @return true if Getter annotation can be found on passed TypeElement otherwise false
*/
public static boolean checkLombokGetterAnnotationOnType(TypeElement typeElement) {

return AnnotationUtils.getAnnotationMirror(typeElement, "lombok.Getter") != null;

}

/**
* Checks if lombok.Getter annotation is present on passed TypeElement.
*
* @param variableElement the VariableElement to check
* @return true if Getter annotation can be found on passed VariableElement otherwise false
*/
public static boolean checkLombokGetterAnnotationOnField(VariableElement variableElement) {

return AnnotationUtils.getAnnotationMirror(variableElement, "lombok.Getter") != null;

}


/**
* Get the getters method name.
*
* @param field The field
* @return the getters method name or null if field has no getter
*/
public static String getGetterMethodName(VariableElement field) {
public static Optional<String> getGetterMethodName(VariableElement field) {

if (field == null || field.getKind() != ElementKind.FIELD) {
return null;
return Optional.empty();
}

TypeElement typeElement = (TypeElement) ElementUtils.AccessEnclosingElements.getFirstEnclosingElementOfKind(field, ElementKind.CLASS);

TypeElement typeElement = ElementUtils.AccessEnclosingElements.getFirstEnclosingElementOfKind(field, ElementKind.CLASS);

ExecutableElement getterMethod = getGetterMethod(field, typeElement);

if (getterMethod != null) {
return getterMethod.getSimpleName().toString();
}

if (checkLombokDataAnnotation(typeElement)
|| checkLombokGetterAnnotationOnType(typeElement)
|| checkLombokGetterAnnotationOnField(field)) {

return TypeUtils.TypeComparison.isTypeEqual(field.asType(), TypeUtils.TypeRetrieval.getTypeMirror(boolean.class)) ? getPrefixedName("is", field.getSimpleName().toString()) : getPrefixedName("get", field.getSimpleName().toString());

return Optional.of(getterMethod.getSimpleName().toString());
}

return null;
return Optional.empty();
}

/**
Expand All @@ -346,12 +309,12 @@ public static String getGetterMethodName(VariableElement field) {
* @param field the fields VariableElement
* @return the name of the setter method
*/
public static String getSetterMethodName(VariableElement field) {
public static Optional<String> getSetterMethodName(VariableElement field) {
if (field == null || field.getKind() != ElementKind.FIELD) {
return null;
return Optional.empty();
}

return checkHasSetter(field) ? getPrefixedName("set", field.getSimpleName().toString()) : null;
return checkHasSetter(field) ? Optional.of(getPrefixedName("set", field.getSimpleName().toString())) : Optional.empty();
}

/**
Expand All @@ -361,13 +324,13 @@ public static String getSetterMethodName(VariableElement field) {
* @param typeElement the TypeElement
* @return true if field has a getter method, otherwise false
*/
protected static boolean checkHasGetterMethod(VariableElement field, TypeElement typeElement) {
static boolean checkHasGetterMethod(VariableElement field, TypeElement typeElement) {

return getGetterMethod(field, ElementUtils.AccessEnclosingElements.<TypeElement>getFirstEnclosingElementOfKind(field, ElementKind.CLASS)) != null;
return getGetterMethod(field, ElementUtils.AccessEnclosingElements.getFirstEnclosingElementOfKind(field, ElementKind.CLASS)) != null;

}

protected static ExecutableElement getGetterMethod(VariableElement field, TypeElement typeElement) {
static ExecutableElement getGetterMethod(VariableElement field, TypeElement typeElement) {
List<ExecutableElement> result = FluentElementFilter.createFluentElementFilter(typeElement.getEnclosedElements())
.applyFilter(AptkCoreMatchers.IS_METHOD)
.applyFilter(AptkCoreMatchers.BY_MODIFIER).filterByAllOf(Modifier.PUBLIC)
Expand All @@ -380,15 +343,15 @@ protected static ExecutableElement getGetterMethod(VariableElement field, TypeEl
return result.size() >= 1 ? result.get(0) : null;
}

protected static boolean checkHasSetterMethod(VariableElement field, TypeElement typeElement) {
static boolean checkHasSetterMethod(VariableElement field, TypeElement typeElement) {


return getSetterMethod(field, typeElement) != null;


}

protected static ExecutableElement getSetterMethod(VariableElement field, TypeElement typeElement) {
static ExecutableElement getSetterMethod(VariableElement field, TypeElement typeElement) {

TypeMirror[] parameters = {field.asType()};

Expand All @@ -404,7 +367,7 @@ protected static ExecutableElement getSetterMethod(VariableElement field, TypeEl
return result.size() >= 1 ? result.get(0) : null;
}

protected static String[] getPossibleGetterOrSetterNames(VariableElement field, String[] prefixes) {
static String[] getPossibleGetterOrSetterNames(VariableElement field, String[] prefixes) {
String[] result = new String[prefixes.length];

for (int i = 0; i < prefixes.length; i++) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
package io.toolisticon.aptk.tools.command.impl;

import io.toolisticon.aptk.tools.command.CommandWithReturnType;
import io.toolisticon.aptk.tools.BeanUtils;
import io.toolisticon.aptk.tools.BeanUtils.AttributeResult;
import io.toolisticon.aptk.tools.TypeMirrorWrapper;
import io.toolisticon.aptk.tools.command.CommandWithReturnType;

import javax.lang.model.element.TypeElement;
import java.util.HashMap;
import java.util.Map;

/**
* Get all attributes of passed TypeElement.
* attribute = field with adequate getter and setter method
*/
public class GetAttributesCommand implements CommandWithReturnType<TypeElement, AttributeResult[]> {

public final static GetAttributesCommand INSTANCE = new GetAttributesCommand();
private final Map<String, TypeMirrorWrapper> resolvedTypeArgumentMap;

public GetAttributesCommand(Map<String, TypeMirrorWrapper> resolvedTypeArgumentMap) {
this.resolvedTypeArgumentMap = resolvedTypeArgumentMap;
}

@Override
public AttributeResult[] execute(TypeElement element) {
Expand All @@ -21,5 +28,11 @@ public AttributeResult[] execute(TypeElement element) {

}

public static GetAttributesCommand createCommand(Map<String, TypeMirrorWrapper> resolvedTypeArgumentMap) {
return new GetAttributesCommand(resolvedTypeArgumentMap);
}

public static GetAttributesCommand createCommand() {
return createCommand(new HashMap<>());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import io.toolisticon.aptk.tools.corematcher.AptkCoreMatchers;
import io.toolisticon.aptk.tools.fluentfilter.FluentElementFilter;

import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
Expand Down Expand Up @@ -117,6 +116,15 @@ public List<TypeParameterElementWrapper> getTypeParameters() {
return this.element.getTypeParameters().stream().map(TypeParameterElementWrapper::wrap).collect(Collectors.toList());
}

/**
* Checks if wrapped TypeElement has type parameters.
*
* @return true, if TypeElement has type parameters, otherwise false.
*/
public boolean hasTypeParameters() {
return getTypeParameters().size() > 0;
}

/**
* Returns an enclosed method.
* Works only if all parameter types are already compiled.
Expand Down Expand Up @@ -239,6 +247,7 @@ public Optional<TypeElementWrapper> getOuterTopLevelType() {

/**
* Gets all enum constant names of enum as VariableElements.
*
* @return A list containing all enum constant names or null if wrapped TypeElement is no enum.
*/
public List<VariableElementWrapper> getEnumValues() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeParameterElement;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -42,6 +43,15 @@ public String toStringWithExtendsAndBounds() {
List<TypeMirrorWrapper> extendedTypes = getBounds();
return toString() + (extendedTypes.size() == 0 ? "" : extendedTypes.stream().map(e -> e.getTypeDeclaration()).collect(Collectors.joining(" & ", " extends ","")));
}

/**
* Gets a Set containing the fully qualified names of all bounds.
* @return a Set containing all fqn of all bounds
*/
public Set<String> getImports() {
return getBounds().stream().map(TypeMirrorWrapper::getQualifiedName).collect(Collectors.toSet());
}

/**
* Wraps a TypeParameterElement.
* Will throw IllegalArgumentException if passed element is null.
Expand Down
Loading

0 comments on commit 76af93e

Please sign in to comment.