Skip to content

Commit 9e14944

Browse files
committed
Minor improvements / Added some more functionality to some wrappers (i.e. checks for meta annotations, getting 'parent' package)
1 parent af5da26 commit 9e14944

11 files changed

Lines changed: 287 additions & 53 deletions

File tree

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
distribution: 'zulu'
2727
java-version: 17
2828
cache: 'maven'
29-
server-id: sonatype-nexus-staging
29+
server-id: central
3030
server-username: OSS_CENTRAL_USERNAME # env variable for Maven Central
3131
server-password: OSS_CENTRAL_PASSWORD # env variable for Maven Central
3232

pom.xml

Lines changed: 19 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@
4141
<developers>
4242
<developer>
4343
<name>Tobias Stamann</name>
44-
<email>tobias.stamann@holisticon.de</email>
45-
<organization>Holisticon AG</organization>
46-
<organizationUrl>http://holisticon.de/</organizationUrl>
44+
<email>tobias@stamann.dev</email>
45+
<organization>Tobias Stamann - IT Beratung</organization>
46+
<organizationUrl>https://stamann.dev/</organizationUrl>
4747
</developer>
4848
</developers>
4949

@@ -84,7 +84,7 @@
8484

8585
<!-- project dependency versions -->
8686
<spiap.version>0.11.0</spiap.version>
87-
<cute.version>1.7.0</cute.version>
87+
<cute.version>1.8.2</cute.version>
8888

8989
<!-- versions of test dependencies -->
9090
<junit.version>4.13.2</junit.version>
@@ -123,7 +123,7 @@
123123
<maven-versions-plugin.version>2.5</maven-versions-plugin.version>
124124

125125
<gitflow-maven-plugin.version>1.19.0</gitflow-maven-plugin.version>
126-
<nexus-staging-maven-plugin.version>1.6.13</nexus-staging-maven-plugin.version>
126+
<sonatype-centralPublishingPlugin.version>0.8.0</sonatype-centralPublishingPlugin.version>
127127

128128

129129
</properties>
@@ -247,25 +247,17 @@
247247
</executions>
248248
</plugin>
249249

250-
<plugin>
251-
<groupId>org.sonatype.plugins</groupId>
252-
<artifactId>nexus-staging-maven-plugin</artifactId>
253-
<version>${nexus-staging-maven-plugin.version}</version>
254-
<configuration>
255-
<autoReleaseAfterClose>true</autoReleaseAfterClose>
256-
<serverId>sonatype-nexus-staging</serverId>
257-
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
258-
</configuration>
259-
<executions>
260-
<execution>
261-
<id>default-deploy</id>
262-
<phase>deploy</phase>
263-
<goals>
264-
<goal>deploy</goal>
265-
</goals>
266-
</execution>
267-
</executions>
268-
</plugin>
250+
<!-- [RELEASE] NEXUS (version, configuration) -->
251+
<plugin>
252+
<groupId>org.sonatype.central</groupId>
253+
<artifactId>central-publishing-maven-plugin</artifactId>
254+
<version>${sonatype-centralPublishingPlugin.version}</version>
255+
<extensions>true</extensions>
256+
<configuration>
257+
<publishingServerId>central</publishingServerId>
258+
<autoPublish>true</autoPublish>
259+
</configuration>
260+
</plugin>
269261

270262
<!-- assembly plugin -->
271263
<plugin>
@@ -450,9 +442,9 @@
450442
<artifactId>maven-gpg-plugin</artifactId>
451443
</plugin>
452444
<plugin>
453-
<groupId>org.sonatype.plugins</groupId>
454-
<artifactId>nexus-staging-maven-plugin</artifactId>
455-
</plugin>
445+
<groupId>org.sonatype.central</groupId>
446+
<artifactId>central-publishing-maven-plugin</artifactId>
447+
</plugin>
456448
</plugins>
457449
</build>
458450
</profile>
@@ -761,19 +753,6 @@
761753

762754
</profiles>
763755

764-
<distributionManagement>
765-
<snapshotRepository>
766-
<id>sonatype-nexus-snapshots</id>
767-
<name>Sonatype Nexus Snapshots</name>
768-
<url>${sonatype-oss-dist-mgmt-snapshots-url}</url>
769-
</snapshotRepository>
770-
<repository>
771-
<id>sonatype-nexus-staging</id>
772-
<name>Nexus Release Repository</name>
773-
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
774-
</repository>
775-
</distributionManagement>
776-
777756
<dependencies>
778757

779758

