EhCache config with BeanUtils

BeanUtils allows you to set Bean properties.If you have configuration stored in a Map it’s tempting to use BeanUtils to automagically setup EhCache configuration.Sadly this class has mixed types in setters and getter and thus BeanUtils that use Introsp…

BeanUtils allows you to set Bean properties.
If you have configuration stored in a Map it’s tempting to use BeanUtils to automagically setup EhCache configuration.
Sadly this class has mixed types in setters and getter and thus BeanUtils that use Introspector behind won’t get getter and setter pairs properly. It will get only getters and thus inform you that these properties are read only: “Skipping read-only property”.

My fast solution is to use BeanUtils and have a fallback to Reflection.

public static void setProperty(Object obj, String propertyName, Object propertyValue, boolean silently) {
try {
PropertyDescriptor desc = PropertyUtils.getPropertyDescriptor(obj, propertyName);
Method writeMethod = desc.getWriteMethod();

if (writeMethod == null) {
writeMethod = getAlternativeWriteMethod(obj, propertyName, propertyValue.getClass());
}

if (writeMethod == null) {
if (silently) {
return;
}
throw new IllegalArgumentException("Can't find writerMethod for " + propertyName);
}

if (LOG.isTraceEnabled()) {
LOG.trace(String.format("Setting %s property of %s", propertyName, obj.getClass().getSimpleName()));
}

writeMethod.invoke(obj, propertyValue);
} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
throw new IllegalArgumentException("Error when setting object property.", e);
}
}

private static Method getAlternativeWriteMethod(Object obj, String propertyName, Class paramClass) throws NoSuchMethodException {
String setterMethod = "set" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
Method m;
if ((m = getMethod(obj, paramClass, setterMethod)) != null) {
return m;
}
Class altClass = paramClass.isPrimitive() ? ClassUtils.primitiveToWrapper(paramClass) : ClassUtils.wrapperToPrimitive(paramClass);
if ((m = getMethod(obj, altClass, setterMethod)) != null) {
return m;
}

return null;
}

private static Method getMethod(Object obj, Class paramClass, String setterMethod) {

try {
return obj.getClass().getMethod(setterMethod, paramClass);
} catch (NoSuchMethodException e) {
return null;
}
}

I will think about PR to Configuration class but it’s complicated as EhCache 2.x is not present on GitHub.

You May Also Like

New HTTP Logger Grails plugin

I've wrote a new Grails plugin - httplogger. It logs:

  • request information (url, headers, cookies, method, body),
  • grails dispatch information (controller, action, parameters),
  • response information (elapsed time and body).

It is mostly useful for logging your REST traffic. Full HTTP web pages can be huge to log and generally waste your space. I suggest to map all of your REST controllers with the same path in UrlMappings, e.g. /rest/ and configure this plugin with this path.

Here is some simple output just to give you a taste of it.

17:16:00,331 INFO  filters.LogRawRequestInfoFilter  - 17:16:00,340 INFO  filters.LogRawRequestInfoFilter  - 17:16:00,342 INFO  filters.LogGrailsUrlsInfoFilter  - 17:16:00,731 INFO  filters.LogOutputResponseFilter  - >> #1 returned 200, took 405 ms.
17:16:00,745 INFO filters.LogOutputResponseFilter - >> #1 responded with '{count:0}'
17:18:55,799 INFO  filters.LogRawRequestInfoFilter  - 17:18:55,799 INFO  filters.LogRawRequestInfoFilter  - 17:18:55,800 INFO  filters.LogRawRequestInfoFilter  - 17:18:55,801 INFO  filters.LogOutputResponseFilter  - >> #2 returned 404, took 3 ms.
17:18:55,802 INFO filters.LogOutputResponseFilter - >> #2 responded with ''

Official plugin information can be found on Grails plugins website here: http://grails.org/plugins/httplogger or you can browse code on github: TouK/grails-httplogger.