/*******************************************************************************
 * Copyright (c) 2004, 2005 Sybase, Inc. and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.facesconfig.ui.util;

import java.beans.Introspector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jst.jsf.common.ui.internal.utils.JavaModelUtil;

/**
 * This utility class is used to access java bean class, e.g., get java bean's
 * property
 * 
 * @author xgzhang
 * @version
 */
public final class JavaBeanUtils {
	/**
	 * fully qualified name of a List
	 */
	private static final String JAVA_UTIL_LIST = "java.util.List";

	/**
	 * fully qualifed name of a Map
	 */
	private static final String JAVA_UTIL_MAP = "java.util.Map";

	/**
	 * 
	 */
	private JavaBeanUtils() {
		super();
	}

	/**
	 * get the getter method according to property name
	 * 
	 * @param type
	 * @param propertyName
	 * @return - can be <b>null</b>, if not found
	 * @throws JavaModelException
	 * @throws JavaModelException
	 */
	private static IMethod getPropertyGetterMethod(IType type,
			String propertyName)  {
		if (type == null || !type.exists() || propertyName == null) {
			return null;
		}
		IMethod getterMethod = null;

		String methodBaseName = null;
		// Uppercase 1st letter
		if (propertyName.length() == 1) {
			methodBaseName = propertyName.substring(0, 1).toUpperCase();
		} else {
			methodBaseName = propertyName.substring(0, 1).toUpperCase()
					+ propertyName.substring(1);
		}

		String getterMethodName = "get" + methodBaseName;

		getterMethod = type.getMethod(getterMethodName, null);
		if (getterMethod == null || !getterMethod.exists()
				|| !JavaClassUtils.isPublicMethod(getterMethod)) {
			getterMethodName = "is" + methodBaseName;
			getterMethod = type.getMethod(getterMethodName, null);

			if (getterMethod == null || !getterMethod.exists()
					|| !JavaClassUtils.isPublicMethod(getterMethod)) {
				getterMethod = null;
			}
		}
		return getterMethod;
	}

	/**
	 * get the getter method in the type hierarchy according to property name
	 * 
	 * @param type
	 * @param propertyName
	 * @return - can be <b>null</b>, if not found
	 * @throws JavaModelException
	 * @throws JavaModelException
	 */
	private static IMethod getPropertyGetterMethodInTypeHierarchy(IType type,
			String propertyName) throws JavaModelException {
		if (type == null || !type.exists() || propertyName == null) {
			return null;
		}
		IMethod getterMethod = null;

		getterMethod = getPropertyGetterMethod(type, propertyName);

		if (getterMethod == null) {
			ITypeHierarchy typeHierarchy = null;
			typeHierarchy = type.newSupertypeHierarchy(null);

			if (typeHierarchy == null) {
				return null;
			}

			IType[] superTypes = typeHierarchy.getAllSuperclasses(type);

			if (superTypes == null || superTypes.length == 0) {
				return null;
			}
			for (int i = 0; i < superTypes.length; i++) {
				if (!superTypes[i].getFullyQualifiedName().equals(
						"java.lang.Object")) {
					getterMethod = getPropertyGetterMethod(superTypes[i],
							propertyName);
					if (getterMethod != null) {
						break;
					}
				}
			}
		}
		return getterMethod;
	}

	/**
	 * get the setter method in the type hierarchy according to property name
	 * 
	 * @param type
	 * @param propertyName
	 * @return - can be <b>null</b>, if not found
	 * @throws JavaModelException
	 */
	private static IMethod getPropertySetterMethodInTypeHierarchy(IType type,
			String propertyName) throws JavaModelException {
		if (type == null || !type.exists() || propertyName == null) {
			return null;
		}
		IMethod setterMethod = null;

		setterMethod = getPropertySetterMethod(type, propertyName);

		if (setterMethod == null) {
			ITypeHierarchy typeHierarchy = null;
			typeHierarchy = type.newSupertypeHierarchy(null);

			if (typeHierarchy == null) {
				return null;
			}

			IType[] superTypes = typeHierarchy.getAllSuperclasses(type);

			if (superTypes == null || superTypes.length == 0) {
				return null;
			}
			for (int i = 0; i < superTypes.length; i++) {
				if (!superTypes[i].getFullyQualifiedName().equals(
						"java.lang.Object")) {
					setterMethod = getPropertySetterMethod(superTypes[i],
							propertyName);
					if (setterMethod != null) {
						break;
					}
				}
			}
		}

		return setterMethod;
	}

