EntrySet.java 4.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package me.lortseam.completeconfig.data;
  2. import com.google.common.base.CaseFormat;
  3. import me.lortseam.completeconfig.api.ConfigContainer;
  4. import me.lortseam.completeconfig.api.ConfigEntries;
  5. import me.lortseam.completeconfig.api.ConfigEntry;
  6. import me.lortseam.completeconfig.api.ConfigEntryListener;
  7. import me.lortseam.completeconfig.data.text.TranslationIdentifier;
  8. import me.lortseam.completeconfig.exception.IllegalAnnotationParameterException;
  9. import me.lortseam.completeconfig.exception.IllegalModifierException;
  10. import me.lortseam.completeconfig.exception.IllegalReturnTypeException;
  11. import java.lang.reflect.Field;
  12. import java.lang.reflect.Modifier;
  13. import java.util.Arrays;
  14. import java.util.regex.Pattern;
  15. public class EntrySet extends DataSet<Entry> {
  16. EntrySet(TranslationIdentifier translation) {
  17. super(translation);
  18. }
  19. void resolve(ConfigContainer container) {
  20. for (Class<? extends ConfigContainer> clazz : container.getConfigClasses()) {
  21. Arrays.stream(clazz.getDeclaredFields()).filter(field -> {
  22. if (clazz != container.getClass() && Modifier.isStatic(field.getModifiers())) {
  23. return false;
  24. }
  25. if (clazz.isAnnotationPresent(ConfigEntries.class)) {
  26. return !ConfigContainer.class.isAssignableFrom(field.getType()) && !field.isAnnotationPresent(ConfigContainer.Ignore.class) && !Modifier.isTransient(field.getModifiers());
  27. }
  28. return field.isAnnotationPresent(ConfigEntry.class);
  29. }).map(field -> {
  30. if (Modifier.isFinal(field.getModifiers())) {
  31. throw new IllegalModifierException("Entry field " + field + " must not be final");
  32. }
  33. Entry<?> entry = Entry.Draft.of(field, container.getClass()).build(Modifier.isStatic(field.getModifiers()) ? null : container, translation);
  34. entry.resolve(field);
  35. return entry;
  36. }).forEach(this::add);
  37. Arrays.stream(clazz.getDeclaredMethods()).filter(method -> {
  38. if (clazz != container.getClass() && Modifier.isStatic(method.getModifiers())) {
  39. return false;
  40. }
  41. return method.isAnnotationPresent(ConfigEntryListener.class);
  42. }).forEach(method -> {
  43. String fieldName = null;
  44. Class<? extends ConfigContainer> fieldClass = clazz;
  45. if (method.isAnnotationPresent(ConfigEntryListener.class)) {
  46. ConfigEntryListener listener = method.getDeclaredAnnotation(ConfigEntryListener.class);
  47. if (!listener.value().equals("")) {
  48. fieldName = listener.value();
  49. }
  50. if (listener.container() != ConfigContainer.class) {
  51. fieldClass = listener.container();
  52. }
  53. }
  54. if (fieldName == null && fieldClass == clazz && method.getName().startsWith("set")) {
  55. try {
  56. Field field = fieldClass.getDeclaredField(CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, method.getName().replaceFirst(Pattern.quote("set"), "")));
  57. fieldName = field.getName();
  58. } catch (NoSuchFieldException ignore) {}
  59. }
  60. if (fieldName == null) {
  61. throw new IllegalAnnotationParameterException("Could not detect field name for listener method " + method);
  62. }
  63. if (method.getParameterCount() != 1) {
  64. throw new IllegalArgumentException("Listener method " + method + " has wrong number of parameters");
  65. }
  66. EntryBase<?> entry = Entry.of(fieldName, fieldClass);
  67. if (!method.getParameterTypes()[0].equals(entry.getType())) {
  68. throw new IllegalArgumentException("Listener method " + method + " has wrong argument type");
  69. }
  70. if (method.getReturnType() != Void.TYPE) {
  71. throw new IllegalReturnTypeException("Listener method " + method + " may not return a type other than void");
  72. }
  73. if (!method.isAccessible()) {
  74. method.setAccessible(true);
  75. }
  76. entry.interact(e -> e.addListener(method, Modifier.isStatic(method.getModifiers()) ? null : container));
  77. });
  78. }
  79. }
  80. }