/*******************************************************************************
 * Copyright (c) 2001, 2006 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.jst.j2ee.ejb.internal.impl;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jem.java.JavaClass;
import org.eclipse.jem.java.Method;
import org.eclipse.jst.j2ee.ejb.EjbPackage;
import org.eclipse.jst.j2ee.ejb.EnterpriseBean;
import org.eclipse.jst.j2ee.ejb.Query;
import org.eclipse.jst.j2ee.ejb.QueryMethod;

/**
 * @generated
 */
public class QueryMethodImpl extends MethodElementImpl implements QueryMethod {

	public QueryMethodImpl() {
		super();
	}
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected EClass eStaticClass() {
		return EjbPackage.Literals.QUERY_METHOD;
	}

/**
 * For Query methods, their enterprise bean must be derived.
 * It is the Entity which contains the Query.
 */
public EnterpriseBean getEnterpriseBean() {
	if (enterpriseBean == null) {
		if (getQuery() != null)
			enterpriseBean = getQuery().getEntity();
	}
	return enterpriseBean;
}
/**
 * Answer the method for which this method element applies in the HOME INTERFACE.
 */
protected Method getHomeMethod() {
	Method result = null;
	JavaClass javaClass = getEnterpriseBean().getHomeInterface();
	if (javaClass != null) {
		String methodName = getName().trim();
		if (hasMethodParams())
			result = javaClass.getPublicMethodExtended(methodName, getMethodParams());
		else {
			List methods = javaClass.getPublicMethodsExtendedNamed(methodName);
			if (!methods.isEmpty())
				result = (Method) methods.get(0);
		}
	}
	return result;
}
/**
 * Answer the method for which this method element applies in the LOCAL HOME INTERFACE.
 */
protected Method getLocalHomeMethod() {
	Method result = null;
	JavaClass javaClass = getEnterpriseBean().getLocalHomeInterface();
	if (javaClass != null) {
		String methodName = getName().trim();
		if (hasMethodParams())
			result = javaClass.getPublicMethodExtended(methodName, getMethodParams());
		else {
			List methods = javaClass.getPublicMethodsExtendedNamed(methodName);
			if (!methods.isEmpty())
				result = (Method) methods.get(0);
		}
	}
	return result;
}



protected void addMethodIfNotNull(List aList, Method aMethod) {
	if (aMethod != null)
		aList.add(aMethod);
}
/**
 * This method will return a zero-length Method[] if there is no matching method
 * on the home, local home, or bean class.  It will return exactly one method
 * for ejbSelect, and one or two methods for finders.  The two method case occurs
 * when the same method with the same signature exists on both the home and
 * local home.
 */
public Method[] getMethods() {
	List result = new ArrayList(2);
	if (getName().startsWith("ejbSelect")) { //$NON-NLS-1$
		addMethodIfNotNull(result, getSelectMethod());
	} else {
		addMethodIfNotNull(result, getHomeMethod());
		addMethodIfNotNull(result, getLocalHomeMethod());
	}
	return (Method[])result.toArray(new Method[result.size()]);
}
/**
 * Answer the method for which this method element applies in the HOME INTERFACE.
 */
protected Method getSelectMethod() {
	Method result = null;
	JavaClass javaClass = getEnterpriseBean().getEjbClass();
	String methodName = getName().trim();
	if (hasMethodParams())
		result = javaClass.getPublicMethodExtended(name, getMethodParams());
	else {
		List methods = javaClass.getPublicMethodsExtendedNamed(methodName);
		if (!methods.isEmpty())
			result = (Method) methods.iterator().next();
	}
	return result;
}
	/**
	 * @generated This field/method will be replaced during code generation 
	 */
	public Query getQuery() {
		if (eContainerFeatureID != EjbPackage.QUERY_METHOD__QUERY) return null;
		return (Query)eContainer();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetQuery(Query newQuery, NotificationChain msgs) {
		msgs = eBasicSetContainer((InternalEObject)newQuery, EjbPackage.QUERY_METHOD__QUERY, msgs);
		return msgs;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public void setQuery(Query newQuery) {
		if (newQuery != eInternalContainer() || (eContainerFeatureID != EjbPackage.QUERY_METHOD__QUERY && newQuery != null)) {
			if (EcoreUtil.isAncestor(this, newQuery))
				throw new IllegalArgumentException("Recursive containment not allowed for " + toString());
			NotificationChain msgs = null;
			if (eInternalContainer() != null)
				msgs = eBasicRemoveFromContainer(msgs);
			if (newQuery != null)
				msgs = ((InternalEObject)newQuery).eInverseAdd(this, EjbPackage.QUERY__QUERY_METHOD, Query.class, msgs);
			msgs = basicSetQuery(newQuery, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EjbPackage.QUERY_METHOD__QUERY, newQuery, newQuery));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case EjbPackage.QUERY_METHOD__QUERY:
				if (eInternalContainer() != null)
					msgs = eBasicRemoveFromContainer(msgs);
				return basicSetQuery((Query)otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case EjbPackage.QUERY_METHOD__QUERY:
				return basicSetQuery(null, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) {
		switch (eContainerFeatureID) {
			case EjbPackage.QUERY_METHOD__QUERY:
				return eInternalContainer().eInverseRemove(this, EjbPackage.QUERY__QUERY_METHOD, Query.class, msgs);
		}
		return super.eBasicRemoveFromContainerFeature(msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case EjbPackage.QUERY_METHOD__QUERY:
				return getQuery();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case EjbPackage.QUERY_METHOD__QUERY:
				setQuery((Query)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void eUnset(int featureID) {
		switch (featureID) {
			case EjbPackage.QUERY_METHOD__QUERY:
				setQuery((Query)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case EjbPackage.QUERY_METHOD__QUERY:
				return getQuery() != null;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * You should use getClientTypeJavaClasses to ensure you pick up both home interfaces
	 * if they exist.
	 */
	public JavaClass getTypeJavaClass() {
		JavaClass[] result = getClientTypeJavaClasses();
		if (result != null && result.length > 0)
			return result[0];
		return null;
	}
	
	/**
	 * Return an array of JavaClasses of all the interfaces or bean class that this method is presented
	 * to a client.  If it is an ejbSelect... on the bean class will be returned and if
	 * it if a find both home interfaces will be returned if they exist.
	 * 
	 * May return null.
	 */
	public JavaClass[] getClientTypeJavaClasses() {
		if (getName() == null || getEnterpriseBean() == null) return null;
		EnterpriseBean ejb = getEnterpriseBean();
		if (getName().startsWith(SELECT_PREFIX))
			return new JavaClass[]{ejb.getEjbClass()};
		//Next case is tougher since you could have both a remove and local client
		//We want to return the home interface in this case.
		if (getName().startsWith(FIND_PREFIX)) {
			if (ejb.hasLocalClient() && !ejb.hasRemoteClient())
				return new JavaClass[]{getEnterpriseBean().getLocalHomeInterface()};
			if (ejb.hasRemoteClient() && !ejb.hasLocalClient())
				return new JavaClass[]{ejb.getHomeInterface()};
			if (ejb.hasRemoteClient() && ejb.hasLocalClient())
				return new JavaClass[]{ejb.getLocalHomeInterface(), ejb.getHomeInterface()};
		}
		return null;
	}
}