	/**
	 * get the setter method according to property name
	 * 
	 * @param type
	 * @param propertyName
	 * @return - can be <b>null</b>, if not found
	 * @throws JavaModelException
	 */
	private static IMethod getPropertySetterMethod(IType type,
			String propertyName) throws JavaModelException {
		if (type == null || !type.exists() || propertyName == null) {
			return null;
		}
		IMethod setterMethod = null;

		String methodBaseName = null;
		// Uppercase 1st letter
		if (propertyName.length() == 1) {
			methodBaseName = propertyName.substring(0, 1).toUpperCase();
		} else {
			methodBaseName = propertyName.substring(0, 1).toUpperCase()
					+ propertyName.substring(1);
		}

		String setterMethodName = "set" + methodBaseName;

		IMethod[] methods = null;

		methods = type.getMethods();

		if (methods == null || methods.length == 0) {
			return null;
		}

		for (int i = 0; i < methods.length; i++) {
			if (methods[i].getElementName().equals(setterMethodName)) {
				if (methods[i] == null || !methods[i].exists()
						|| !JavaClassUtils.isPublicMethod(methods[i])) {
					continue;
				}

				// Method must return void
				String returnType = methods[i].getReturnType();
				if (!returnType.equals(Signature.SIG_VOID)) {
					continue;
				}

				String params[] = methods[i].getParameterTypes();
				// method must have only one argument
				if (params.length != 1) {
					continue;
				}
				setterMethod = methods[i];
			}
		}

		return setterMethod;
	}

	/**
	 * Check whether the propertyName is bean's property or not.
	 * 
	 * @param baseType
	 * @param propertyName
	 * 
	 * @return - True means the property name is valid bean's property,
	 *         otherwise, not.
	 * 
	 */
	public static boolean isBeanProperty(IType baseType, String propertyName)
    {
		if (baseType == null || !baseType.exists() || propertyName == null) {
			return false;
		}

		return (getBeanPropertyType(baseType, propertyName) != null);
	}

	/**
	 * get the bean's property type
	 * 
	 * @param baseType
	 * @param propertyName
	 * @return - can be <b>null</b>, if not found
	 * 
	 */
	public static IType getBeanPropertyType(IType baseType, String propertyName) {
		if (baseType == null || !baseType.exists() || propertyName == null) {
			return null;
		}

		String typeSignature = null;
		IMethod getterMethod = null;
		IMethod setterMethod = null;

		IType declaredType = baseType;
		try {
			getterMethod = getPropertyGetterMethodInTypeHierarchy(baseType,
					propertyName);
			setterMethod = getPropertySetterMethodInTypeHierarchy(baseType,
					propertyName);
		} catch (JavaModelException e1) {
			// Need not any error handling.
		}

		if (getterMethod != null && setterMethod == null) {
			declaredType = getterMethod.getDeclaringType();
			try {
				typeSignature = getterMethod.getReturnType();
			} catch (JavaModelException e2) {
				// Need not any error handling.
			}
		} else if (setterMethod != null && getterMethod == null) {
			declaredType = setterMethod.getDeclaringType();
			typeSignature = setterMethod.getParameterTypes()[0];
		} else if (setterMethod != null && getterMethod != null) {
			declaredType = getterMethod.getDeclaringType();
			try {
				// FIXME: should check the type hierachy
				if (getterMethod.getReturnType().equals(
						setterMethod.getParameterTypes()[0])) {
					typeSignature = getterMethod.getReturnType();
				}
			} catch (JavaModelException e2) {
				// Need not any error handling.
			}
		}

		if (typeSignature == null) {
			return null;
		}

		IType type = null;

		try {
			String typeName = JavaModelUtil.getResolvedTypeName(typeSignature,
					declaredType);
			if (typeName != null) {
				type = baseType.getJavaProject().findType(typeName);
			}
		} catch (JavaModelException e) {
			// Need not any error handling.
		}
		return type;
	}

