MethodUtils.java

package org.microspace.specific;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.TreeMap;

import org.microspace.exception.IllegalOperationException;
import org.microspace.table.column.GetSetPair;
import org.microspace.table.column.Getter;
import org.microspace.table.column.Setter;

/**
 * Utility Class to scan methods.
 * 
 * @author Gaspar Sinai - {@literal gaspar.sinai@microspace.org}
 * @version 2016-06-26
 */
public class MethodUtils {

	public static <T> List<GetSetPair<T>> generateGetSetPairs (TreeMap<String, MethodBasedGetter<T>> getters, TreeMap<String, MethodBasedSetter<T>> setters) {
		List<GetSetPair<T>> ret = new ArrayList<GetSetPair<T>> ();
		// setters.keySet() iterator is ascending.
		for (Entry<String, MethodBasedSetter<T>> mapEntry : setters.entrySet()) {
			Setter<T> setter = mapEntry.getValue();
			Getter<T> getter = getters.get(setter.getName());
			if (getter == null) {
				continue;
			}
			GetSetPair<T> pair = new GetSetPair<T> (getter, setter, ret.size());
			ret.add (pair);
		}
		return ret;
	}
	
	public static <T> TreeMap<String, MethodBasedGetter<T>> scanGetters (Class<T> clazz, NullValueExtractor extractor) {
		TreeMap<String, MethodBasedGetter<T>> ret = new TreeMap<String, MethodBasedGetter<T>> ();
		
		for (Method m : clazz.getMethods()) {
			String name =  null;
			if (m.getName().length() > 3 && m.getName().startsWith("get")) {
				name = m.getName().substring(3,4).toLowerCase() + m.getName().substring(4);
			} else if (m.getName().length() > 2 && m.getName().startsWith("is")) {
				name = m.getName().substring(2,3).toLowerCase() + m.getName().substring(3);
			}
			if (name == null) continue;
			Class<?> retClass = m.getReturnType();
			if (void.class.equals (retClass)) continue;
			Class<?> pt[] = m.getParameterTypes();
			if (pt.length != 0) continue;
			int modifiers = m.getModifiers();
			if (!Modifier.isPublic (modifiers)) continue;
			if (Modifier.isStatic (modifiers)) continue;
			MethodBasedGetter<T> getter = new MethodBasedGetter<T> (m, name);
			getter.setNullValue(extractor.getNullValue(m));
			if (ret.put (getter.getName(), getter) != null) {
				throw new IllegalArgumentException ("Getter " + getter.getName() + " name clash");
			}
		}
		return ret;
	}

	public static <T> TreeMap<String, MethodBasedSetter<T>> scanSetters (Class<T> clazz) {
		TreeMap<String, MethodBasedSetter<T>> ret = new TreeMap<String, MethodBasedSetter<T>> ();
		
		for (Method m : clazz.getMethods()) {
			String name =  null;
			if (m.getName().length() > 3 && m.getName().startsWith("set")) {
				name = m.getName().substring(3,4).toLowerCase() + m.getName().substring(4);
			}
			if (name == null) continue;
			Class<?> retClass = m.getReturnType();
			if (!void.class.equals (retClass)) continue;
			Class<?> pt[] = m.getParameterTypes();
			if (pt.length != 1) continue;
			int modifiers = m.getModifiers();
			if (!Modifier.isPublic (modifiers)) continue;
			if (Modifier.isStatic (modifiers)) continue;
			MethodBasedSetter<T> setter = new MethodBasedSetter<T> (m, name);
			if (ret.put (setter.getName(), setter) != null) {
				throw new IllegalArgumentException ("Setter " + setter.getName() + " name clash");
			}
		}
		return ret;
	}

	public static <T> T getBlank (Class<T> targetClass) {
		try {
			Constructor<T> c = targetClass.getConstructor();
			return c.newInstance();
		} catch (Exception e){
			e.printStackTrace();
			throw new IllegalOperationException ("Class needs public constructor with no parameters: " + targetClass, e);
		}
	}

}