Stradaa_

FieldAdapter.java

Apr 1st, 2021
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.13 KB | None | 0 0
  1. /*
  2. * Copyright (C) 2019 TheAltening
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17.  
  18. package com.thealtening.auth.service;
  19.  
  20. import java.lang.invoke.MethodHandle;
  21. import java.lang.invoke.MethodHandles;
  22. import java.lang.reflect.Field;
  23. import java.lang.reflect.Modifier;
  24. import java.util.HashMap;
  25. import java.util.Optional;
  26.  
  27. /**
  28. * @author Vladymyr
  29. * @since 10/08/2019
  30. */
  31. public final class FieldAdapter {
  32.  
  33. private final HashMap<String, MethodHandle> fields = new HashMap<>();
  34. private static final MethodHandles.Lookup LOOKUP;
  35. private static Field MODIFIERS;
  36.  
  37. public FieldAdapter(String parent) {
  38. try {
  39. Class cls = Class.forName(parent);
  40. Field modifiers = FieldAdapter.MODIFIERS;
  41. for (Field field : cls.getDeclaredFields()) {
  42. field.setAccessible(true);
  43. int accessFlags = field.getModifiers();
  44. if (Modifier.isFinal(accessFlags)) {
  45. modifiers.setInt(field, accessFlags & ~Modifier.FINAL);
  46. }
  47.  
  48. MethodHandle handler = LOOKUP.unreflectSetter(field);
  49. handler = handler.asType(handler.type().generic().changeReturnType(void.class));
  50. fields.put(field.getName(), handler);
  51. }
  52. } catch (ClassNotFoundException e) {
  53. throw new RuntimeException("Couldn't load/find the specified class");
  54. } catch (Exception e) {
  55. throw new RuntimeException("Couldn't create a method handler for the field");
  56. }
  57. }
  58.  
  59. public void updateFieldIfPresent(String name, Object newValue) {
  60. Optional.ofNullable(fields.get(name)).ifPresent(setter -> {
  61. try {
  62. setter.invokeExact(newValue);
  63. } catch (Throwable e) {
  64. e.printStackTrace();
  65. }
  66. });
  67. }
  68.  
  69. static {
  70. try {
  71. MODIFIERS = Field.class.getDeclaredField("modifiers");
  72. MODIFIERS.setAccessible(true);
  73. } catch (NoSuchFieldException e) {
  74. e.printStackTrace();
  75. }
  76.  
  77. MethodHandles.Lookup lookupObject;
  78. try {
  79. Field lookupImplField = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
  80. lookupImplField.setAccessible(true);
  81. lookupObject = (MethodHandles.Lookup) lookupImplField.get(null);
  82. } catch (ReflectiveOperationException e) {
  83. lookupObject = MethodHandles.lookup();
  84. }
  85.  
  86. LOOKUP = lookupObject;
  87. }
  88. }
  89.  
Advertisement
Add Comment
Please, Sign In to add comment