/*******************************************************************************
 * Copyright (c) 2003, 2005 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jem.internal.java.adapters.jdk;
/*
 *  $RCSfile: JDKAdaptor.java,v $
 *  $Revision: 1.7 $  $Date: 2005/08/24 20:20:25 $ 
 */

import java.lang.reflect.Array;

import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.jem.java.*;
import org.eclipse.jem.internal.java.adapters.JavaReflectionAdaptor;
/**
 * Insert the type's description here.
 * Creation date: (6/6/2000 4:42:50 PM)
 * @author: Administrator
 */
public abstract class JDKAdaptor extends JavaReflectionAdaptor {
	public JavaJDKAdapterFactory adapterFactory;
	public JDKAdaptor(Notifier target, JavaJDKAdapterFactory anAdapterFactory) {
		super(target);
		setAdapterFactory(anAdapterFactory);
	}
	/**
	 * computeMethodID - generate the unique ID to be used to identify a constructor.
	 * Similar to a Signature, but hopefully more readable.
	 * The name format will be:
	 * 	simpleClassName.simpleClassName(com.fronk.ParmType1_parmType2&V
	 * Note: This implementation is tightly coupled with ReflectionAdapter.getTypeNamesFromMethodID().
	 *
	 * It has to be done separately for JDK because Constructors and Methods are different classes.
	 * However, in the Java Model they are both just Methods with a flag indicating Constructor.
	 */
	public static String computeMethodID(java.lang.reflect.Constructor jdkConstructor) {
		StringBuffer out = new StringBuffer();
		String className = getSimpleName(jdkConstructor.getDeclaringClass().getName());
		out.append(className);
		out.append(C_CLASS_MEMBER_DELIMITER);
		out.append(computeMethodName(jdkConstructor));
		out.append(C_METHOD_PARM_DELIMITER);
		Class[] parmTypes = jdkConstructor.getParameterTypes();
		for (int i = 0; i < parmTypes.length; i++) {
			out.append(parmTypes[i].getName());
			if (i < parmTypes.length - 1)
				out.append(C_PARM_PARM_DELIMITER);
		}
		out.append(S_CONSTRUCTOR_TOKEN); //It's a constructor
		return out.toString();
	}
	/**
	 * computeMethodID - generate the unique ID to be used to identify a method.
	 * Similar to a Signature, but hopefully more readable.
	 * If there are no parms, it will end with a "(" so that it can be distictive from a field.
	 * The name format will be:
	 * 	simpleClassName.methodName(com.fronk.ParmType1_parmType2
	 * Note: This implementation is tightly coupled with ReflectionAdapter.getTypeNamesFromMethodID().
	 */
	public static String computeMethodID(java.lang.reflect.Method jdkMethod) {
		StringBuffer out = new StringBuffer();
		String className = getSimpleName(jdkMethod.getDeclaringClass().getName());
		out.append(className);
		out.append(C_CLASS_MEMBER_DELIMITER);
		out.append(computeMethodName(jdkMethod));
		out.append(C_METHOD_PARM_DELIMITER);
		Class[] parmTypes = jdkMethod.getParameterTypes();
		for (int i = 0; i < parmTypes.length; i++) {
			out.append(parmTypes[i].getName());
			if (i < parmTypes.length - 1)
				out.append(C_PARM_PARM_DELIMITER);
		}
		if (jdkMethod.getDeclaringClass().getName().equals(jdkMethod.getName()))
			out.append(S_CONSTRUCTOR_TOKEN); //It's a constructor
		return out.toString();
	}
	/**
	 * computeMethodName - generate the name to be used to identify a constructor.
	 * For the moment, names are simple, and UUID's are complex.
	 *
	 * It has to be done separately for JDK because Constructors and Methods are different classes.
	 * However, in the Java Model they are both just Methods with a flag indicating Constructor. 
	 */
	public static String computeMethodName(java.lang.reflect.Constructor jdkConstructor) {
		return getSimpleName(jdkConstructor.getName()); // CTOR names come back fully-qualified with package.
	}
	/**
	 * computeMethodName - generate the name to be used to identify a method.
	 * For the moment, names are simple, and UUID's are complex.
	 */
	public static String computeMethodName(java.lang.reflect.Method jdkMethod) {
		return jdkMethod.getName();
	}
	/**
	 * createJavaField - instantiate a Java Field based on the passed Field
	 * We are deferring field contents assuming that its adaptor will reflect its details.
	 */
	public Field createJavaField(java.lang.reflect.Field reflectedField, XMIResource resource) {
		Field newField = getJavaFactory().createField();
		newField.setName(reflectedField.getName());
		String className = getSimpleName(reflectedField.getDeclaringClass().getName());
		resource.setID(newField, className + C_CLASS_MEMBER_DELIMITER + reflectedField.getName());
		return newField;
	}
	/**
	 * createJavaMethod - instantiate a Java Method based on the passed Java Reflection Constructor
	 * We are deferring method contents assuming that its adaptor will reflect its details.
	 * We need to store enough info in the empty Method to find its Java source.
	 * The ID will eventually hold enough info to identify the source, so we use it.
	 */
	public Method createJavaMethod(java.lang.reflect.Constructor jdkConstructor, XMIResource resource) {
		Method newMethod = getJavaFactory().createMethod();
		// We use a simple name, but a complex ID 
		newMethod.setName(computeMethodName(jdkConstructor));
		resource.setID(newMethod, computeMethodID(jdkConstructor));
		return newMethod;
	}
	/**
	 * createJavaMethod - instantiate a Java Method based on the passed Java Reflection Method
	 * We are deferring method contents assuming that its adaptor will reflect its details.
	 * We need to store enough info in the empty Method to find its Java source.
	 * The ID will eventually hold enough info to identify the source, so we use it.
	 */
	public Method createJavaMethod(java.lang.reflect.Method jdkMethod, XMIResource resource) {
		Method newMethod = getJavaFactory().createMethod();
		// We use a simple name, but a complex ID 
		newMethod.setName(computeMethodName(jdkMethod));
		resource.setID(newMethod, computeMethodID(jdkMethod));
		return newMethod;
	}
	/**
	 * Insert the method's description here.
	 * Creation date: (11/07/00 3:43:55 PM)
	 * @return org.eclipse.jem.java.adapters.JavaJDKAdapterFactory
	 */
	public JavaJDKAdapterFactory getAdapterFactory() {
		return adapterFactory;
	}
	public ClassLoader getAlternateClassLoader() {
		return getAdapterFactory().getContextClassLoader();
	}
	/*****************************************************************************
	* Method to convert the textual form of a primitive type into its Class object
	*
	* @param type The primitive type's textual representation
	*/
	public static Class getPrimitiveType(String type) {
		Class c = null;

		if (type.equals(byte.class.getName())) {
			c = byte.class;
		} else if (type.equals(short.class.getName())) {
			c = short.class;
		} else if (type.equals(int.class.getName())) {
			c = int.class;
		} else if (type.equals(long.class.getName())) {
			c = long.class;
		} else if (type.equals(float.class.getName())) {
			c = float.class;
		} else if (type.equals(double.class.getName())) {
			c = double.class;
		} else if (type.equals(boolean.class.getName())) {
			c = boolean.class;
		} else if (type.equals(char.class.getName())) {
			c = char.class;
		} else if (type.equals(void.class.getName())) {
			c = void.class;
		}

		return c;
	}
	/**
	 * Returns the last segment of a '.'-separated qualified name.
	 * Returns the given name if it is not qualified.
	 * For example:
	 * <pre>
	 * getSimpleName("java.lang.Object") -> "Object"
	 * </pre>
	 */
	public static String getSimpleName(String name) {
		int lastDot = name.lastIndexOf('.');
		if (lastDot == -1)
			return name;
		return name.substring(lastDot + 1);
	}
	public Class getType(JavaHelpers modelClass) {
		Class result = null;
		if (modelClass.isArray()) {
			ArrayType arrayType = (ArrayType) modelClass;
			Class componentClass = getType(arrayType.getFinalComponentType());
			result = (Array.newInstance(componentClass, new int[arrayType.getArrayDimensions()])).getClass();
		} else if (modelClass.isPrimitive()) {
			result = getType(modelClass.getQualifiedName());
		} else {
			result = getType(((JavaClass) modelClass).getQualifiedNameForReflection());
		}
		return result;
	}
	public Class getType(String qualifiedName) {
		// Try for a primitive type ("int","char",etc.) first
		Class primType = getPrimitiveType(qualifiedName);
		if (primType == null) {
			// Changed for defect #212147 botp@ausaix19.austin.ibm.com@7630 system.
			//
			// Search only one of the following classloaders (the first one that exists) in this order. If not found
			// in a classloader, it will not roll-over to another class loader. This is to avoid problems where a
			// class may exist in more than one classloader. You get errors when this happens due to one class that
			// was found in only one classloader that refers to another class that was found in both classloaders.
			// They don't match when trying to reflect later.
			// 1) Alternate classloader (if exists)
			// 2) Thread context classloader (if exists)
			// 3) System classloader (if exists)
			// 4) Class.forName().
			if (getAlternateClassLoader() != null) {
				try {
					return getAlternateClassLoader().loadClass(qualifiedName);
				} catch (ClassNotFoundException cnf2) {
					return null;
				}
			}
			
			ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
			if (contextClassLoader != null) {
				try {
					return contextClassLoader.loadClass(qualifiedName);
				} catch (ClassNotFoundException e) {
					return null;
				}
			}
			
			ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
			if (systemClassLoader != null) {
				try {
					return systemClassLoader.loadClass(qualifiedName);
				} catch (ClassNotFoundException e) {
					return null;
				}
			}
			
			try {
				return Class.forName(qualifiedName);
			} catch (ClassNotFoundException e) {
				return null;
			}
		} else
			return primType;
	}
	/*
	 * Utility routine to paper over array type names
	 * Borrowed from a package-visibility helper on java.lang.reflect.Field
	 */
	static String getTypeName(Class type) {
		if (type.isArray()) {
			try {
				Class cl = type;
				int dimensions = 0;
				while (cl.isArray()) {
					dimensions++;
					cl = cl.getComponentType();
				}
				StringBuffer sb = new StringBuffer();
				sb.append(cl.getName());
				for (int i = 0; i < dimensions; i++) {
					sb.append("[]"); //$NON-NLS-1$
				}
				return sb.toString();
			} catch (Throwable e) { /*FALLTHRU*/
			}
		}
		return type.getName();
	}

	/*****************************************************************************
	* Method to convert the textual form of a primitive type into its Class object
	*
	* @param type The primitive type's textual representation
	*/
	public static Class primitiveForName(String type) {
		Class c = null;

		if (type.equals(byte.class.getName())) {
			c = byte.class;
		} else if (type.equals(short.class.getName())) {
			c = short.class;
		} else if (type.equals(int.class.getName())) {
			c = int.class;
		} else if (type.equals(long.class.getName())) {
			c = long.class;
		} else if (type.equals(float.class.getName())) {
			c = float.class;
		} else if (type.equals(double.class.getName())) {
			c = double.class;
		} else if (type.equals(boolean.class.getName())) {
			c = boolean.class;
		} else if (type.equals(char.class.getName())) {
			c = char.class;
		} else if (type.equals(void.class.getName())) {
			c = void.class;
		}

		return c;
	}

	/**
	 * Insert the method's description here.
	 * Creation date: (11/07/00 3:43:55 PM)
	 * @param newAdapterFactory org.eclipse.jem.java.adapters.JavaJDKAdapterFactory
	 */
	public void setAdapterFactory(JavaJDKAdapterFactory newAdapterFactory) {
		adapterFactory = newAdapterFactory;
	}
}