	/**
	 * get the bean's property's getter and setter methods.
	 * 
	 * @param baseType
	 * @param propertyName
	 * @return - IMethod[], the first is getter and the second is setter method,
	 *         however, both of them can be null.
	 */
	public static IMethod[] getBeanPropertyMethods(IType baseType,
			String propertyName) {
		if (baseType == null || !baseType.exists() || propertyName == null) {
			return null;
		}

		IMethod[] methods = new IMethod[2];

		IMethod getterMethod = null;
		IMethod setterMethod = null;
		try {
			getterMethod = getPropertyGetterMethodInTypeHierarchy(baseType,
					propertyName);

			setterMethod = getPropertySetterMethodInTypeHierarchy(baseType,
					propertyName);
		} catch (JavaModelException e) {
			// Need not any error handling.
		}

		if (getterMethod != null && setterMethod == null) {
			methods[0] = getterMethod;
		} else if (setterMethod != null && getterMethod == null) {
			methods[1] = setterMethod;
		} else if (setterMethod != null && getterMethod != null) {
			try {
				// FIXME: should check the type hierachy
				if (getterMethod.getReturnType().equals(
						setterMethod.getParameterTypes()[0])) {
					methods[0] = getterMethod;
					methods[1] = setterMethod;
				}
			} catch (JavaModelException e1) {
				// Need not any error handling.
			}
		}

		return methods;
	}

	/**
	 * check whether the type implements <code>java.util.List</code>
	 * 
	 * @param type
	 * @return - True if the type is the sub class of
	 *         <code>java.util.List</code>, otherwise, not.
	 */
	public static boolean isListType(IType type) {
		if (type == null) {
			return false;
		}
		if (type.getFullyQualifiedName().equalsIgnoreCase(JAVA_UTIL_LIST)) {
			return true;
		}

		return JavaClassUtils.isSubClassOf(type.getJavaProject(), type
				.getFullyQualifiedName(), JAVA_UTIL_LIST);
	}

	/**
	 * check whether the type implements <code>java.util.Map</code>
	 * 
	 * @param type
	 * @return - True if the type is the sub class of <code>java.uitl.Map</code>,
	 *         otherwise, not.
	 */
	public static boolean isMapType(IType type) {
		if (type == null) {
			return false;
		}
		if (type.getFullyQualifiedName().equalsIgnoreCase(JAVA_UTIL_MAP)) {
			return true;
		}

		return JavaClassUtils.isSubClassOf(type.getJavaProject(), type
				.getFullyQualifiedName(), JAVA_UTIL_MAP);
	}

	/**
	 * Test for method inclusion in bindings list.
	 * <p>
	 * This test has the following conditions:
	 * </p>
	 * <ul>
	 * <li>method starts with <code>get</code></li>
	 * <li>method has no arguments</li>
	 * <li>method does not return void</li>
	 * </ul>
	 * 
	 * @param method -
	 *            the IMethod to examine
	 * @return boolean - true, if method satisfies the condition test
	 */
	public static boolean isGetterMethod(IMethod method) {
		try {
			if (!JavaClassUtils.isPublicMethod(method)) {
				return false;
			}
			String params[] = method.getParameterTypes();
			// Has no arguments
			if (params.length > 0) {
				return false;
			}

			// Starts with "get"
			if (!(method.getElementName().startsWith("get") || method.getElementName().startsWith("is"))) //$NON-NLS-1$
			{
				return false;
			}
			// Does not return void
			String rtn = method.getReturnType();
			if (!rtn.equals(Signature.SIG_VOID)) {
				return true;
			}
		} catch (JavaModelException e) {
			// Need not any error handling.
		}
		return false;
	}

	/**
	 * Test for method inclusion in bindings list.
	 * <p>
	 * This test has the following conditions:
	 * </p>
	 * <ul>
	 * <li>method starts with <code>set</code></li>
	 * <li>method returns void</li>
	 * </ul>
	 * 
	 * @param method -
	 *            the IMethod to examine
	 * @return boolean - true, if method satisfies the condition test
	 */
	public static boolean isSetterMethod(IMethod method) {
		try {
			if (!JavaClassUtils.isPublicMethod(method)) {
				return false;
			}
			// Starts with "set"
			if (!method.getElementName().startsWith("set")) //$NON-NLS-1$
			{
				return false;
			}

			// the parameter's number should be one.
			if (method.getParameterTypes().length != 1) {
				return false;
			}
			// Returns void
			String rtn = method.getReturnType();
			if (rtn.equals(Signature.SIG_VOID)) {
				return true;
			}
		} catch (JavaModelException e) {
			// Need not any error handling.
		}
		return false;
	}

