Skip to content

Commit 8227e3b

Browse files
committed
add @priority annotation
1 parent 58423f9 commit 8227e3b

1 file changed

Lines changed: 69 additions & 27 deletions

File tree

core/src/main/java/net/j4c0b3y/api/config/StaticConfig.java

Lines changed: 69 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.lang.annotation.Retention;
2020
import java.lang.annotation.RetentionPolicy;
2121
import java.lang.annotation.Target;
22+
import java.lang.reflect.AnnotatedElement;
2223
import java.lang.reflect.Field;
2324
import java.lang.reflect.Modifier;
2425
import java.util.*;
@@ -226,6 +227,8 @@ public void save() {
226227
* @param initialize If this is the initialization phase.
227228
*/
228229
private void step(Class<?> parent, String path, boolean initialize) throws ReflectiveOperationException {
230+
Map<Integer, List<Pair<String, AnnotatedElement>>> members = new TreeMap<>();
231+
229232
for (Field field : parent.getDeclaredFields()) {
230233
// Skip field if its modifiers are invalid, or it is marked @Ignore.
231234
if (!Modifier.isStatic(field.getModifiers()) || field.isAnnotationPresent(Ignore.class)) {
@@ -248,20 +251,8 @@ private void step(Class<?> parent, String path, boolean initialize) throws Refle
248251
continue;
249252
}
250253

251-
boolean hidden = field.isAnnotationPresent(Hidden.class);
252-
boolean present = document.contains(route);
253-
254-
// If this is the initial saving of the value in the document,
255-
// or the field is final, so we have to override the value anyway.
256-
boolean initial = (!present || Modifier.isFinal(field.getModifiers())) && !hidden;
257-
258-
// Set the field value in the configuration document.
259-
if (initial || (!hidden || present)) {
260-
set(route, field, field.get(null));
261-
}
262-
263-
// Set the associated comment for the route's block if present.
264-
document.setComment(document.getBlock(route), field.getAnnotation(Comment.class));
254+
// Add the field to the member priority map.
255+
members.computeIfAbsent(getPriority(field), key -> new ArrayList<>()).add(new Pair<>(route, field));
265256
}
266257

267258
Class<?>[] classes = parent.getDeclaredClasses();
@@ -291,22 +282,56 @@ private void step(Class<?> parent, String path, boolean initialize) throws Refle
291282
continue;
292283
}
293284

294-
// If the class is final, remove it so it is regenerated with default values.
295-
if (Modifier.isFinal(clazz.getModifiers())) {
296-
document.remove(route);
297-
}
285+
// Add the class to the member priority map.
286+
members.computeIfAbsent(getPriority(clazz), key -> new ArrayList<>()).add(new Pair<>(route, clazz));
287+
}
298288

299-
Section section = document.getSection(route);
289+
for (List<Pair<String, AnnotatedElement>> priority : members.values()) {
290+
for (Pair<String, AnnotatedElement> member : priority) {
291+
String route = member.getLeft();
300292

301-
// If the section doesn't exist and is not hidden, create it.
302-
if (section == null && !clazz.isAnnotationPresent(Hidden.class)) {
303-
section = document.createSection(route);
304-
}
293+
if (member.getRight() instanceof Field) {
294+
Field field = (Field) member.getRight();
295+
296+
boolean hidden = field.isAnnotationPresent(Hidden.class);
297+
boolean present = document.contains(route);
298+
299+
// If this is the initial saving of the value in the document,
300+
// or the field is final, so we have to override the value anyway.
301+
boolean initial = (!present || Modifier.isFinal(field.getModifiers())) && !hidden;
302+
303+
// Set the field value in the configuration document.
304+
if (initial || (!hidden || present)) {
305+
set(route, field, field.get(null));
306+
}
307+
308+
// Set the associated comment for the route's block if present.
309+
document.setComment(document.getBlock(route), field.getAnnotation(Comment.class));
310+
311+
continue;
312+
}
313+
314+
if (member.getRight() instanceof Class) {
315+
Class<?> clazz = (Class<?>) member.getRight();
305316

306-
// If the section exists, and we shouldn't skip, set the comment and recurse.
307-
if (section != null) {
308-
document.setComment(section, clazz.getAnnotation(Comment.class));
309-
step(clazz, route + ".", false);
317+
// If the class is final, remove it so it is regenerated with default values.
318+
if (Modifier.isFinal(clazz.getModifiers())) {
319+
document.remove(route);
320+
}
321+
322+
Section section = document.getSection(route);
323+
324+
// If the section doesn't exist and is not hidden, create it.
325+
if (section == null && !clazz.isAnnotationPresent(Hidden.class)) {
326+
section = document.createSection(route);
327+
}
328+
329+
// If the section exists, and we shouldn't skip, set the comment and recurse.
330+
if (section != null) {
331+
document.setComment(section, clazz.getAnnotation(Comment.class));
332+
step(clazz, route + ".", false);
333+
}
334+
}
310335
}
311336
}
312337
}
@@ -468,6 +493,17 @@ private String getRoute(Key key, String name) {
468493
return valid ? key.value() : handler.getKeyFormatter().apply(name);
469494
}
470495

496+
/**
497+
* Gets the priority for a class member.
498+
*
499+
* @param member The member.
500+
* @return The priority.
501+
*/
502+
private int getPriority(AnnotatedElement member) {
503+
Priority annotation = member.getAnnotation(Priority.class);
504+
return annotation != null ? annotation.value() : Integer.MAX_VALUE;
505+
}
506+
471507
/**
472508
* Changes the yaml key to the specified value.
473509
*/
@@ -520,4 +556,10 @@ private String getRoute(Key key, String name) {
520556
public @interface Footer {
521557
String[] value();
522558
}
559+
560+
@Retention(RetentionPolicy.RUNTIME)
561+
@Target({ElementType.TYPE, ElementType.FIELD})
562+
public @interface Priority {
563+
int value();
564+
}
523565
}

0 commit comments

Comments
 (0)