tools/src/main/java/io/toolisticon/aptk/tools/AnnotationToClassMapperHelper.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,5 +291,7 @@ String getValidatorExpressionAttributeValueStringRepresentation(AnnotationValueW
291291
public String getStringRepresentationOfAnnotation() {
292292
return annotation.getStringRepresentation();
293293
}
294+
295+
294296

295297
}

tools/src/main/java/io/toolisticon/aptk/tools/TypeMirrorWrapper.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,15 @@ public Optional<TypeElementWrapper> getTypeElement() {
826826
return getTypeElement(typeMirror);
827827
}
828828

829+
/**
830+
* Checks if wrapped TypeMirror is assignable to class with passed fqn.
831+
*
832+
* @param fqn the fqn of the class to check against
833+
* @return true if wrapped TypeMirror is assignable to passed class, otherwise false
834+
*/
835+
public boolean isAssignableTo(String fqn) {
836+
return isAssignableTo(TypeMirrorWrapper.wrap(fqn));
837+
}
829838

830839
/**
831840
* Checks if wrapped TypeMirror is assignable to passed class.
@@ -867,6 +876,17 @@ public boolean isAssignableTo(TypeElementWrapper typeElementWrapper) {
867876
return isAssignableTo(typeElementWrapper.asType());
868877
}
869878

879+
880+
/**
881+
* Checks if wrapped TypeMirror is assignable from class with passed fqn.
882+
*
883+
* @param fqn the fqn of the class to check against
884+
* @return true if wrapped TypeMirror is assignable to passed class, otherwise false
885+
*/
886+
public boolean isAssignableFrom(String fqn) {
887+
return isAssignableFrom(TypeMirrorWrapper.wrap(fqn));
888+
}
889+
870890
/**
871891
* Checks if wrapped TypeMirror is assignable from passed class.
872892
*
@@ -888,20 +908,20 @@ public boolean isAssignableFrom(TypeMirror otherTypeMirror) {
888908
}
889909

890910
/**
891-
* Checks if wrapped TypeMirror is assignable to passed TypeMirrorWrapper.
911+
* Checks if wrapped TypeMirror is assignable from passed TypeMirrorWrapper.
892912
*
893913
* @param otherTypeMirrorWrapper the TypeMirrorWrapper to check against
894-
* @return true if wrapped TypeMirror is assignable to passed class, otherwise false
914+
* @return true if wrapped TypeMirror is assignable from passed class, otherwise false
895915
*/
896916
public boolean isAssignableFrom(TypeMirrorWrapper otherTypeMirrorWrapper) {
897917
return TypeUtils.TypeComparison.isAssignableTo(otherTypeMirrorWrapper.unwrap(), this.typeMirror);
898918
}
899919

