/* * */ package org.smartly.commons.io.serialization.json.serializer; import org.smartly.commons.logging.Level; import org.smartly.commons.logging.Logger; import org.smartly.commons.logging.util.LoggingUtils; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * @author angelo.geminiani */ public class BeanData { /** * The readable properties of the bean. */ private Map<String, Method> _readableProps; /** * The writable properties of the bean. */ private Map<String, Method> _writableProps; public BeanData() { _readableProps = new HashMap<String, Method>(); _writableProps = new HashMap<String, Method>(); } public BeanData(final Class clazz) { this(); this.analyzeBean(clazz, true, false); } public BeanData(final Object instance) { this(); this.analyzeBean(instance.getClass(), true, false); } public Map<String, Method> getReadableProps() { return _readableProps; } public Map<String, Method> getWritableProps() { return _writableProps; } // ------------------------------------------------------------------------ // p r i v a t e // ------------------------------------------------------------------------ private Logger getlogger() { return LoggingUtils.getLogger(this); } /** * Analyses a bean, returning a BeanData with the data extracted from it. * * @param clazz The class of the bean to analyse */ private void analyzeBean(final Class clazz, final boolean onlyrwproperties, boolean includeSuperClass) { try { final Map<String, Method[]> methods = this.getProperties(clazz, onlyrwproperties, includeSuperClass); final Set<String> properties = methods.keySet(); for (final String property : properties) { final Method[] pair = methods.get(property); if (null != pair[0]) { _readableProps.put(property, pair[0]); } if (null != pair[1]) { _writableProps.put(property, pair[0]); } } } catch (Throwable t) { this.getlogger().log(Level.SEVERE, null, t); } } private Map<String, Method[]> getProperties(final Class klass, final boolean onlyrwproperties, boolean includeSuperClass) { final Map<String, Method[]> result = new HashMap<String, Method[]>(); if (klass.getClassLoader() == null) { includeSuperClass = false; } final Method[] methods = includeSuperClass ? klass.getMethods() : klass.getDeclaredMethods(); // add methods to map for (int i = 0; i < methods.length; i++) { try { final Method method = methods[i]; if (this.isValidMethod(method)) { final String name = method.getName(); final String key = this.getPropertyName(name); if (key.length() > 0) { if (!result.containsKey(key)) { result.put(key, new Method[]{null, null}); } final Method[] pair = result.get(key); if (name.startsWith("get") || name.startsWith("is")) { pair[0] = method; } else if (name.startsWith("set")) { pair[1] = method; } } } } catch (Throwable t) { } } // remove invalid methods if (onlyrwproperties) { final String[] keys = result.keySet().toArray(new String[result.keySet().size()]); for (final String key : keys) { final Method[] pair = result.get(key); if (null == pair[0] || null == pair[1]) { result.remove(key); } } } return result; } private String getPropertyName(final String methodName) { String key = ""; if (methodName.startsWith("get") || methodName.startsWith("set")) { key = methodName.substring(3); } else if (methodName.startsWith("is")) { key = methodName.substring(2); } if (key.length() > 0 && Character.isUpperCase(key.charAt(0))) { if (key.length() == 1) { key = key.toLowerCase(); } else if (!Character.isUpperCase(key.charAt(1))) { key = key.substring(0, 1).toLowerCase() + key.substring(1); } } return key; } private boolean isValidMethod(final Method method) { if (Modifier.isPublic(method.getModifiers())) { if (method.getName().startsWith("is") || method.getName().startsWith("get")) { return method.getParameterTypes().length == 0; } else if (method.getName().startsWith("set")) { return method.getParameterTypes().length == 1; } } return false; } }