Skip to content

Commit

Permalink
IPROTO-92 AnnotatedClassScanner.isPublicElement does not work
Browse files Browse the repository at this point in the history
  • Loading branch information
anistor committed May 26, 2019
1 parent adc1cfa commit d633691
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Collection<? extends TypeMirror> discoverClasses(RoundEnvironment roundEnv) thro
Element enclosingElement = annotatedElement.getEnclosingElement();
if (enclosingElement.getKind() == ElementKind.CLASS || enclosingElement.getKind() == ElementKind.INTERFACE) {
TypeElement typeElement = (TypeElement) enclosingElement;
filterByPackage(classes, typeElement, excludedClasses, packages, packageOfInitializer);
filterByPackage(classes, typeElement, excludedClasses, packages, packageOfInitializer, true);
}
}

Expand All @@ -79,37 +79,37 @@ Collection<? extends TypeMirror> discoverClasses(RoundEnvironment roundEnv) thro
throw new AnnotationProcessingException(annotatedElement, "@ProtoEnumValue can only be applied to enum constants.");
}
TypeElement typeElement = (TypeElement) enclosingElement;
filterByPackage(classes, typeElement, excludedClasses, packages, packageOfInitializer);
filterByPackage(classes, typeElement, excludedClasses, packages, packageOfInitializer, true);
}

for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(ProtoEnum.class)) {
if (annotatedElement.getKind() != ElementKind.CLASS && annotatedElement.getKind() != ElementKind.INTERFACE) {
throw new AnnotationProcessingException(annotatedElement, "@ProtoEnum can only be applied to enums.");
}
TypeElement typeElement = (TypeElement) annotatedElement;
filterByPackage(classes, typeElement, excludedClasses, packages, packageOfInitializer);
filterByPackage(classes, typeElement, excludedClasses, packages, packageOfInitializer, true);
}

for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(ProtoMessage.class)) {
if (annotatedElement.getKind() != ElementKind.CLASS && annotatedElement.getKind() != ElementKind.INTERFACE) {
throw new AnnotationProcessingException(annotatedElement, "@ProtoMessage can only be applied to classes and interfaces.");
}
TypeElement typeElement = (TypeElement) annotatedElement;
filterByPackage(classes, typeElement, excludedClasses, packages, packageOfInitializer);
filterByPackage(classes, typeElement, excludedClasses, packages, packageOfInitializer, true);
}

for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(ProtoName.class)) {
if (annotatedElement.getKind() != ElementKind.CLASS && annotatedElement.getKind() != ElementKind.INTERFACE && annotatedElement.getKind() != ElementKind.ENUM) {
throw new AnnotationProcessingException(annotatedElement, "@ProtoName can only be applied to classes, interfaces and enums.");
}
TypeElement typeElement = (TypeElement) annotatedElement;
filterByPackage(classes, typeElement, excludedClasses, packages, packageOfInitializer);
filterByPackage(classes, typeElement, excludedClasses, packages, packageOfInitializer, true);
}
} else {
// filter the included classes by package and exclude the explicitly excluded ones
for (TypeMirror c : includedClasses) {
TypeElement typeElement = (TypeElement) ((DeclaredType) c).asElement();
filterByPackage(classes, typeElement, excludedClasses, packages, packageOfInitializer);
filterByPackage(classes, typeElement, excludedClasses, packages, packageOfInitializer, false);
}
}