	/**
	 * set the first character into low case.
	 * 
	 * @param str
	 * @return str with the first char lower cased
	 */
	public static String toLowCaseFirstChar(String str) {
		// change the first alphabet to lowcase.
		if (str != null && str.length() > 0) {
			if (str.length() == 1) {
				str = str.toLowerCase();
			} else {
				str = str.substring(0, 1).toLowerCase() + str.substring(1);
			}
		}
		return str;
	}

	/**
	 * set the first character into low case.
	 * 
	 * @param str
	 * @return str with the first char upper-cased
	 */
	public static String toUpperCaseFirstChar(String str) {
		// change the first alphabet to lowcase.
		if (str != null && str.length() > 0) {
			if (str.length() == 1) {
				str = str.toUpperCase();
			} else {
				str = str.substring(0, 1).toUpperCase() + str.substring(1);
			}
		}
		return str;
	}

	/**
	 * get property name from getter method.
	 * 
	 * @param method
	 * @return - can be <b>null</b>, if the method is not a valid getter method
	 */
	public static String getPropertyNameFromGetterMethod(IMethod method) {
		if (!isGetterMethod(method)) {
			return null;
		}
		String methodName = method.getElementName();
		String propertyName = null;
		// Starts with "get"
		if (methodName.startsWith("get") && methodName.length() > 3) {
			propertyName = methodName.substring(3);
		} else if (methodName.startsWith("is") && methodName.length() > 2) // Starts
		// with
		// "is"
		{
			propertyName = methodName.substring(2);
		}
		propertyName = Introspector.decapitalize(propertyName);
		return propertyName;
	}

	/**
	 * get property name from setter class.
	 * 
	 * @param method
	 * @return - can be <b>null</b>, if the method is not a valid setter method
	 */
	public static String getPropertyNameFromSetterMethod(IMethod method) {
		if (!isSetterMethod(method)) {
			return null;
		}
		String methodName = method.getElementName();
		String propertyName = null;
		// Starts with "get"
		if (methodName.startsWith("set") && methodName.length() > 3) {
			propertyName = methodName.substring(3);
		}
		propertyName = Introspector.decapitalize(propertyName);
		return propertyName;
	}

	/**
	 * get the method with the same parameters
	 * 
	 * @param methods
	 * @param visitedMethods
	 * @param foundMethod
	 * @param foundMethodName
	 * @param foundParamTypes
	 * @return
	 */
	private static IMethod getMethodWithSameParamters(IMethod[] methods,
			Map visitedMethods, IMethod foundMethod, String foundMethodName,
			String[] foundParamTypes) {
		// get all qualified type name for the found method's parameters.
		String[] foundParamQulifiedTypeNames = null;
		if (foundParamTypes != null && foundParamTypes.length > 0) {
			foundParamQulifiedTypeNames = new String[foundParamTypes.length];
			for (int i = 0; i < foundParamTypes.length; i++) {
				foundParamQulifiedTypeNames[i] = JavaClassUtils
						.getQualifiedTypeNameInTypeHierarchy(foundMethod
								.getDeclaringType(), foundParamTypes[i]);
			}
		}
		for (int i = 0; i < methods.length; i++) {
			if (visitedMethods.get(methods[i]) != null) {
				continue;
			}

			if (!methods[i].getElementName().equals(foundMethodName)) {
				continue;
			}
			if (methods[i].getParameterTypes() == null
					&& foundParamTypes == null) {
				return methods[i];
			} else if (methods[i].getParameterTypes() != null
					&& foundParamTypes != null
					&& foundParamTypes.length == methods[i].getParameterTypes().length) {
				boolean bSameParams = true;
				String[] methodParamTypes = methods[i].getParameterTypes();
				for (int j = 0; j < foundParamQulifiedTypeNames.length; j++) {
					String methodParamQualifiedTypeName = JavaClassUtils
							.getQualifiedTypeNameInTypeHierarchy(methods[i]
									.getDeclaringType(), methodParamTypes[j]);
					// if the qualified type name is not same or not subclass or
					// supper class between each other.
					if (!methodParamQualifiedTypeName
							.equals(foundParamQulifiedTypeNames[j])
							&& !JavaClassUtils.isSubClassOf(methods[i]
									.getJavaProject(),
									methodParamQualifiedTypeName,
									foundParamQulifiedTypeNames[j])
							&& !JavaClassUtils.isSubClassOf(methods[i]
									.getJavaProject(),
									foundParamQulifiedTypeNames[j],
									methodParamQualifiedTypeName)) {
						bSameParams = false;
						break;
					}
				}
				if (bSameParams) {
					return methods[i];
				}
			}
		}
		return null;
	}

