Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public class ApiAnnotationProcessor extends AbstractProcessor {
private static final String OPENSEARCH_PACKAGE = "org.opensearch";

private final Set<Element> reported = new HashSet<>();
private final Set<Element> validated = new HashSet<>();
private final Set<AnnotatedConstruct> processed = new HashSet<>();
private Kind reportFailureAs = Kind.ERROR;

Expand All @@ -85,6 +86,8 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
);

for (var element : elements) {
validate(element);

if (!checkPackage(element)) {
continue;
}
Expand All @@ -100,6 +103,64 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
return false;
}

private void validate(Element element) {
// The element was validated already
if (validated.contains(element)) {
return;
}

validated.add(element);

final PublicApi publicApi = element.getAnnotation(PublicApi.class);
if (publicApi != null) {
if (!validateVersion(publicApi.since())) {
processingEnv.getMessager()
.printMessage(
reportFailureAs,
"The type " + element + " has @PublicApi annotation with unparseable OpenSearch version: " + publicApi.since()
);
}
}

final DeprecatedApi deprecatedApi = element.getAnnotation(DeprecatedApi.class);
if (deprecatedApi != null) {
if (!validateVersion(deprecatedApi.since())) {
processingEnv.getMessager()
.printMessage(
reportFailureAs,
"The type "
+ element
+ " has @DeprecatedApi annotation with unparseable OpenSearch version: "
+ deprecatedApi.since()
);
}
}
}

private boolean validateVersion(String version) {
String[] parts = version.split("[.-]");
if (parts.length < 3 || parts.length > 4) {
return false;
}

int major = Integer.parseInt(parts[0]);
if (major > 3 || major < 0) {
return false;
}

int minor = Integer.parseInt(parts[1]);
if (minor < 0) {
return false;
}

int patch = Integer.parseInt(parts[2]);
if (patch < 0) {
return false;
}

return true;
}

/**
* Check top level executable element
* @param executable top level executable element
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -486,4 +486,35 @@ public void testPublicApiConstructorAnnotatedInternalApi() {

assertThat(failure.diagnotics(), not(hasItem(matching(Diagnostic.Kind.ERROR))));
}

public void testPublicApiUnparseableVersion() {
final CompilerResult result = compile("PublicApiAnnotatedUnparseable.java");
assertThat(result, instanceOf(Failure.class));

final Failure failure = (Failure) result;
assertThat(failure.diagnotics(), hasSize(3));

assertThat(
failure.diagnotics(),
hasItem(
matching(
Diagnostic.Kind.ERROR,
containsString(
"The type org.opensearch.common.annotation.processor.PublicApiAnnotatedUnparseable has @PublicApi annotation with unparseable OpenSearch version: 2.x"
)
)
)
);
}

public void testPublicApiWithDeprecatedApiMethod() {
final CompilerResult result = compile("PublicApiWithDeprecatedApiMethod.java");
assertThat(result, instanceOf(Failure.class));

final Failure failure = (Failure) result;
assertThat(failure.diagnotics(), hasSize(2));

assertThat(failure.diagnotics(), not(hasItem(matching(Diagnostic.Kind.ERROR))));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.common.annotation.processor;

import org.opensearch.common.annotation.PublicApi;

@PublicApi(since = "2.x")
public class PublicApiAnnotatedUnparseable {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.common.annotation.processor;

import org.opensearch.common.annotation.DeprecatedApi;
import org.opensearch.common.annotation.PublicApi;

@PublicApi(since = "1.0.0")
public class PublicApiWithDeprecatedApiMethod {
@DeprecatedApi(since = "0.1.0")
public void method() {

}
}