package games.strategy.util; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * Utility for getting/setting java bean style properties on an object. */ public class PropertyUtil { public static void set(final String propertyName, final Object value, final Object subject) { final Method m = getSetter(propertyName, subject, value); try { m.setAccessible(true); m.invoke(subject, value); } catch (final Exception e) { throw new IllegalStateException( "Could not set property:" + propertyName + " subject:" + subject + " new value:" + value, e); } } /** * You don't want to clear the variable first unless you are setting some variable where the setting method is * actually adding things to a * list rather than overwriting. */ public static void set(final String propertyName, final Object value, final Object subject, final boolean resetFirst) { if (resetFirst) { reset(propertyName, subject); } set(propertyName, value, subject); } public static void reset(final String propertyName, final Object subject) { try { final Method c = getResetter(propertyName, subject); c.setAccessible(true); c.invoke(subject); } catch (final Exception e) { throw new IllegalStateException("Could not reset property:" + propertyName + " subject:" + subject, e); } } public static Field getFieldIncludingFromSuperClasses(final Class<?> c, final String name, final boolean justFromSuper) { Field rVal = null; if (!justFromSuper) { try { rVal = c.getDeclaredField(name); // TODO: unchecked reflection return rVal; } catch (final NoSuchFieldException e) { return getFieldIncludingFromSuperClasses(c, name, true); } } else { if (c.getSuperclass() == null) { throw new IllegalStateException("No such Property Field: " + name); } try { rVal = c.getSuperclass().getDeclaredField(name); // TODO: unchecked reflection return rVal; } catch (final NoSuchFieldException e) { return getFieldIncludingFromSuperClasses(c.getSuperclass(), name, true); } } } public static Object getPropertyFieldObject(final String propertyName, final Object subject) { try { final Field field = getPropertyField(propertyName, subject); field.setAccessible(true); return field.get(subject); } catch (final Exception e) { final String msg = "No such Property Field named: " + "m_" + propertyName + ", or: " + propertyName + ", for Subject: " + subject.toString(); throw new IllegalStateException(msg, e); } } private static Field getPropertyField(final String propertyName, final Object subject) { try { return getFieldIncludingFromSuperClasses(subject.getClass(), "m_" + propertyName, false); } catch (final Exception e) { try { return getFieldIncludingFromSuperClasses(subject.getClass(), propertyName, false); } catch (final Exception exception) { throw exception; } } } private static String capitalizeFirstLetter(final String aString) { char first = aString.charAt(0); first = Character.toUpperCase(first); return first + aString.substring(1); } private static Method getSetter(final String propertyName, final Object subject, final Object value) { final String setterName = "set" + capitalizeFirstLetter(propertyName); // for (final Method m : subject.getClass().getDeclaredMethods()) for (final Method m : subject.getClass().getMethods()) { if (m.getName().equals(setterName)) { try { final Class<?> argType = value.getClass(); return subject.getClass().getMethod(setterName, argType); } catch (final NoSuchMethodException nsmf) { // Go ahead and try the first one return m; } catch (final NullPointerException n) { // Go ahead and try the first one return m; } } } throw new IllegalStateException("No method called:" + setterName + " on:" + subject); } private static Method getResetter(final String propertyName, final Object subject) { final String resetterName = "reset" + capitalizeFirstLetter(propertyName); // for (final Method c : subject.getClass().getDeclaredMethods()) for (final Method c : subject.getClass().getMethods()) { if (c.getName().equals(resetterName)) { try { return subject.getClass().getMethod(resetterName); } catch (final NoSuchMethodException nsmf) { // Go ahead and try the first one return c; } catch (final NullPointerException n) { // Go ahead and try the first one return c; } } } throw new IllegalStateException("No method called:" + resetterName + " on:" + subject); } }