	/**
	 * Creates an array of bean properties
	 * 
	 * 
	 * @param classType
	 * @return it can be <b>null</b>, if property is not found.
	 */
	public static JavaBeanProperty[] getBeanProperties(IType classType) {
		IMethod[] methods;
		try {
			methods = JavaClassUtils.getMethods(classType);
		} catch (JavaModelException e2) {
			return null;
		}

		return getBeanProperties(classType, methods);
	}

	/**
	 * Creates an array of bean properties
	 * 
	 * @param type
	 * @param methods
	 * 
	 * @return - the array of java bean properties.
	 */
	public static JavaBeanProperty[] getBeanProperties(IType type,
			IMethod[] methods) {
		if (methods == null || methods.length == 0) {
			return null;
		}

		List properties = new ArrayList();
		Map visitedMethods = new HashMap();
		for (int m = 0; m < methods.length; m++) {
			String propertyName = null;
			// if a property's getter method or setter method already visited,
			// just skip it.
			if (visitedMethods.get(methods[m]) != null) {
				continue;
			}

			visitedMethods.put(methods[m], methods[m]);

			// Check getter firstly
			propertyName = JavaBeanUtils
					.getPropertyNameFromGetterMethod(methods[m]);

			if (propertyName != null && propertyName.length() > 0) //$NON-NLS-1$
			{
				String setterMethodName = "set"
						+ JavaBeanUtils.toUpperCaseFirstChar(propertyName);

				String getterReturnType = null;
				try {
					getterReturnType = methods[m].getReturnType();
				} catch (JavaModelException e1) {
					continue;
				}
				IMethod setterMethod = getMethodWithSameParamters(methods,
						visitedMethods, methods[m], setterMethodName,
						new String[] { getterReturnType });
				if (setterMethod != null && setterMethod.exists()) {
					visitedMethods.put(setterMethod, setterMethod);
				}

				properties.add(new JavaBeanProperty(propertyName,
						getterReturnType, methods[m], setterMethod));
				continue;
			}

			// Check setter secondly.
			propertyName = JavaBeanUtils
					.getPropertyNameFromSetterMethod(methods[m]);

			if (propertyName != null && propertyName.length() > 0) //$NON-NLS-1$
			{
				// first form of getter method, "get..."
				String getterMethodName = "get"
						+ JavaBeanUtils.toUpperCaseFirstChar(propertyName);
				IMethod getterMethod = getMethodWithSameParamters(methods,
						visitedMethods, methods[m], getterMethodName, null);

				if (getterMethod != null && getterMethod.exists()) {
					try {
						if (getterMethod.getReturnType().equals(
								methods[m].getParameterTypes()[0])) {
							visitedMethods.put(getterMethod, getterMethod);
						}
					} catch (JavaModelException e) {
						// need not error logging
					}
				} else {
					// another form of getter method, "is...".
					getterMethodName = "is"
							+ JavaBeanUtils.toUpperCaseFirstChar(propertyName);
					getterMethod = getMethodWithSameParamters(methods,
							visitedMethods, methods[m], getterMethodName, null);
					try {
						if (getterMethod != null
								&& getterMethod.exists()
								&& getterMethod.getReturnType().equals(
										methods[m].getParameterTypes()[0])) {
							visitedMethods.put(getterMethod, getterMethod);
						}
					} catch (JavaModelException e) {
						// need not error logging
					}
				}

				properties.add(new JavaBeanProperty(propertyName, methods[m]
						.getParameterTypes()[0], getterMethod, methods[m]));
				continue;
			}
		}

		JavaBeanProperty[] propertyArray = (JavaBeanProperty[]) properties
				.toArray(new JavaBeanProperty[properties.size()]);

		Arrays.sort(propertyArray, new Comparator() {
			public int compare(Object o1, Object o2) {
				String name1 = ((JavaBeanProperty) o1).getName();
				String name2 = ((JavaBeanProperty) o2).getName();
				return name1.compareTo(name2);
			}
		});
		return propertyArray;
	}
}
