package pluginbase.config.properties; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import pluginbase.config.field.FieldInstance; import pluginbase.config.field.PropertyVetoException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; class DefaultPropertyHandler implements PropertyHandler<Object> { private static final Map<Class, Method> VALUE_OF_METHODS = new HashMap<Class, Method>(); private static final Map<Class, Class> PRIMITIVE_WRAPPER_MAP; static { Map<Class, Class> map = new HashMap<Class, Class>(); map.put(int.class, Integer.class); map.put(boolean.class, Boolean.class); map.put(long.class, Long.class); map.put(double.class, Double.class); map.put(float.class, Float.class); map.put(byte.class, Byte.class); map.put(short.class, Short.class); PRIMITIVE_WRAPPER_MAP = Collections.unmodifiableMap(map); } protected static Method getValueOfMethod(Class clazz) throws NoSuchMethodException { Method method = VALUE_OF_METHODS.get(clazz); if (method == null) { method = cacheValueOfMethod(clazz); } return method; } private static Method cacheValueOfMethod(Class clazz) throws NoSuchMethodException { Method method = clazz.getDeclaredMethod("valueOf", String.class); if (Modifier.isStatic(method.getModifiers())) { method.setAccessible(true); VALUE_OF_METHODS.put(clazz, method); return method; } throw new NoSuchMethodException("valueOf(String) method is not static."); } private static Object getValueFromString(String value, Class desiredType) { if (PRIMITIVE_WRAPPER_MAP.containsKey(desiredType)) { desiredType = PRIMITIVE_WRAPPER_MAP.get(desiredType); } if (desiredType.equals(String.class)) { return value; } if (Enum.class.isAssignableFrom(desiredType)) { Enum e = EnumUtil.matchEnum(desiredType, value); if (e != null) { return e; } } try { Method method = getValueOfMethod(desiredType); return method.invoke(null, value); } catch (NoSuchMethodException e) { throw new IllegalArgumentException(e); } catch (IllegalAccessException e) { throw new IllegalArgumentException(e); } catch (InvocationTargetException e) { throw new IllegalArgumentException(e); } } @Override public void set(@NotNull FieldInstance field, @NotNull String newValue) throws PropertyVetoException, UnsupportedOperationException { if (field.getCollectionType() != null) { throw new UnsupportedOperationException(); } field.setValue(getValueFromString(newValue, field.getType())); } @Override public void add(@NotNull FieldInstance field, @NotNull String valueToAdd) throws PropertyVetoException, UnsupportedOperationException { if (field.getCollectionType() == null) { throw new UnsupportedOperationException(); } Object currentValue = field.getValue(); if (currentValue == null) { throw new IllegalStateException("Cannot modify null collection"); } Collection collection = (Collection) currentValue; Object value = getValueFromString(valueToAdd, field.getCollectionType()); collection.add(value); } @Override public void remove(@NotNull FieldInstance field, @NotNull String valueToRemove) throws PropertyVetoException, UnsupportedOperationException { if (field.getCollectionType() == null) { throw new UnsupportedOperationException(); } Object currentValue = field.getValue(); if (currentValue == null) { throw new IllegalStateException("Cannot modify null collection"); } Collection collection = (Collection) currentValue; Object value = getValueFromString(valueToRemove, field.getCollectionType()); collection.remove(value); } @Override public void clear(@NotNull FieldInstance field, @Nullable String valueToClear) throws PropertyVetoException, UnsupportedOperationException { if (field.getCollectionType() == null) { throw new UnsupportedOperationException(); } Object currentValue = field.getValue(); if (currentValue == null) { throw new IllegalStateException("Cannot modify null collection"); } Collection collection = (Collection) currentValue; collection.clear(); } }