/*******************************************************************************
 * Copyright (c) 2001, 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
 *******************************************************************************/
/*
 * Created on Apr 21, 2003
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package org.eclipse.jst.j2ee.ejb;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.common.util.Enumerator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jem.java.JavaClass;
import org.eclipse.jem.java.JavaRefFactory;
import org.eclipse.jem.java.Method;
import org.eclipse.jst.j2ee.ejb.internal.impl.EjbFactoryImpl;

/**
 * @author blancett
 * 
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class EjbMethodElementHelper {
	public static final int ALL_METHODS = 0;
	public static final int HOME_METHODS = 1;
	public static final int CLIENT_METHODS = 2;
	public static final int REMOTE_METHODS = 3;
	public static final int LOCAL_METHODS = 4;
	public static final int LOCAL_HOME_METHODS = 5;
	public static final int LOCAL_REMOTE_METHODS = 6;
	protected EjbMethodElementComparator defaultMEComparator;
	protected EjbMethodElementComparator defaultMethodElementComparator;
	private static EjbMethodElementHelper singleton;
	public static final String DEFAULT_METHOD_NAME = "*"; //$NON-NLS-1$
	protected static final String METHOD_ELEMENT_NAME = "MethodElement"; //$NON-NLS-1$
	public EjbMethodElementHelper() {
		super();
	}
	public static EjbMethodElementHelper singleton() {
		if (singleton == null)
			singleton = new EjbMethodElementHelper();
		return singleton;
	}
	public boolean isMethodElementsEqual(MethodElement me1, MethodElement me2) {
		return (me1.getSignature().equals(me2.getSignature()) 
				&& me1.getEnterpriseBean() == me2.getEnterpriseBean() 
				&& me1.getMethodParams().equals(me2.getMethodParams()) 
				&& me1.getType() == me2.getType());
	}
	public boolean isMethodElementinList(List meList, Object me) {
		if (! (me instanceof MethodElement))
			return false;
		for (int i = 0; i < meList.size(); i++) {
			if (meList.get(i) instanceof MethodElement) {
				MethodElement element = (MethodElement) meList.get(i);
				if (isMethodElementsEqual(element, (MethodElement)me))
					return true;
			}
		}
		return false;
	}
	protected EjbMethodElementComparator getDefaultMEComparator() {
		if (defaultMEComparator == null)
			defaultMEComparator = new EjbMethodElementComparator();
		return defaultMEComparator;
	}
	protected void excludeQueryMethods(List result, List someQueries) {
		if (someQueries.isEmpty())
			return;
		int size = someQueries.size();
		List methods = new ArrayList(size);
		Query query = null;
		for (int i = 0; i < size; i++) {
			query = (Query) someQueries.get(i);
			methods.add(query.getQueryMethod());
		}
		excludeMethodElements(result, methods);
	}
	public List getAvailableSelectQueryMethodsExcludingExisting(ContainerManagedEntity cmp) {
		if (cmp == null)
			return Collections.EMPTY_LIST;
		List result = cmp.getAvailableSelectQueryMethods();
		List existing = cmp.getQueries();
		excludeQueryMethods(result, existing);
		return result;
	}
	public List getAvailableFindQueryMethodsExcludingExisting(ContainerManagedEntity cmp) {
		if (cmp == null)
			return Collections.EMPTY_LIST;
		List result = cmp.getAvailableFindQueryMethods();
		List existing = cmp.getQueries();
		excludeQueryMethods(result, existing);
		return result;
	}
	public List getExistingOrAvailableTransactionMethodElements(EObject object, EnterpriseBean bean) {
		List result = new ArrayList();
		result.addAll(getAvailableMethodTransactionMethodElementsExcludingExisting(bean));
		unionMethodElements(result, getExistingMethodElements(object, bean));
		Collections.sort(result, getDefaultMethodElementComparator());
		return result;
	}
	protected EjbMethodElementComparator getDefaultMethodElementComparator() {
		if (defaultMethodElementComparator == null)
			defaultMethodElementComparator = new EjbMethodElementComparator();
		return defaultMethodElementComparator;
	}
	protected List getExistingMethodElements(EObject refObject, EnterpriseBean bean) {
		if (refObject != null) {
			EjbPackage pack = getEjbPackage();
			if (refObject.eClass() == pack.getMethodTransaction())
				return ((MethodTransaction) refObject).getMethodElements(bean);
			if (refObject.eClass() == pack.getMethodPermission())
				return ((MethodPermission) refObject).getMethodElements(bean);
		}
		return Collections.EMPTY_LIST;
	}
	protected void unionMethodElements(List sourceMethodElements, List additionalMethodElements) {
		MethodElement sourceME, additionalME;
		int sourceSize, addSize;
		sourceSize = sourceMethodElements.size();
		addSize = additionalMethodElements.size();
		List foundElements = new ArrayList(addSize);
		boolean found = false;
		for (int i = 0; i < addSize; i++) {
			found = false;
			additionalME = (MethodElement) additionalMethodElements.get(i);
			sourceME = null;
			for (int ii = 0; ii < sourceSize; ii++) {
				sourceME = (MethodElement) sourceMethodElements.get(ii);
				if (sourceME.isEquivalent(additionalME)) {
					found = true;
					break;
				}
			}
			if (found)
				foundElements.add(sourceME);
		}
		sourceMethodElements.removeAll(foundElements);
		sourceMethodElements.addAll(additionalMethodElements);
	}
	public List getAvailableMethodTransactionMethodElementsExcludingExisting(EnterpriseBean bean) {
		List result = new ArrayList();
		List filteredMethods = new ArrayList();
		if (bean.isEntity()) {
			if (bean.getRemoteInterface() != null) {
				filteredMethods = bean.getRemoteInterface().getMethodsExtendedWithFilters(Collections.EMPTY_LIST, getEntityMethodTransactionExcludedMethods((Entity) bean, REMOTE_METHODS));
				result.addAll(createMethodElements(getMethodElementSignatures(filteredMethods), MethodElementKind.REMOTE_LITERAL, bean));
			}
			if (bean.getHomeInterface() != null) {
				filteredMethods = bean.getHomeInterface().getMethodsExtendedWithFilters(Collections.EMPTY_LIST, getEntityMethodTransactionExcludedMethods((Entity) bean, HOME_METHODS));
				result.addAll(createMethodElements(getMethodElementSignatures(filteredMethods), MethodElementKind.HOME_LITERAL, bean));
			}
			if (bean.getLocalInterface() != null) {
				filteredMethods = bean.getLocalInterface().getMethodsExtendedWithFilters(Collections.EMPTY_LIST, getEntityMethodTransactionExcludedMethods((Entity) bean, LOCAL_METHODS));
				result.addAll(createMethodElements(getMethodElementSignatures(filteredMethods), MethodElementKind.LOCAL_LITERAL, bean));
			}
			if (bean.getLocalHomeInterface() != null)
				result.addAll(bean.getAvailableLocalHomeMethodElements());
			result.addAll(bean.getAvailableUnspecifiedMethodElements());
		} else if (bean.isSession()) {
			if (bean.getRemoteInterface() != null) {
				filteredMethods = bean.getRemoteInterface().getMethodsExtendedWithFilters(getSessionMethodTransactionExcludedClasses((Session) bean, REMOTE_METHODS), Collections.EMPTY_LIST);
				result.addAll(createMethodElements(getMethodElementSignatures(filteredMethods), MethodElementKind.REMOTE_LITERAL, bean));
			}
			if (bean.getLocalInterface() != null) {
				filteredMethods = bean.getLocalInterface().getMethodsExtendedWithFilters(getSessionMethodTransactionExcludedClasses((Session) bean, LOCAL_METHODS), Collections.EMPTY_LIST);
				result.addAll(createMethodElements(getMethodElementSignatures(filteredMethods), MethodElementKind.LOCAL_LITERAL, bean));
			}
			result.add(bean.getAvailableUnspecifiedMethodElements().get(0));
		} else if (bean.isMessageDriven()) {
			filteredMethods = Arrays.asList(new Object[]{getMethod(bean.getEjbClass(), getMDBMethod_Sig())});
			result.addAll(bean.createMethodElements(filteredMethods, bean.getEjbClass()));
		}
		return result;
	}
	public List getMethodElementSignatures(List methods) {
		List signatures, sameNames;
		sameNames = new ArrayList();
		signatures = new ArrayList(methods.size() + 1);
		signatures.add(DEFAULT_METHOD_NAME);
		Iterator it = methods.iterator();
		Method aMethod;
		String methodName;
		while (it.hasNext()) {
			aMethod = (Method) it.next();
			methodName = aMethod.getName();
			if (sameNames.contains(methodName)) {
				if (!signatures.contains(methodName))
					signatures.add(methodName);
			} else
				sameNames.add(methodName);
			signatures.add(aMethod.getMethodElementSignature());
		}
		Collections.sort(signatures);
		return signatures;
	}
	protected List createMethodElements(List signatures, Enumerator aType, EnterpriseBean bean) {
		return createMethodElements(METHOD_ELEMENT_NAME, signatures, aType, bean);
	}
	protected EjbPackage getEjbPackage() {
		return EjbFactoryImpl.getPackage();
	}
	protected EjbFactory getEjbFactory() {
		return ((EjbPackage) EPackage.Registry.INSTANCE.getEPackage(EjbPackage.eNS_URI)).getEjbFactory();
	}
	protected List createMethodElements(String meTypeName, List signatures, Enumerator aType, EnterpriseBean bean) {
		int size = signatures.size();
		List methodElements = new ArrayList(size);
		String signature;
		MethodElement me;
		for (int i = 0; i < size; i++) {
			signature = (String) signatures.get(i);
			me = (MethodElement) getEjbFactory().create((EClass) getEjbPackage().getEClassifier(meTypeName));
			me.initializeFromSignature(signature);
			me.setEnterpriseBean(bean);
			me.setType((MethodElementKind) aType);
			methodElements.add(me);
		}
		return methodElements;
	}
	protected List getEntityMethodTransactionExcludedMethods(Entity entity, int type) {
		List result = new ArrayList();
		switch (type) {
			case (REMOTE_METHODS) :
				{
					JavaClass aClass = getEJBObjectClass(entity);
					aClass.getClassImport();
					result.addAll(excludeMethods(aClass, Arrays.asList(new Object[]{getMethod(aClass, getRemoteRemoveMethod_Sig())})));
					break;
				}
			case (HOME_METHODS) :
				{
					JavaClass aClass = getEJBHomeClass(entity);
					aClass.getClassImport();
					result.addAll(Arrays.asList(new Object[]{getMethod(aClass, getEjbGetMetaDataMethod_Sig()), getMethod(aClass, getEjbGetHomeHandleMethod_Sig())}));
					break;
				}
			case (LOCAL_METHODS) :
				{
					JavaClass aClass = getEJBLocalObjectClass(entity);
					aClass.getClassImport();
					result.addAll(excludeMethods(aClass, Arrays.asList(new Object[]{getMethod(aClass, getLocalRemoveMethod_Sig())})));
					break;
				}
		}
		return result;
	}
	protected List getSessionMethodTransactionExcludedClasses(Session session, int type) {
		List result = new ArrayList();
		Object[] allInterfaces;
		String className;
		switch (type) {
			case (REMOTE_METHODS) :
				{
					className = getEJBObjectClassName();
					allInterfaces = session.getRemoteInterface().getImplementsInterfaces().toArray();
					result.addAll(getInterfaces(allInterfaces, className));
					break;
				}
			case (LOCAL_METHODS) :
				{
					className = getEJBLocalObjectClassName();
					allInterfaces = session.getLocalInterface().getImplementsInterfaces().toArray();
					result.addAll(getInterfaces(allInterfaces, className));
					break;
				}
		}
		return result;
	}
	protected List excludeMethods(JavaClass aClass, List methods) {
		List currentMethods = aClass.getMethods();
		List resultMethods = new ArrayList();
		for (int i = 0; i < currentMethods.size(); i++) {
			if (!methods.contains(currentMethods.get(i)))
				resultMethods.add(currentMethods.get(i));
		}
		return resultMethods;
	}
	protected Method getMethod(JavaClass aClass, String methodName) {
		List currentMethods = aClass.getMethods();
		for (int i = 0; i < currentMethods.size(); i++) {
			Method method = (Method) currentMethods.get(i);
			if (methodName.equals(method.getSignature()))
				return method;
		}
		return null;
	}
	protected Method getMethodUsingMethodSig(JavaClass aClass, String methodName) {
		List currentMethods = aClass.getMethods();
		for (int i = 0; i < currentMethods.size(); i++) {
			Method method = (Method) currentMethods.get(i);
			if (methodName.equals(method.getSignature()))
				return method;
		}
		return null;
	}
	public List getInterfaces(Object[] interfaces, String aEjbObjectClassName) {
		List extractedInterfaces = new ArrayList();
		for (int i = 0; i < interfaces.length; i++) {
			if (((JavaClass) interfaces[i]).getQualifiedName().equals(aEjbObjectClassName))
				extractedInterfaces.add(interfaces[i]);
		}
		return extractedInterfaces;
	}
	public List getAvailableMethodElementsExcludingExisting(EnterpriseBean ejb, List someMethodElementOwners, EReference methodElementReference, int usageFlag) {
		return getAvailableMethodElementsExcludingExisting(ejb, someMethodElementOwners, methodElementReference, getDefaultMEComparator(), usageFlag);
	}
	public List getAvailableMethodElementsExcludingExisting(EnterpriseBean ejb, List someMethodElementOwners, EReference methodElementReference) {
		return getAvailableMethodElementsExcludingExisting(ejb, someMethodElementOwners, methodElementReference, getDefaultMEComparator());
	}
	public List getAvailableMethodElementsExcludingExisting(EnterpriseBean ejb, List someMethodElementOwners, EReference methodElementReference, Comparator comparator) {
		return getAvailableMethodElementsExcludingExisting(ejb, someMethodElementOwners, methodElementReference, comparator, ALL_METHODS);
	}
	protected List getExistingMethodElements(List someMethodElementOwners, EReference methodElementReference) {
		if (someMethodElementOwners == null || someMethodElementOwners.isEmpty() || methodElementReference == null || !methodElementReference.isMany())
			return Collections.EMPTY_LIST;
		List result = new ArrayList();
		int size = someMethodElementOwners.size();
		EObject owner = null;
		for (int i = 0; i < size; i++) {
			owner = (EObject) someMethodElementOwners.get(i);
			result.addAll((List) owner.eGet(methodElementReference));
		}
		return result;
	}
	public List getAvailableMethodElementsExcludingExisting(EnterpriseBean ejb, List someMethodElementOwners, EReference methodElementReference, Comparator comparator, int usageFlag) {
		if (ejb == null)
			return Collections.EMPTY_LIST;
		List result = new ArrayList();
		boolean showHomes = usageFlag == ALL_METHODS || usageFlag == HOME_METHODS;
		boolean showClients = usageFlag == ALL_METHODS || usageFlag == CLIENT_METHODS;
		if (showHomes)
			result.addAll(ejb.getAvailableHomeMethodElements());
		if (showClients)
			result.addAll(ejb.getAvailableRemoteMethodElements());
		if (showHomes)
			result.addAll(ejb.getAvailableLocalHomeMethodElements());
		if (showClients)
			result.addAll(ejb.getAvailableLocalMethodElements());
		result.addAll(ejb.getAvailableUnspecifiedMethodElements());
		excludeMethodElements(result, getExistingMethodElements(someMethodElementOwners, methodElementReference));
		Collections.sort(result, comparator);
		return result;
	}
	protected void excludeMethodElements(List sourceMethodElements, List existingMethodElements) {
		MethodElement sourceME, existingME;
		int sourceSize, existingSize;
		sourceSize = sourceMethodElements.size();
		existingSize = existingMethodElements.size();
		List foundElements = new ArrayList(existingSize);
		boolean found = false;
		for (int i = 0; i < existingSize; i++) {
			found = false;
			existingME = (MethodElement) existingMethodElements.get(i);
			sourceME = null;
			for (int ii = 0; ii < sourceSize; ii++) {
				sourceME = (MethodElement) sourceMethodElements.get(ii);
				if (existingME != null && existingME.getName() != null && sourceME.getSignature().equals(existingME.getSignature()) && sourceME.getTypeJavaClass() == existingME.getTypeJavaClass()) {
					if (sourceME.getTypeJavaClass() != null) { //it returns
						// null if the
						// method is *
						// and it is not
						// a message
						// bean
						found = true;
						break;
					}
					else if (sourceME.getEnterpriseBean().getEjbClass() == existingME.getEnterpriseBean().getEjbClass()) {
						found = true;
						break;
					}
				}
			}
			if (found)
				foundElements.add(sourceME);
		}
		sourceMethodElements.removeAll(foundElements);
	}
	private String getEjbGetHomeHandleMethod_Sig() {
		return "Public abstract javax.ejb.HomeHandle javax.ejb.EJBHome.getHomeHandle() throws java.rmi.RemoteException"; //$NON-NLS-1$
	}
	private String getEjbGetMetaDataMethod_Sig() {
		return "Public abstract javax.ejb.EJBMetaData javax.ejb.EJBHome.getEJBMetaData() throws java.rmi.RemoteException"; //$NON-NLS-1$
	}
	private String getRemoteRemoveMethod_Sig() {
		return "Public abstract void javax.ejb.EJBObject.remove() throws java.rmi.RemoteException,javax.ejb.RemoveException"; //non-nls //$NON-NLS-1$
	}
	private String getLocalRemoveMethod_Sig() {
		return "Public abstract void javax.ejb.EJBLocalObject.remove() throws java.rmi.RemoteException,javax.ejb.RemoveException"; //non-nls //$NON-NLS-1$
	}
	private String getMDBMethod_Sig() {
		return "public void onMessage(javax.jms.Message msg)"; //$NON-NLS-1$
	}
	private String getEJBObjectClassName() {
		return "javax.ejb.EJBObject"; //$NON-NLS-1$
	}
	private String getEJBLocalObjectClassName() {
		return "javax.ejb.EJBLocalObject"; //$NON-NLS-1$
	}
	private JavaClass getEJBObjectClass(EnterpriseBean bean) {
		Resource res = bean.eResource();
		ResourceSet set = res != null ? res.getResourceSet() : null;
		return (JavaClass) JavaRefFactory.eINSTANCE.reflectType("javax.ejb", "EJBObject", set); //$NON-NLS-1$ //$NON-NLS-2$
	}
	private JavaClass getEJBLocalObjectClass(EnterpriseBean bean) {
		Resource res = bean.eResource();
		ResourceSet set = res != null ? res.getResourceSet() : null;
		return (JavaClass) JavaRefFactory.eINSTANCE.reflectType("javax.ejb", "EJBLocalObject", set); //$NON-NLS-1$ //$NON-NLS-2$
	}
	private JavaClass getEJBHomeClass(EnterpriseBean bean) {
		Resource res = bean.eResource();
		ResourceSet set = res != null ? res.getResourceSet() : null;
		return (JavaClass) JavaRefFactory.eINSTANCE.reflectType("javax.ejb", "EJBHome", set); //$NON-NLS-1$ //$NON-NLS-2$
	}
}