900920
/**
901-
* Checks if wrapped TypeMirror is assignable to passed TypeMirrorWrapper.
921+
* Checks if wrapped TypeMirror is assignable from passed TypeMirrorWrapper.
902922
*
903923
* @param typeElementWrapper the TypeMirrorWrapper to check against
904-
* @return true if wrapped TypeMirror is assignable to passed class, otherwise false
924+
* @return true if wrapped TypeMirror is assignable from passed class, otherwise false
905925
*/
906926
public boolean isAssignableFrom(TypeElementWrapper typeElementWrapper) {
907927
return isAssignableFrom(typeElementWrapper.asType());

tools/src/main/java/io/toolisticon/aptk/tools/fluentfilter/FluentElementFilter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ public List<ELEMENT> getResult() {
476476
return elements;
477477

478478
}
479+
479480

480481
/**
481482
* Checks if filter result is empty.

tools/src/main/java/io/toolisticon/aptk/tools/wrapper/AnnotationMirrorWrapper.java

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import javax.lang.model.type.DeclaredType;
1313
import java.lang.annotation.Annotation;
1414
import java.util.Arrays;
15+
import java.util.HashSet;
1516
import java.util.List;
1617
import java.util.Objects;
1718
import java.util.Optional;
@@ -280,6 +281,43 @@ public List<String> getAttributeNamesInDeclarationOrder() {
280281
public boolean hasAttribute(String name) {
281282
return getAttributeNames().contains(name);
282283
}
284+
285+
/**
286+
* Checks if AnnotationMirrors TypeElement has a certain meta annotation.
287+
* @param metaAnnotationType The meta annotation to scan for
288+
* @return true, if the annotation has passed meta annotation(itself, or recursively via annotations on annotation type)
289+
*/
290+
public boolean hasMetaAnnotation(Class<? extends Annotation> metaAnnotationType) {
291+
return metaAnnotationType != null && hasMetaAnnotation(metaAnnotationType.getCanonicalName());
292+
}
293+
294+
295+
private boolean hasMetaAnnotation(String fullyQualifiedMetaAnnotationName, Set<String> state) {
296+
297+
if (state.contains(this.asElement().getQualifiedName())) {
298+
// catch cyclic annotation relations like with Documented annotation(which has a self reference)
299+
return false;
300+
}
301+
302+
// for preventing
303+
state.add(this.asElement().getQualifiedName());
304+
305+
return fullyQualifiedMetaAnnotationName != null && (
306+
this.asElement().hasAnnotation(fullyQualifiedMetaAnnotationName)
307+
|| this.asElement().getAnnotationMirrors().stream()
308+
.anyMatch(annotationMirror -> annotationMirror.hasMetaAnnotation(fullyQualifiedMetaAnnotationName, state))
309+
);
310+
311+
}
312+
313+
/**
314+
* Checks if AnnotationMirrors TypeElement has a certain meta annotation.
315+
* @param fullyQualifiedMetaAnnotationName The meta annotation to scan for
316+
* @return true, if the annotation has passed meta annotation(itself, or recursively via annotations on annotation type)
317+
*/
318+
public boolean hasMetaAnnotation(String fullyQualifiedMetaAnnotationName) {
319+
return hasMetaAnnotation(fullyQualifiedMetaAnnotationName, new HashSet<>());
320+
}
283321

284322

285323
/**
@@ -316,7 +354,7 @@ public String getStringRepresentation() {
316354
.filter(Objects::nonNull)
317355
.collect(Collectors.joining(", ", "(", ")"));
318356

319-
return stringBuilder.replaceAll("\"", "\\\\\"");
357+
return stringBuilder;
320358
}
321359

322360
/**
@@ -331,7 +369,7 @@ public String getStringRepresentationWithDefaults() {
331369
.map(e -> e + " = " + getAnnotationAttributeValueStringRepresentation(getAttributeWithDefault(e)))
332370
.collect(Collectors.joining(", ", "(", ")"));
333371

334-
return stringBuilder.replaceAll("\"", "\\\\\"");
372+
return stringBuilder;
335373
}
336374

337375
String getAnnotationAttributeValueStringRepresentation(AnnotationValueWrapper annotationValueWrapper) {

tools/src/main/java/io/toolisticon/aptk/tools/wrapper/ElementWrapper.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import io.toolisticon.aptk.tools.AnnotationUtils;
44
import io.toolisticon.aptk.tools.ElementUtils;
5+
import io.toolisticon.aptk.tools.ElementUtils.AccessEnclosingElements;
56
import io.toolisticon.aptk.tools.TypeMirrorWrapper;
7+
import io.toolisticon.aptk.tools.TypeUtils;
68
import io.toolisticon.aptk.tools.fluentfilter.FluentElementFilter;
79
import io.toolisticon.aptk.tools.fluentvalidator.FluentElementValidator;
810

@@ -48,12 +50,12 @@ public E unwrap() {
4850

4951

5052
/**
51-
* Gets the PackageElement of the enclosing package.
53+
* Gets the wrapped PackageElement of the enclosing package or the Package itself if the ElementWrapper wraps a PackageElement.
5254
*
5355
* @return the PackageElement of the enclosing Package
5456
*/
5557
public PackageElementWrapper getPackage() {
56-
return PackageElementWrapper.wrap(ElementUtils.AccessEnclosingElements.<PackageElement>getFirstEnclosingElementOfKind(element, ElementKind.PACKAGE));
58+
return this.isPackage() ? toPackageElement(this) : PackageElementWrapper.wrap(AccessEnclosingElements.<PackageElement>getFirstEnclosingElementOfKind(element, ElementKind.PACKAGE));
5759
}
5860

5961
/**
@@ -373,13 +375,31 @@ public boolean hasAnnotation(Class<? extends Annotation> annotation) {
373375
/**
374376
* Checks if passed annotation is present.
375377
*
376-
* @param annotationFqn the annotation tom check
378+
* @param annotationFqn the annotation to check
377379
* @return true if passed annotation is present, otherwise false
378380
*/
379381
public boolean hasAnnotation(String annotationFqn) {
380382
return getAnnotationMirror(annotationFqn).isPresent();
381383
}
382384

385+
/**
386+
* Checks if wrapped element has passed meta annotation.
387+
* @param annotation the annotation to check for
388+
* @return true, if the meta annotation can be found, otherwise false
389+
*/
390+
public boolean hasMetaAnnotation(Class<? extends Annotation> annotation) {
391+
return hasAnnotation(annotation) || this.getAnnotationMirrors().stream().anyMatch(it -> it.hasMetaAnnotation(annotation));
392+
}
393+
394+
/**
395+
* Checks if wrapped element has passed meta annotations fqn.
396+
* @param fqn the fully qualified name of the annotation to check for
397+
* @return true, if the meta annotation can be found, otherwise false
398+
*/
399+
public boolean hasMetaAnnotation(String fqn) {
400+
return hasAnnotation(fqn) || this.getAnnotationMirrors().stream().anyMatch(it -> it.hasMetaAnnotation(fqn));
401+
}
402+
383403
/**
384404
* Returns an annotation of a specific type.
385405
* This should only be used if annotation doesn't have Class based attributes, since Classes might not be compiled already.

tools/src/main/java/io/toolisticon/aptk/tools/wrapper/PackageElementWrapper.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
import io.toolisticon.aptk.common.ToolingProvider;
44

55
import javax.lang.model.element.PackageElement;
6+
7+
import java.util.Arrays;
68
import java.util.Optional;
9+
import java.util.stream.Collectors;
710

811
/**
912
* Wrapper for PackageElement.
@@ -36,6 +39,31 @@ public String getQualifiedName() {
3639
public boolean isUnnamed() {
3740
return this.element.isUnnamed();
3841
}
42+
43+
/**
44+
* WARN - This method is in incubation stage and might be removed in the near future.
45+
* Returns the parent package of the wrapped package.
46+
* The annotation processor api handles all packages as unrelated, nevertheless it's a common case that packages are handled as they are related.
47+
* Think of configuration annotations that should be applied to all sub-packages as well.
48+
* WARN : The behavior of this method depends on the JDK since it uses javax.lang.model.util.Elements.getPackageElement() . Some JDKs handle "uniquely determined" differently. So using this method might lead to inconsistent behavior.
49+
* @return The wrapped PackageElement, or an empty optional if it doesn't exist or if the parent package cannot be uniquely determined (i.e. parent package is used in dependency and in code under compilation).
50+
*/
51+
52+
public Optional<PackageElementWrapper> getParentPackage() {
53+
54+
String qualifiedPackageName = this.getQualifiedName();
55+
String [] packageToken = qualifiedPackageName.split("[.]");
56+
57+
if (packageToken.length == 1) {
58+
return Optional.empty();
59+
} else {
60+
String parentPackageName = Arrays.stream(packageToken, 0, packageToken.length-1).collect(Collectors.joining("."));
61+
return PackageElementWrapper.getByFqn(parentPackageName);
62+
}
63+
64+
}
65+
66+
3967

4068
/**
4169
* Wraps a PackageElement instance.

tools/src/test/java/io/toolisticon/aptk/tools/AnnotationToClassMapperHelperTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,4 +255,29 @@ public void test_incorrectMappingWithMethodParameterMappingOnAnnotatedTypeElemen
255255
.executeTest();
256256

257257
}
258+
259+
260+
@Test
261+
public void test_getStringRepresentationOfAnnotation (){
262+
unitTestBuilder.<VariableElement>defineTestWithPassedInElement(TestClassWithCorrectMapping.class, (processingEnvironment, element) -> {
263+
264+
try {
265+
ToolingProvider.setTooling(processingEnvironment);
266+
267+
VariableElementWrapper parameterElement = VariableElementWrapper.wrap(element);
268+
AnnotationMirrorWrapper mappingAnnotation = parameterElement.getAnnotationMirror(CorrectMappingWithParameters.class).get();
269+
AnnotationToClassMapperHelper helper = AnnotationToClassMapperHelper.getInstance(parameterElement,mappingAnnotation);
270+
271+
System.out.println(helper.getStringRepresentationOfAnnotation());
272+
MatcherAssert.assertThat(helper.getStringRepresentationOfAnnotation(), Matchers.is("@CorrectMappingWithParameters(aString = \"YES\", aLong = 4L, aClass = String.class, anArray = {2.0, 3.0, 4.0})"));
273+
274+
} finally {
275+
ToolingProvider.clearTooling();
276+
}
277+
278+
279+
})
280+
.compilationShouldSucceed()
281+
.executeTest();
282+
}
258283
}

0 commit comments

Comments
 (0)