package com.peterhi.almostworking;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import com.peterhi.CoreUtilities;
public class ObjectModelUtilities {
private static Map objectModelPropertiesMap;
public static boolean isCollection(Class type) {
if (type == Set.class) {
return true;
}
if (type == List.class) {
return true;
}
if (type == Map.class) {
return true;
}
return false;
}
public static boolean isSupported(Class type) {
if (type.isPrimitive()) {
return true;
}
if (CoreUtilities.isBoxer(type)) {
return true;
}
if (type == String.class) {
return true;
}
if (type == HashSet.class) {
return true;
}
if (type == ArrayList.class) {
return true;
}
if (type == HashMap.class) {
return true;
}
if (isCollection(type)) {
return true;
}
if (ObjectModel.class.isAssignableFrom(type)) {
return true;
}
if (type == Object.class) {
return true;
}
if (type.isArray()) {
return isSupported(type.getComponentType());
}
return false;
}
public static String getPrefix(Class returnType) {
if (returnType == void.class) {
return "set"; //$NON-NLS-1$
}
if (returnType == boolean.class) {
return "is"; //$NON-NLS-1$
}
if (isCollection(returnType)) {
return ""; //$NON-NLS-1$
}
return "get"; //$NON-NLS-1$
}
public static boolean isGetter(Method method) {
String methodName = method.getName();
Class returnType = method.getReturnType();
String prefix = getPrefix(returnType);
if (methodName.length() <= prefix.length()) {
return false;
}
if (!methodName.startsWith(prefix)) {
return false;
}
if (!isSupported(returnType)) {
return false;
}
Class[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length != 0) {
return false;
}
return true;
}
public static boolean isSetter(Method method) {
String methodName = method.getName();
Class returnType = method.getReturnType();
String prefix = getPrefix(returnType);
if (methodName.length() <= prefix.length()) {
return false;
}
if (!methodName.startsWith(prefix)) {
return false;
}
if (returnType != void.class) {
return false;
}
Class[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length != 1) {
return false;
}
if (!isSupported(parameterTypes[0])) {
return false;
}
if (isCollection(parameterTypes[0])) {
return false;
}
return true;
}
public static Class getType(ObjectModel objectModel) {
Class objectModelType = objectModel.getClass();
if (Proxy.isProxyClass(objectModelType)) {
ObjectModelInvocationHandler invocationHandler =
(ObjectModelInvocationHandler )Proxy.getInvocationHandler(objectModel);
objectModelType = invocationHandler.getInterfaceType();
}
return objectModelType;
}
public static String getPropertyName(Method method) {
String methodName = method.getName();
Class returnType = method.getReturnType();
String prefix = getPrefix(returnType);
String propertyName = methodName.substring(prefix.length());
propertyName = Character.toLowerCase(propertyName.charAt(0)) + propertyName.substring(1);
return propertyName;
}
public static ObjectModelPropertyDescriptor[] getProperties(Class objectModelType) {
Map theObjectModelPropertiesMap = getObjectModelPropertiesMap();
ObjectModelPropertyDescriptor[] objectModelProperties = (ObjectModelPropertyDescriptor[] )
theObjectModelPropertiesMap.get(objectModelType);
if (objectModelProperties == null) {
objectModelProperties = createObjectModelProperties(objectModelType);
theObjectModelPropertiesMap.put(objectModelType, objectModelProperties);
}
return objectModelProperties;
}
public static ObjectModelPropertyDescriptor[] getProperties(ObjectModel objectModel) {
Class objectModelType = getType(objectModel);
return getProperties(objectModelType);
}
public static ObjectModelPropertyDescriptor getProperty(Class objectModelType, String propertyName) {
ObjectModelPropertyDescriptor[] properties = getProperties(objectModelType);
for (ObjectModelPropertyDescriptor property : properties) {
if (property.getName().equals(propertyName)) {
return property;
}
}
return null;
}
public static ObjectModelPropertyDescriptor getProperty(ObjectModel objectModel, String propertyName) {
ObjectModelPropertyDescriptor[] properties = getProperties(objectModel);
for (ObjectModelPropertyDescriptor property : properties) {
if (property.getName().equals(propertyName)) {
return property;
}
}
return null;
}
public static Object getPropertyValue(ObjectModel objectModel, String propertyName) {
ObjectModelPropertyDescriptor property = getProperty(objectModel, propertyName);
return property.getPropertyValue(objectModel);
}
public static void setPropertyValue(ObjectModel objectModel, String propertyName, Object propertyValue) {
ObjectModelPropertyDescriptor property = getProperty(objectModel, propertyName);
property.setPropertyValue(objectModel, propertyValue);
}
public static void addPropertyListener(ObjectModel objectModel, String propertyName, ObjectModelPropertyListener listener) {
ObjectModelPropertyDescriptor property = getProperty(objectModel, propertyName);
property.addListener(objectModel, listener);
}
public static void removePropertyListener(ObjectModel objectModel, String propertyName, ObjectModelPropertyListener listener) {
ObjectModelPropertyDescriptor property = getProperty(objectModel, propertyName);
property.removeListener(objectModel, listener);
}
public static ObjectModel createLocalObjectModel(Class objectModelType) {
ClassLoader classLoader = objectModelType.getClassLoader();
Class[] objectModelTypes = new Class[] { objectModelType };
InvocationHandler invocationHandler = new ObjectModelInvocationHandler(objectModelType);
ObjectModel objectModel = (ObjectModel )Proxy.newProxyInstance(classLoader, objectModelTypes, invocationHandler);
return objectModel;
}
private static ObjectModelPropertyDescriptor[] createObjectModelProperties(Class objectModelType) {
Set<ObjectModelPropertyDescriptor> properties = new TreeSet();
Method[] methods = objectModelType.getMethods();
for (Method method : methods) {
if (isGetter(method)) {
Method getterMethod = method;
Class propertyType = getterMethod.getReturnType();
String propertyName = getPropertyName(getterMethod);
Method setterMethod = getSetter(objectModelType, propertyName, propertyType);
ObjectModelPropertyDescriptor property = new ObjectModelPropertyDescriptor(objectModelType,
propertyType, propertyName, getterMethod, setterMethod);
properties.add(property);
}
}
ObjectModelPropertyDescriptor[] propertyArray = properties.toArray(new ObjectModelPropertyDescriptor[properties.size()]);
return propertyArray;
}
private static Method getSetter(Class objectModelType, String propertyName, Class propertyType) {
String prefix = "set"; //$NON-NLS-1$
String methodName = prefix + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
Method[] methods = objectModelType.getMethods();
for (Method method : methods) {
if (!method.getName().equals(methodName)) {
continue;
}
Class returnType = method.getReturnType();
if (returnType != void.class) {
continue;
}
Class[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length != 1) {
continue;
}
if (parameterTypes[0] != propertyType) {
continue;
}
return method;
}
return null;
}
private static Map getObjectModelPropertiesMap() {
if (objectModelPropertiesMap == null) {
objectModelPropertiesMap = new HashMap();
}
return objectModelPropertiesMap;
}
}