EntryMap.java 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package me.lortseam.completeconfig.data;
  2. import com.google.common.base.CaseFormat;
  3. import me.lortseam.completeconfig.api.ConfigEntry;
  4. import me.lortseam.completeconfig.api.ConfigEntryContainer;
  5. import me.lortseam.completeconfig.api.ConfigEntryListener;
  6. import me.lortseam.completeconfig.data.gui.TranslationIdentifier;
  7. import me.lortseam.completeconfig.exception.IllegalAnnotationParameterException;
  8. import me.lortseam.completeconfig.exception.IllegalModifierException;
  9. import me.lortseam.completeconfig.exception.IllegalReturnTypeException;
  10. import java.lang.reflect.Modifier;
  11. import java.util.ArrayList;
  12. import java.util.Arrays;
  13. import java.util.List;
  14. public class EntryMap extends ConfigMap<Entry> {
  15. EntryMap(TranslationIdentifier translation) {
  16. super(translation);
  17. }
  18. public void resolve(ConfigEntryContainer container) {
  19. List<Entry> containerEntries = new ArrayList<>();
  20. for (Class<? extends ConfigEntryContainer> clazz : container.getConfigClasses()) {
  21. Arrays.stream(clazz.getDeclaredMethods()).filter(method -> !Modifier.isStatic(method.getModifiers()) && method.isAnnotationPresent(ConfigEntryListener.class)).forEach(method -> {
  22. ConfigEntryListener listener = method.getDeclaredAnnotation(ConfigEntryListener.class);
  23. String fieldName = listener.value();
  24. if (fieldName.equals("")) {
  25. if (!method.getName().startsWith("set") || method.getName().equals("set")) {
  26. throw new IllegalAnnotationParameterException("Could not detect field name for listener method " + method + ", please provide it inside the annotation");
  27. }
  28. fieldName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, method.getName().replaceFirst("set", ""));
  29. }
  30. Class<? extends ConfigEntryContainer> fieldClass = listener.container();
  31. if (fieldClass == ConfigEntryContainer.class) {
  32. fieldClass = clazz;
  33. }
  34. if (method.getParameterCount() != 1) {
  35. throw new IllegalArgumentException("Listener method " + method + " has wrong number of parameters");
  36. }
  37. EntryAccessor<?> accessor = Entry.of(fieldName, fieldClass);
  38. if (method.getParameterTypes()[0] != accessor.getType()) {
  39. throw new IllegalArgumentException("Listener method " + method + " has wrong argument type");
  40. }
  41. if (method.getReturnType() != Void.TYPE) {
  42. throw new IllegalReturnTypeException("Listener method " + method + " may not return a type other than void");
  43. }
  44. if (!method.isAccessible()) {
  45. method.setAccessible(true);
  46. }
  47. accessor.connect(entry -> entry.addListener(method, container));
  48. });
  49. List<Entry> clazzEntries = new ArrayList<>();
  50. Arrays.stream(clazz.getDeclaredFields()).filter(field -> {
  51. if (Modifier.isStatic(field.getModifiers())) {
  52. return false;
  53. }
  54. if (container.isConfigPOJO()) {
  55. return !ConfigEntryContainer.class.isAssignableFrom(field.getType()) && !field.isAnnotationPresent(ConfigEntry.Ignore.class);
  56. }
  57. return field.isAnnotationPresent(ConfigEntry.class);
  58. }).forEach(field -> {
  59. if (Modifier.isFinal(field.getModifiers())) {
  60. throw new IllegalModifierException("Entry field " + field + " must not be final");
  61. }
  62. if (!field.isAccessible()) {
  63. field.setAccessible(true);
  64. }
  65. Entry<?> entry = ((Entry.Draft<?>) Entry.of(field)).build(container, translation);
  66. entry.resolve(field);
  67. clazzEntries.add(entry);
  68. });
  69. containerEntries.addAll(0, clazzEntries);
  70. }
  71. for (Entry<?> entry : containerEntries) {
  72. putUnique(entry.getID(), entry);
  73. }
  74. }
  75. }