Skip to content

Commit eb4d607

Browse files
committed
Refactoring done
1 parent 3b8f463 commit eb4d607

16 files changed

+397
-171
lines changed

.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ end_of_line = lf
1818
insert_final_newline = true
1919
charset = utf-8
2020
indent_size = 2
21-
indent_style = space
21+
indent_style = tab
2222
trim_trailing_whitespace = true
2323
max_line_length = 100
2424
ij_formatter_off_tag = @formatter:off

aptools/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
dependencies {
22

33
compile("org.apache.commons:commons-lang3:3.9")
4+
compile("org.reflections:reflections:0.10.2")
45
compileOnly files(org.gradle.internal.jvm.Jvm.current().toolsJar)
56

67
testCompile group: 'commons-io', name: 'commons-io', version: '2.6'

aptools/src/main/java/com/mageddo/aptools/ClassUtils.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.mageddo.aptools;
22

3+
import java.util.List;
4+
35
public class ClassUtils {
46
private ClassUtils() {
57
}
@@ -15,4 +17,16 @@ public static String getClassPackage(String className) {
1517
public static boolean doPackageOwnClass(String packageName, String className) {
1618
return getClassPackage(className).contains(packageName);
1719
}
20+
21+
public static List<Class<?>> findNestClasses(Class<?> clazz){
22+
throw new UnsupportedOperationException();
23+
}
24+
25+
public static Class<?> forName(String className) {
26+
try {
27+
return Class.forName(className);
28+
} catch (ClassNotFoundException e) {
29+
throw new RuntimeException(e);
30+
}
31+
}
1832
}
Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package nativeimage;
22

3-
import java.lang.annotation.*;
3+
import java.lang.annotation.Documented;
4+
import java.lang.annotation.ElementType;
5+
import java.lang.annotation.Retention;
6+
import java.lang.annotation.RetentionPolicy;
7+
import java.lang.annotation.Target;
48

59
/**
610
* Register the annotated element to be scanned and generate a reflection config file,
@@ -13,54 +17,59 @@
1317
//@Repeatable(value = RuntimeReflections.class)
1418
public @interface Reflection {
1519

16-
/**
17-
* The package to be scanned to generate reflection config, e.g <code>java.lang</code>
18-
*/
19-
String scanPackage() default "";
20+
/**
21+
* The package to be scanned to generate reflection config, e.g <code>java.lang</code>
22+
*/
23+
String scanPackage() default "";
2024

21-
/**
22-
* The class to be scanned to generate reflection config
23-
*/
24-
Class scanClass() default Void.class;
25+
/**
26+
* The class to be scanned to generate reflection config
27+
*/
28+
Class scanClass() default Void.class;
2529

26-
/**
27-
* The class name to be scanned to generate reflection config, e.g <code>java.lang.String</code>
28-
*/
29-
String scanClassName() default "";
30+
/**
31+
* The class name to be scanned to generate reflection config, e.g <code>java.lang.String</code>
32+
*/
33+
String scanClassName() default "";
3034

31-
/**
32-
* {@link #declaredConstructors()}, {@link #publicConstructors()} and &lt;init&gt; together
33-
*/
34-
boolean constructors() default false;
35+
/**
36+
* {@link #declaredConstructors()}, {@link #publicConstructors()} and &lt;init&gt; together
37+
*/
38+
boolean constructors() default false;
3539

36-
/**
37-
* aka allDeclaredConstructors
38-
*/
39-
boolean declaredConstructors() default false;
40+
/**
41+
* aka allDeclaredConstructors
42+
*/
43+
boolean declaredConstructors() default false;
4044

41-
/**
42-
* aka allPublicConstructors
43-
*/
44-
boolean publicConstructors() default false;
45+
/**
46+
* aka allPublicConstructors
47+
*/
48+
boolean publicConstructors() default false;
4549

46-
/**
47-
* aka allDeclaredMethods
48-
*/
49-
boolean declaredMethods() default false;
50+
/**
51+
* aka allDeclaredMethods
52+
*/
53+
boolean declaredMethods() default false;
5054

51-
/**
52-
* aka allPublicMethods
53-
*/
54-
boolean publicMethods() default false;
55+
/**
56+
* aka allPublicMethods
57+
*/
58+
boolean publicMethods() default false;
5559

56-
/**
57-
* aka allPublicFields
58-
*/
59-
boolean publicFields() default false;
60+
/**
61+
* aka allPublicFields
62+
*/
63+
boolean publicFields() default false;
6064

61-
/**
62-
* aka allDeclaredFields
63-
*/
64-
boolean declaredFields() default false;
65+
/**
66+
* aka allDeclaredFields
67+
*/
68+
boolean declaredFields() default false;
69+
70+
/**
71+
* If must scan for package or class in project libs instead of in the source.
72+
*/
73+
boolean scanLibs() default false;
6574

6675
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package nativeimage.core;
2+
3+
import java.io.IOException;
4+
import java.io.Writer;
5+
import java.net.URI;
6+
7+
import javax.annotation.processing.ProcessingEnvironment;
8+
import javax.tools.FileObject;
9+
import javax.tools.StandardLocation;
10+
11+
import com.mageddo.aptools.IoUtils;
12+
13+
public class NativeImagePropertiesWriter {
14+
public static URI write(
15+
ProcessingEnvironment processingEnv, String packageName, String... reflectionResources
16+
) {
17+
Writer nativeImagePropsWriter = null;
18+
try {
19+
final FileObject fileObject = processingEnv
20+
.getFiler()
21+
.createResource(
22+
StandardLocation.CLASS_OUTPUT, "",
23+
NativeImages.solvePath(packageName, "native-image.properties")
24+
);
25+
nativeImagePropsWriter = fileObject .openWriter();
26+
nativeImagePropsWriter.append(String.format(
27+
String.format(
28+
"Args=-H:ReflectionConfigurationResources=%s\n",
29+
buildResourcePaths(reflectionResources)
30+
)
31+
));
32+
return fileObject.toUri();
33+
} catch (IOException e) {
34+
throw new RuntimeException(e);
35+
} finally {
36+
IoUtils.safeClose(nativeImagePropsWriter);
37+
}
38+
}
39+
40+
private static String buildResourcePaths(String[] resources) {
41+
if(resources.length == 0){
42+
return "";
43+
}
44+
final StringBuilder sb = new StringBuilder();
45+
for (int i = 0; i < resources.length - 1; i++) {
46+
sb.append("${.}/");
47+
sb.append(resources[i]);
48+
sb.append('|');
49+
}
50+
sb.append("${.}/");
51+
sb.append(resources[resources.length - 1]);
52+
return sb.toString();
53+
}
54+
}

reflection-config-generator/src/main/java/nativeimage/core/NativeImageReflectionConfigGenerator.java

Lines changed: 89 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package nativeimage.core;
22

33
import java.io.IOException;
4+
import java.net.URI;
45
import java.util.LinkedHashSet;
56
import java.util.Set;
67

@@ -11,26 +12,33 @@
1112
import javax.lang.model.element.TypeElement;
1213

1314
import com.mageddo.aptools.ClassUtils;
14-
import com.mageddo.aptools.IoUtils;
1515
import com.mageddo.aptools.Processor;
1616
import com.mageddo.aptools.elements.ElementFinder;
17+
import com.mageddo.aptools.elements.ElementUtils;
1718
import com.mageddo.aptools.log.Logger;
1819
import com.mageddo.aptools.log.LoggerFactory;
1920

2021
import nativeimage.Reflection;
2122
import nativeimage.Reflections;
2223
import 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+
*/
2430
public 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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package nativeimage.core;
2+
3+
public class NativeImages {
4+
5+
public static String solvePath(String classPackage, final String fileName) {
6+
return String.format("META-INF/native-image/%s/%s", classPackage, fileName);
7+
}
8+
}

0 commit comments

Comments
 (0)