Expand Down Expand Up @@ -164,31 +164,36 @@ private Set<TypeMirror> getExcludedClasses() {
* collectedClasses if it satisfies all conditions.
*/
private void filterByPackage(Map<String, TypeMirror> collectedClasses, TypeElement typeElement,
Set<TypeMirror> excludedClasses, Set<String> packages, PackageElement packageOfInitializer) {
// Skip interfaces and abstract classes when scanning packages. We only generate for instantiable classes.
if (typeElement.getKind() == ElementKind.INTERFACE || typeElement.getModifiers().contains(Modifier.ABSTRACT)) {
Set<TypeMirror> excludedClasses, Set<String> basePackages, PackageElement packageOfInitializer,
boolean isScanning) {
TypeMirror type = typeElement.asType();
if (excludedClasses.contains(type)) {
return;
}

PackageElement packageOfElement = elements.getPackageOf(typeElement);
if (packageOfElement.isUnnamed() && !packageOfInitializer.isUnnamed()) {

// when scanning we have some additional rules
if (isScanning) {
// Skip interfaces and abstract classes when scanning packages. We only generate for instantiable classes.
if (typeElement.getKind() == ElementKind.INTERFACE || typeElement.getModifiers().contains(Modifier.ABSTRACT)) {
return;
}

// classes from default/unnamed package cannot be imported so are ignored unless the initializer is itself located in the default package
return;
}
if (packageOfElement.isUnnamed() && !packageOfInitializer.isUnnamed()) {
return;
}

if (!isPublicElement(typeElement) && !packageOfElement.equals(packageOfInitializer)) {
// classes with non-public visibility are ignored unless the initializer is in the same package
return;
}

TypeMirror type = typeElement.asType();
if (excludedClasses.contains(type)) {
return;
if (!isPublicElement(typeElement) && !packageOfElement.equals(packageOfInitializer)) {
return;
}
}

if (!packages.isEmpty()) {
if (!basePackages.isEmpty()) {
String packageName = packageOfElement.getQualifiedName().toString();
if (!isPackageIncluded(packages, packageName)) {
if (!isPackageIncluded(basePackages, packageName)) {
return;
}
}
Expand All @@ -202,14 +207,18 @@ private void filterByPackage(Map<String, TypeMirror> collectedClasses, TypeEleme
*/
private boolean isPublicElement(TypeElement typeElement) {
Element e = typeElement;

while (e != null) {
while (true) {
if (!e.getModifiers().contains(Modifier.PUBLIC)) {
return false;
}
e = e.getEnclosingElement();
if (e == null || e.getKind() == ElementKind.PACKAGE) {
break;
}
if (e.getKind() != ElementKind.CLASS && e.getKind() != ElementKind.INTERFACE && e.getKind() != ElementKind.ENUM) {
return false;
}
}

return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,11 +397,19 @@ private void writeSerializationContextInitializer(Element annotatedElement, Stri
if (schemaFilePath.isEmpty()) {
schemaFilePath = null;
} else {
// write Protobuf schema as a resource file
// reinterpret the path as a package
String pkg = (schemaFilePath.startsWith("/") ? schemaFilePath.substring(1) : schemaFilePath).replace('/', '.');
String schemaResourcePackage;
if (schemaFilePath.startsWith("/")) {
schemaResourcePackage = schemaFilePath.substring(1);
} else {
schemaResourcePackage = schemaFilePath;
schemaFilePath = '/' + schemaFilePath;
}
schemaFilePath = schemaFilePath.replace('.', '/');
schemaResourcePackage = schemaResourcePackage.replace('/', '.');

generatedFilesWriter.addSchemaResourceFile(pkg, fileName, schemaSrc, originatingElements);
// write Protobuf schema as a resource file
generatedFilesWriter.addSchemaResourceFile(schemaResourcePackage, fileName, schemaSrc, originatingElements);
}

if (annotation.service()) {
Expand Down Expand Up @@ -455,7 +463,7 @@ private String generateSerializationContextInitializer(Element annotatedElement,
if (schemaFilePath == null) {
iw.append("PROTO_SCHEMA");
} else {
iw.append("org.infinispan.protostream.FileDescriptorSource.getResourceAsString(getClass(), getProtoFileName())");
iw.append("org.infinispan.protostream.FileDescriptorSource.getResourceAsString(getClass(), \"").append(schemaFilePath).append('/').append(fileName).append("\")");
}
iw.append("; }\n\n");

Expand All @@ -465,12 +473,7 @@ private String generateSerializationContextInitializer(Element annotatedElement,
for (int j = 0; j < serCtxInitDeps.size(); j++) {
iw.append("dep").append(String.valueOf(j)).append(".registerSchema(serCtx);\n");
}
if (schemaFilePath == null) {
iw.append("serCtx.registerProtoFiles(org.infinispan.protostream.FileDescriptorSource.fromString(getProtoFileName(), PROTO_SCHEMA));\n");
} else {
String resourceFile = schemaFilePath.replace('.', '/') + '/' + fileName;
iw.append("serCtx.registerProtoFiles(org.infinispan.protostream.FileDescriptorSource.fromResources(getClass().getClassLoader(), \"").append(resourceFile).append("\"));\n");
}
iw.append("serCtx.registerProtoFiles(org.infinispan.protostream.FileDescriptorSource.fromString(getProtoFileName(), getProtoFile()));\n");
iw.dec();
iw.append("}\n\n");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,7 @@ public void testGeneratedInitializer() throws Exception {
assertTrue(ctx.canMarshall(Note.class));
ProtobufUtil.toWrappedByteArray(ctx, new Note());

// Simple is not in the right package so it is not included
assertFalse(ctx.canMarshall(Simple.class));
assertTrue(ctx.canMarshall(Simple.class));
}

@AutoProtoSchemaBuilder(schemaFilePath = "second_initializer", className = "TestInitializer", autoImportClasses = true,
Expand Down

0 comments on commit d633691

Please sign in to comment.