-
Notifications
You must be signed in to change notification settings - Fork 107
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove runtime classpath scanning (#911)
* Remove runtime classpath scanning Operations, custom XStream types,and publishable classes are stored in registry files in the META-INF directory of the core project JAR. * Use annotation processor to generate class lists
- Loading branch information
1 parent
a2c3264
commit 142b1de
Showing
57 changed files
with
506 additions
and
160 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# GRIP Annotation Processor | ||
|
||
This subproject contains an annotation processor used to generate manifest files in the core project, | ||
used by the GRIP runtime to discover operations, publishable data types, and aliases for XStream | ||
serialization for save files. | ||
|
||
The annotation processor generates these files: | ||
|
||
| Annotation | File | | ||
|---|---| | ||
| `@Description` | `/META-INF/operations` | | ||
| `@PublishableObject` | `/META-INF/publishables` | | ||
| `@XStreamAlias` | `/META-INF/xstream-aliases` | | ||
|
||
Each file contains a list of the names of the classes annotated with the corresponding annotation, | ||
which is then read by the `MetaInfReader` class in the GRIP core module. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
plugins { | ||
`java-library` | ||
} | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
compileOnly(group = "com.google.auto.service", name = "auto-service", version = "1.0-rc4") | ||
annotationProcessor(group = "com.google.auto.service", name = "auto-service", version = "1.0-rc4") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
annotation/src/main/java/edu/wpi/grip/annotation/operation/OperationCategory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package edu.wpi.grip.annotation.operation; | ||
|
||
/** | ||
* The categories that entries can be in. | ||
*/ | ||
public enum OperationCategory { | ||
IMAGE_PROCESSING, | ||
FEATURE_DETECTION, | ||
NETWORK, | ||
LOGICAL, | ||
OPENCV, | ||
MISCELLANEOUS, | ||
} |
14 changes: 14 additions & 0 deletions
14
annotation/src/main/java/edu/wpi/grip/annotation/operation/PublishableObject.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package edu.wpi.grip.annotation.operation; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* Marks a type as being publishable by a network operation. | ||
*/ | ||
@Target(ElementType.TYPE) | ||
@Retention(RetentionPolicy.SOURCE) | ||
public @interface PublishableObject { | ||
} |
111 changes: 111 additions & 0 deletions
111
annotation/src/main/java/edu/wpi/grip/annotation/processor/ClassListProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package edu.wpi.grip.annotation.processor; | ||
|
||
import edu.wpi.grip.annotation.operation.Description; | ||
import edu.wpi.grip.annotation.operation.PublishableObject; | ||
|
||
import com.google.auto.service.AutoService; | ||
import com.google.common.collect.ImmutableMap; | ||
|
||
import java.io.IOException; | ||
import java.io.Writer; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
|
||
import javax.annotation.processing.AbstractProcessor; | ||
import javax.annotation.processing.Filer; | ||
import javax.annotation.processing.Processor; | ||
import javax.annotation.processing.RoundEnvironment; | ||
import javax.annotation.processing.SupportedAnnotationTypes; | ||
import javax.annotation.processing.SupportedSourceVersion; | ||
import javax.lang.model.SourceVersion; | ||
import javax.lang.model.element.Element; | ||
import javax.lang.model.element.TypeElement; | ||
import javax.lang.model.type.DeclaredType; | ||
import javax.lang.model.type.TypeKind; | ||
import javax.lang.model.util.SimpleTypeVisitor8; | ||
import javax.tools.Diagnostic; | ||
import javax.tools.FileObject; | ||
import javax.tools.StandardLocation; | ||
|
||
/** | ||
* Processes elements with the GRIP annotations and generates class list files for them. | ||
*/ | ||
@SupportedAnnotationTypes({ | ||
"edu.wpi.grip.annotation.*", | ||
"com.thoughtworks.xstream.annotations.XStreamAlias" | ||
}) | ||
@SupportedSourceVersion(SourceVersion.RELEASE_8) | ||
@AutoService(Processor.class) | ||
public class ClassListProcessor extends AbstractProcessor { | ||
|
||
public static final String OPERATIONS_FILE_NAME = "operations"; | ||
public static final String PUBLISHABLES_FILE_NAME = "publishables"; | ||
public static final String XSTREAM_ALIASES_FILE_NAME = "xstream-aliases"; | ||
|
||
private final Map<String, String> fileNames = ImmutableMap.of( | ||
Description.class.getName(), OPERATIONS_FILE_NAME, | ||
PublishableObject.class.getName(), PUBLISHABLES_FILE_NAME, | ||
"com.thoughtworks.xstream.annotations.XStreamAlias", XSTREAM_ALIASES_FILE_NAME | ||
); | ||
|
||
@Override | ||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { | ||
for (TypeElement annotation : annotations) { | ||
String fileName = fileNames.get(annotation.asType().toString()); | ||
if (fileName != null) { | ||
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Processing " + annotation); | ||
createFile(fileName, classesAnnotatedWith(annotation, roundEnv)); | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
private Iterable<String> classesAnnotatedWith(TypeElement element, RoundEnvironment roundEnv) { | ||
return roundEnv.getElementsAnnotatedWith(element) | ||
.stream() | ||
.map(Element::asType) | ||
.map(t -> t.accept(TypeNameExtractor.INSTANCE, null)) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
private void createFile(String fileName, Iterable<String> classNames) { | ||
Filer filer = processingEnv.getFiler(); | ||
|
||
String resource = "META-INF/" + fileName; | ||
|
||
try { | ||
FileObject fileObject = filer.createResource(StandardLocation.CLASS_OUTPUT, "", resource); | ||
try (Writer writer = fileObject.openWriter()) { | ||
for (String className : classNames) { | ||
writer.write(className); | ||
writer.write('\n'); | ||
} | ||
} | ||
} catch (IOException e) { | ||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, | ||
"Unable to create resource file " + resource + ": " + e.getMessage()); | ||
} | ||
} | ||
|
||
private static final class TypeNameExtractor extends SimpleTypeVisitor8<String, Void> { | ||
|
||
static final TypeNameExtractor INSTANCE = new TypeNameExtractor(); | ||
|
||
@Override | ||
public String visitDeclared(DeclaredType t, Void o) { | ||
String typeName = t.toString(); | ||
if (typeName.contains("<")) { | ||
typeName = typeName.substring(0, typeName.indexOf('<')); | ||
} | ||
if (t.getEnclosingType().getKind() != TypeKind.NONE) { | ||
// Inner class, replace '.' with '$' | ||
int lastDot = typeName.lastIndexOf('.'); | ||
String first = typeName.substring(0, lastDot); | ||
String second = typeName.substring(lastDot + 1); | ||
typeName = first + "$" + second; | ||
} | ||
return typeName; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.