11package nativeimage .core ;
22
33import java .io .IOException ;
4+ import java .net .URI ;
45import java .util .LinkedHashSet ;
56import java .util .Set ;
67
1112import javax .lang .model .element .TypeElement ;
1213
1314import com .mageddo .aptools .ClassUtils ;
14- import com .mageddo .aptools .IoUtils ;
1515import com .mageddo .aptools .Processor ;
1616import com .mageddo .aptools .elements .ElementFinder ;
17+ import com .mageddo .aptools .elements .ElementUtils ;
1718import com .mageddo .aptools .log .Logger ;
1819import com .mageddo .aptools .log .LoggerFactory ;
1920
2021import nativeimage .Reflection ;
2122import nativeimage .Reflections ;
2223import nativeimage .core .domain .ReflectionConfig ;
24+ import static nativeimage .core .NativeImages .solvePath ;
25+ import static nativeimage .thirdparty .ThirdPartyPackageScanner .findPackageClasses ;
2326
27+ /**
28+ * Will generate native image reflection config to project source classes.
29+ */
2430public class NativeImageReflectionConfigGenerator implements Processor {
2531
2632 private final Logger logger = LoggerFactory .getLogger ();
2733 private final ProcessingEnvironment processingEnv ;
2834 private final Set <ReflectionConfig > classes ;
35+ private final Set <ReflectionConfig > thirdPartyClasses ;
2936 private String classPackage ;
3037
3138 public NativeImageReflectionConfigGenerator (ProcessingEnvironment processingEnv ) {
3239 this .processingEnv = processingEnv ;
3340 this .classes = new LinkedHashSet <>();
41+ this .thirdPartyClasses = new LinkedHashSet <>();
3442 }
3543
3644 @ Override
@@ -57,21 +65,67 @@ private void processElementsForRepeatableAnnotation(RoundEnvironment roundEnv, E
5765 }
5866 }
5967
60- private void processElementsForAnnotation (RoundEnvironment roundEnv ) {
68+ void processElementsForAnnotation (RoundEnvironment roundEnv ) {
6169 for (Element element : roundEnv .getElementsAnnotatedWith (Reflection .class )) {
6270 processElementsForAnnotation (roundEnv , element , element .getAnnotation (Reflection .class ));
6371 }
6472 }
6573
66- private void processElementsForAnnotation (RoundEnvironment roundEnv , Element element , Reflection reflection ) {
67- if (reflection .scanPackage ().isEmpty ()){
74+ void processElementsForAnnotation (
75+ RoundEnvironment roundEnv , Element element , Reflection reflection
76+ ) {
77+ if (reflection .scanLibs ()) {
78+ this .addMatchingProjectLibsClasses (reflection );
79+ } else {
80+ this .addMatchingProjectSourceElements (roundEnv , element , reflection );
81+ }
82+ }
83+
84+ void addMatchingProjectLibsClasses (Reflection reflection ) {
85+ if (reflection .scanPackage ().isEmpty ()) {
86+ this .addClassAndNested (reflection , chooseClass (reflection ));
87+ } else {
88+ final Set <Class <?>> classes = findPackageClasses (reflection .scanPackage ());
89+ for (final Class <?> clazz : classes ) {
90+ this .addClassAndNested (reflection , clazz );
91+ }
92+ }
93+ }
94+
95+ static Class <?> chooseClass (Reflection reflection ) {
96+ return reflection .scanClass () != Void .class
97+ ? reflection .scanClass ()
98+ : ClassUtils .forName (reflection .scanClassName ());
99+ }
100+
101+ void addClassAndNested (Reflection reflection , Class <?> clazz ) {
102+ this .addClass (clazz , reflection );
103+ for (final Class <?> innerClass : ClassUtils .findNestClasses (clazz )) {
104+ this .addClass (innerClass , reflection );
105+ logger .debug ("m=addMatchingProjectLibsClasses, innerClass=%s" , innerClass );
106+ }
107+ }
108+
109+ void addClass (Class <?> clazz , Reflection reflection ) {
110+ logger .debug ("m=addClass, clazz=%s" , clazz , clazz .getName ());
111+ // todo check if the name is correct
112+ for (ReflectionConfig config : ReflectionConfigBuilder .of (reflection , clazz .getName ())) { //
113+ this .thirdPartyClasses .remove (config );
114+ this .thirdPartyClasses .add (config );
115+ }
116+ }
117+
118+ void addMatchingProjectSourceElements (RoundEnvironment roundEnv , Element element ,
119+ Reflection reflection ) {
120+ if (reflection .scanPackage ().isEmpty ()) {
68121 this .addElement (element , reflection );
122+ // todo must add nested classes too
69123 } else {
70124 for (final Element nestedElement : roundEnv .getRootElements ()) {
71125 this .addElement (nestedElement , reflection );
72126 for (final Element innerClass : ElementFinder .find (nestedElement , ElementKind .CLASS )) {
73127 this .addElement (innerClass , reflection );
74- logger .debug ("innerClass=%s" , innerClass );
128+ logger .debug ("m=addMatchingProjectSourceElements, innerClass=%s" , innerClass );
75129 }
76130 }
77131 }
@@ -81,30 +135,46 @@ private void addElement(Element element, Reflection annotation) {
81135// final Symbol.ClassSymbol symbol = (Symbol.ClassSymbol) element;
82136// ((Symbol.ClassSymbol) element).sourcefile.de
83137 logger .debug (
84- "m=addElement, asType=%s, kind=%s, simpleName=%s, enclosing=%s, clazz=%s" ,
85- element .asType (), element .getKind (), element .getSimpleName (),
86- element .getEnclosingElement (), element .getClass ()
138+ "m=addElement, asType=%s, kind=%s, simpleName=%s, enclosing=%s, clazz=%s" ,
139+ element .asType (), element .getKind (), element .getSimpleName (),
140+ element .getEnclosingElement (), element .getClass ()
87141 );
88- this .classPackage = this .classPackage == null ? ClassUtils .getClassPackage (element .toString ()) : this .classPackage ;
89- for (ReflectionConfig config : ReflectionConfigBuilder .of (element , annotation )) {
142+ this .classPackage = this .classPackage == null ?
143+ ClassUtils .getClassPackage (element .toString ()) : this .classPackage ;
144+ for (ReflectionConfig config : ReflectionConfigBuilder .of (annotation ,
145+ ElementUtils .toClassName (element ))) {
90146 this .classes .remove (config );
91147 this .classes .add (config );
92148 }
93149 }
94150
95151 private void writeObjects () {
96- ReflectionConfigAppenderAnnotationProcessing appender = null ;
97- try {
98- appender = new ReflectionConfigAppenderAnnotationProcessing (this .processingEnv , getClassPackage ());
99- for (ReflectionConfig config : this .classes ) {
100- appender .append (config );
101- }
102- logger .info ("native-image-reflection-configuration, written-objects=%d" , this .classes .size ());
152+ final String classPackage = this .getClassPackage ();
153+ final String reflectFile = solvePath (classPackage , "reflect.json" );
154+ final String reflectFileThirdParty = solvePath (classPackage , "reflect-third-party.json" );
155+ try (
156+ ReflectionConfigWriter appender =
157+ new ReflectionConfigWriter (this .processingEnv , reflectFile );
158+
159+ ReflectionConfigWriter appenderThirdParty =
160+ new ReflectionConfigWriter (this .processingEnv , reflectFileThirdParty )
161+ ) {
162+
163+ appender .writeAll (this .classes );
164+ appenderThirdParty .writeAll (this .thirdPartyClasses );
165+
166+ final URI nativeImageFile = NativeImagePropertiesWriter .write (
167+ this .processingEnv , classPackage , reflectFile , reflectFileThirdParty
168+ );
169+ logger .info (
170+ "status=reflect-generation-done, objects=%d, 3rdObjects=%s, path=%s" ,
171+ this .classes .size (), this .thirdPartyClasses .size (), nativeImageFile
172+ );
173+
103174 logger .debug ("objects=%s" , this .classes );
175+ logger .debug ("3rdObjects=%s" , this .classes );
104176 } catch (IOException e ) {
105177 throw new RuntimeException (e );
106- } finally {
107- IoUtils .safeClose (appender );
108178 }
109179 }
110180
0 commit comments