/*******************************************************************************
 * 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.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.EList;
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.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.TypeNameRequestor;
import org.eclipse.jem.java.JavaClass;
import org.eclipse.jem.java.JavaHelpers;
import org.eclipse.jem.java.JavaParameter;
import org.eclipse.jem.java.Method;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.j2ee.common.Description;
import org.eclipse.jst.j2ee.common.internal.impl.J2EEEObjectImpl;
import org.eclipse.jst.j2ee.ejb.EjbPackage;
import org.eclipse.jst.j2ee.ejb.EnterpriseBean;
import org.eclipse.jst.j2ee.ejb.MethodElement;
import org.eclipse.jst.j2ee.ejb.MethodElementKind;
import org.eclipse.jst.j2ee.ejb.Session;
import org.eclipse.jst.j2ee.ejb.internal.util.MethodElementHelper;
import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;

import com.ibm.icu.util.StringTokenizer;


/**
 * The method element is used to denote a method of an enterprise bean's
 * home or remote interface, or a set of methods. The ejb-name element
 * must be the name of one of the enterprise beans in declared in the
 * deployment descriptor; the optional method-intf element allows to
 * distinguish between a method with the same signature that is defined in
 * both the home and remote interface; the method-name element specifies
 * the method name; and the optional method-params elements identify a
 * single method among multiple methods with an overloaded method name.
 * 
 * There are three possible styles of the method element syntax:
 * 
 * 1. 	<method>
 * 		<ejb-name>EJBNAME<//ejb-name>
 *    		<method-name>*<//method-name>
 * 	<//method>
 * 
 *    This style is used to refer to all the methods of the specified
 *    enterprise bean's home and remote interfaces.
 * 
 * 2. 	<method>
 * 		<ejb-name>EJBNAME<//ejb-name>
 *    		<method-name>METHOD<//method-name>
 * 	<//method>>
 * 
 *    This style is used to refer to the specified method of the
 *    specified enterprise bean. If there are multiple methods with
 *    the same overloaded name, the element of this style refers to
 *    all the methods with the overloaded name.
 * 
 * 
 * 
 * 
 * 
 * 3. 	<method>
 * 		<ejb-name>EJBNAME<//ejb-name>
 *    		<method-name>METHOD<//method-name>
 * 		<method-params>
 *    			<method-param>PARAM-1<//method-param>
 *    			<method-param>PARAM-2<//method-param>
 *           			...
 *    			<method-param>PARAM-n<//method-param>
 * 		<//method-params>
 * 	<method>	
 * 
 *    This style is used to refer to a single method within a set of
 *    methods with an overloaded name. PARAM-1 through PARAM-n are the
 *    fully-qualified Java types of the method's input parameters (if
 *    the method has no input arguments, the method-params element
 *    contains no method-param elements). Arrays are specified by the
 *    array element's type, followed by one or more pair of square
 *    brackets (e.g. int[][]).
 * 
 * 
 * Used in: method-permission and container-transaction
 * 
 * Examples:
 * 
 *     Style 1: The following method element refers to all the methods of
 * 		the EmployeeService bean's home and remote interfaces:
 * 
 * 		<method>
 * 			<ejb-name>EmployeeService<//ejb-name>
 * 			<method-name>*<//method-name>
 * 		<//method>
 * 
 * 	Style 2: The following method element refers to all the create
 * 		methods of the EmployeeService bean's home interface:
 * 
 *     		<method>
 * 			<ejb-name>EmployeeService<//ejb-name>
 * 			<method-name>create<//method-name>
 * 		<//method>
 * 
 * 	Style 3: The following method element refers to the
 * 		create(String firstName, String LastName) method of the
 * 	 	EmployeeService bean's home interface.
 * 
 *     		<method>
 * 			<ejb-name>EmployeeService<//ejb-name>
 * 			<method-name>create<//method-name>
 * 			<method-params>
 * 				<method-param>java.lang.String<//method-param>
 * 				<method-param>java.lang.String<//method-param>
 * 			<//method-params>
 * 		<//method>
 * 
 * 	
 * 	The following example illustrates a Style 3 element with
 * 	more complex parameter types. The method
 * 			foobar(char s, int i, int[] iar, mypackage.MyClass mycl,
 * 				mypackage.MyClass[][] myclaar)
 *         would be specified as:
 * 
 *     		<method>
 * 			<ejb-name>EmployeeService<//ejb-name>
 * 			<method-name>foobar<//method-name>
 * 			<method-params>
 * 				<method-param>char<//method-param>
 * 				<method-param>int<//method-param>
 * 				<method-param>int[]<//method-param>
 * 				<method-param>mypackage.MyClass<//method-param>
 * 				<method-param>mypackage.MyClass[][]<//method-param>
 * 			<//method-params>
 * 		<//method>
 * 
 * 	The optional method-intf element can be used when it becomes
 *    necessary to differentiate between a method defined in the home
 *    interface and a method with the same name and signature that is
 *    defined in the remote interface.
 * 
 * 	For example, the method element
 * 
 *    		<method>
 * 			<ejb-name>EmployeeService<//ejb-name>
 * 			<method-intf>Remote<//method-intf>
 * 			<method-name>create<//method-name>
 * 			<method-params>
 * 				<method-param>java.lang.String<//method-param>
 * 				<method-param>java.lang.String<//method-param>
 * 			<//method-params>
 * 		<//method>
 * 
 * 	can be used to differentiate the create(String, String) method
 *    defined in the remote interface from the create(String, String)
 *    method defined in the home interface, which would be defined as
 * 
 *    		<method>
 * 			<ejb-name>EmployeeService<//ejb-name>
 * 			<method-intf>Home<//method-intf>
 * 			<method-name>create<//method-name>
 * 			<method-params>
 * 				<method-param>java.lang.String<//method-param>
 * 				<method-param>java.lang.String<//method-param>
 * 			<//method-params>
 * 		<//method>
 * @generated
 */
public class MethodElementImpl extends J2EEEObjectImpl implements MethodElement {

	/**
	 * The default value of the '{@link #getName() <em>Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getName()
	 * @generated
	 * @ordered
	 */
	protected static final String NAME_EDEFAULT = null;

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	protected String name = NAME_EDEFAULT;
	/**
	 * The default value of the '{@link #getParms() <em>Parms</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getParms()
	 * @generated
	 * @ordered
	 */
	protected static final String PARMS_EDEFAULT = null;

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	protected String parms = PARMS_EDEFAULT;

	/**
	 * The default value of the '{@link #getType() <em>Type</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getType()
	 * @generated
	 * @ordered
	 */
	protected static final MethodElementKind TYPE_EDEFAULT = MethodElementKind.UNSPECIFIED_LITERAL;

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	protected MethodElementKind type = TYPE_EDEFAULT;
	/**
	 * This is true if the Type attribute has been set.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 * @ordered
	 */
	protected boolean typeESet = false;

	/**
	 * The default value of the '{@link #getDescription() <em>Description</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDescription()
	 * @generated
	 * @ordered
	 */
	protected static final String DESCRIPTION_EDEFAULT = null;

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	protected String description = DESCRIPTION_EDEFAULT;
	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	protected EnterpriseBean enterpriseBean = null;
	/**
	 * The cached value of the '{@link #getDescriptions() <em>Descriptions</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDescriptions()
	 * @generated
	 * @ordered
	 */
	protected EList descriptions = null;

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

public void addMethodParams(String param) { 
	String oldParms = getParms();
	if (oldParms == null) {
		setParms(param);
	} else {
		setParms(oldParms.concat(" ").concat(param)); //$NON-NLS-1$
	}
}
/**
 * Set the params for this method element to an empty array, as opposed
 * to null.
 */
public void applyZeroParams() {
	setParms(""); //$NON-NLS-1$
}
public boolean equalSignature(MethodElement anotherMethodElement) {
	boolean equal = getName().equals(anotherMethodElement.getName());
	if (equal) {
		equal = parmsEqual(anotherMethodElement);
		if (equal) {
			if (getType() == null)
				equal = anotherMethodElement.getType() == null;
			else
				equal = getType().equals(anotherMethodElement.getType());
		}
	}
	return equal;
}
public java.util.List getMethodParams() { 
	StringTokenizer tok = getMethodParamsTokenizer();
	java.util.List v = new ArrayList();
	java.util.List paramsList = new ArrayList();
	String current = null;
	if (tok != null) {
		while (current != null || tok.hasMoreTokens()) {
			String peek = null;
			if (current == null)
				current = tok.nextToken();
			if (tok.hasMoreTokens()) {
				peek = tok.nextToken();
				if (peek.startsWith("[")) { //$NON-NLS-1$
					current += peek;
					peek = null;
				}
			}
			v.add(current);
			if (peek != null)
				current = peek;
			else
				current = null;
		}

	}
	
	/*
		 * This is a hack to make sure that for old XMI generated files, that ven if there was ',' separated 
		 * params, it parses them back out right.  To support 4.0.X AAT generated XMI files with runAs roles 
		 * for methods.
		 */
	for (int i = 0; i < v.size(); i++)
	{
		tok = new StringTokenizer((String)v.get(i),","); //$NON-NLS-1$
		if (tok != null)
		{
			while (tok.hasMoreTokens())
			{
				paramsList.add(tok.nextToken());
			}
		}
	}
	return paramsList;
}
private StringTokenizer getMethodParamsTokenizer() {
	//This method is a hack for now; the cardinality is wrong for the params
	String aParms = getParms();
	if (aParms == null || aParms.length() == 0) {
		return null;
	}
	return new StringTokenizer(getParms());
}
/**
 * Answer a list of all the methods for which this method element applies.  The following rules are used:
 *
 * 1)  If the method element type is unspecified, the methods are obtained from the remote interface of the ejb;
 *		If it is specified, then the appropriate interface is used
 *
 * 2)  If the method name = "*", then all the PUBLIC methods for that interface are returned
 *
 * 3)  If the method name is specified, and no method params are specified, then all public methods for the interface
 *      having the same name are returned.
 *
 * 4)  If the method name and params are specified, then a zero or one element array is returned, containing the one and only method
 *      on the interface with the appropriate signature, if it exists
 */
public Method[] getMethods() {
	EnterpriseBean ejb = getEnterpriseBean();
	if(ejb == null)
	    return new Method[0];
	List result = null;
	switch (getType().getValue()) {
		case MethodElementKind.HOME :
			{
				result = getMethods(ejb.getHomeInterface());
				break;
			}
		case MethodElementKind.REMOTE :
			{
				result = getMethods(ejb.getRemoteInterface());
				break;
			}
		case MethodElementKind.LOCAL_HOME :
			{
				result = getMethods(ejb.getLocalHomeInterface());
				break;
			}
		case MethodElementKind.LOCAL :
			{
				result = getMethods(ejb.getLocalInterface());
				break;
			}
		case MethodElementKind.SERVICE_ENDPOINT :
		   {
		    	if(ejb.isSession()) {
		    	    result = getMethods(((Session)ejb).getServiceEndpoint());
		    	    break;
		    	}
		   }
		case MethodElementKind.UNSPECIFIED :
			{
				if (ejb.isMessageDriven())
					result = getMethods(ejb.getEjbClass());
				else {
					result = new ArrayList();
					result.addAll(getMethods(ejb.getHomeInterface()));
					result.addAll(getMethods(ejb.getRemoteInterface()));
					result.addAll(getMethods(ejb.getLocalHomeInterface()));
					result.addAll(getMethods(ejb.getLocalInterface()));
				}
				break;
			}
	}
	return (Method[]) result.toArray(new Method[result.size()]);
}
/**
 * Answer a list of all the methods for which this method element applies.  The following rules are used:
 *
 * 1)  If the method element type is unspecified, the methods are obtained from the remote interface of the ejb;
 *		If it is specified, then the appropriate interface is used
 *
 * 2)  If the method name = "*", then all the PUBLIC methods for that interface are returned
 *
 * 3)  If the method name is specified, and no method params are specified, then all public methods for the interface
 *      having the same name are returned.
 *
 * 4)  If the method name and params are specified, then a zero or one element array is returned, containing the one and only method
 *      on the interface with the appropriate signature, if it exists
 */
private List getMethods(JavaClass javaClass) {
	if (javaClass == null) return Collections.EMPTY_LIST;
	List result = null;
	String methodName = getName().trim();
	if (name.equals("*"))  //$NON-NLS-1$
		result = javaClass.getPublicMethodsExtended();
	else if (hasMethodParams()) {
		result = new ArrayList();
		Method method = javaClass.getPublicMethodExtended(name, getMethodParams());
		if (method != null)
			result.add(method);
	} else
 		result = javaClass.getPublicMethodsExtendedNamed(methodName);
 
 	return result;
}
/**
 * Return the MethodElement that is most specific.
 */
public MethodElement getMostSpecific(MethodElement aMethodElement, JavaClass aClass) {
	if (aMethodElement == null) return this;
	if (aMethodElement.isDefault() && !isDefault())
		return this;
	if (!aMethodElement.isDefault() && isDefault())
		return aMethodElement;
	if (aMethodElement.hasMethodParams() && !hasMethodParams())
		return aMethodElement;
	if (!aMethodElement.hasMethodParams() && hasMethodParams())
		return this;
	if (isUnspecified() && !aMethodElement.isUnspecified())
		return aMethodElement;
	return this;
}
public static MethodElement getMostSpecificMethodElement(List methodElements, Method aMethod) {
	MethodElement specificME = null;
	if (aMethod != null) {
		Iterator it = methodElements.iterator();
		MethodElement me;
		while (it.hasNext()) {
			me = (MethodElement) it.next();
			if (me.represents(aMethod)) {
				if (me.uniquelyIdentifies(aMethod))
					return me;
				else if (specificME == null)
					specificME = me;
				else
					specificME = specificME.getMostSpecific(me, aMethod.getJavaClass());
			}
		}
	}
	return specificME;
}
protected String getParmsString() {
	String parmString = getParms();
	if (parmString == null)
		parmString = ""; //$NON-NLS-1$
	return parmString;
}
/**
 * Return a String array for the possible MethodElement type names.
 */
public static String[] getPossibleTypeNames() {
	EjbPackage pack = EjbFactoryImpl.getPackage();
	List literals = pack.getMethodElementKind().getELiterals();
	String[] names = new String[literals.size()];
	for (int i = 0; i < literals.size(); i++)
		names[i] = literals.get(i).toString();
	return names;
}
/**
 * Return the signature.
 * For example:  setTwoParamMethod(java.lang.String, java.lang.String)
 */
public String getSignature() {
	if (isDefault())
		return getName();
	StringBuffer buf = new StringBuffer();
	buf.append(getName());
	if (hasMethodParams()){
		buf.append(RIGHT_PAREN);
		StringTokenizer tok = getMethodParamsTokenizer();
		if (tok != null) {
			while (tok.hasMoreTokens()) {
				buf.append(tok.nextToken());
				if (tok.hasMoreTokens())
					buf.append(COMMA);		
			}			
		}
		buf.append(LEFT_PAREN);
	}
	return buf.toString();
}
// Returns null if the EEnum is UNSPECIFIED
// unless it is a MessageDriven bean.
public JavaClass getTypeJavaClass() {
	if (isHome())
		return getEnterpriseBean().getHomeInterface();
	else if (isRemote())
		return getEnterpriseBean().getRemoteInterface();
	else if (isLocalHome())
		return getEnterpriseBean().getLocalHomeInterface();
	else if (isLocal())
		return getEnterpriseBean().getLocalInterface();
	else if (isUnspecified() && getEnterpriseBean().isMessageDriven())
		return getEnterpriseBean().getEjbClass();
	else
		return null;
}
	/**
 * Answer whether method params apply to this method, e.g., it is specific to one
 * overloaded method, even if the method is a zero parameter method.  Answer false if no
 * parameters apply, that is, the method element applies to all overloaded methods with this name
 */
public boolean hasMethodParams() {
	return getParms() != null;
}
/**
 * Parse @aSignature setting the name and the params.
 * A signature example:  setTwoParamMethod(java.lang.String, java.lang.String)
 */
public void initializeFromSignature(String aSignature) {
	parseSignature(aSignature);
}
public boolean isDefault() {
    return JavaClass.DEFAULT_METHOD_NAME.equals(getName());
}
/**
 * Return true if this MethodElement and @anotherMethodElement
 * represent the same exact methods.
 */
public boolean isEquivalent(MethodElement anotherMethodElement) {
	boolean equal = equalSignature(anotherMethodElement);
	if (equal)
		equal = getEnterpriseBean() == anotherMethodElement.getEnterpriseBean();
	return equal;
}
public boolean isHome() {
	return getType().getValue() == MethodElementKind.HOME;
}
public boolean isRemote() {
	return getType().getValue() == MethodElementKind.REMOTE;
}
public boolean isUnspecified() {
	return getType().getValue() == MethodElementKind.UNSPECIFIED;
}
public boolean isLocalHome() {
	return getType().getValue() == MethodElementKind.LOCAL_HOME;
}
public boolean isLocal() {
	return getType().getValue() == MethodElementKind.LOCAL;
}
public boolean isService() {
	return getType().getValue() == MethodElementKind.SERVICE_ENDPOINT;
}
/**
 * Return true if this MethodElement represents one or more
 * methods.
 */
public boolean isValid() {
	return getMethods().length > 0;
}
/**
 * Return true only if all the parameters for @aMethod
 * matches the names in the list of parameters.
 */
public boolean matchesParams(Method aMethod) {
	if (aMethod == null) return false;
	List params = getMethodParams();
	JavaParameter[] methodParams = aMethod.listParametersWithoutReturn();
	if (params.size() != methodParams.length)
		return false;
	for (int i = 0; i < methodParams.length; i++){
		String parameterType = ((JavaHelpers)methodParams[i].getEType()).getQualifiedName();
		if (!params.get(i).equals(parameterType)) 
			return false;
	}
	return true;
}
/**
 * Return true if this MethodElement has the same basic signature as
 * @aMethod, ignoring the return type, thrown exceptions, and declaring class of 
 * this instance or @aMethod.  Return false, if params is null
 */
public boolean nameAndParamsEquals(Method aMethod) {
	if (aMethod != null) {
		if (getName().equals(aMethod.getName())) {
			if (hasMethodParams())
				return matchesParams(aMethod);
			return false;
		}
	}
	return false;
}
protected boolean parmsEqual(MethodElement me) {
	if (me == null) return false;
	List myParms, otherParms;
	myParms = getMethodParams();
	otherParms = me.getMethodParams();
	if (myParms.size() != otherParms.size()) return false;
	for (int i = 0; i < myParms.size(); i++){
		if (!myParms.get(i).equals(otherParms.get(i)))
			return false;
	}
	return true;
}
	/**
	 * Parse @aSignature setting the name and the params.
	 * A signature example:  setTwoParamMethod(java.lang.String, java.lang.String)
	 */
	protected void parseSignature(String aSignature) {
		int index = aSignature.indexOf(RIGHT_PAREN);

		int endIndex = aSignature.indexOf(LEFT_PAREN);
		if (endIndex < 0) {
			endIndex = aSignature.length() - 1;
		}

		if (index < 0) {
			setName(aSignature);
			setParms(null); // There are no parameters in the sig so set to null
		} else {
			String sigName = aSignature.substring(0, index);

			setName(sigName);
			String sigParms = aSignature.substring(index + 1, endIndex);

			if (sigParms.lastIndexOf(".") != -1) { //$NON-NLS-1$
				String testParent = sigParms.substring(0, sigParms.lastIndexOf(".")); //$NON-NLS-1$
				if (!Character.isLowerCase(testParent.substring(testParent.lastIndexOf(".") + 1, testParent.length()).charAt(0))) { //$NON-NLS-1$
					class MyTypeNameRequestor extends TypeNameRequestor {
						boolean isNested = false;

						public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path) {
							isNested = true;
						}

						public boolean isNested() {
							return isNested;
						}
					}
					IJavaProject javaProject = JavaCore.create(WorkbenchResourceHelper.getProject(getEnterpriseBean().eResource()));
					IJavaElement javaElements[] = new IJavaElement[] { javaProject };
					final IJavaSearchScope scope = SearchEngine.createJavaSearchScope(javaElements, true);
		
					String newString = sigParms.substring(sigParms.lastIndexOf(".") + 1, sigParms.length()); //$NON-NLS-1$

					while (testParent.length() > 0) {
						String temp = null;
						temp = testParent.substring(testParent.lastIndexOf(".") + 1, testParent.length()); //$NON-NLS-1$
								
						MyTypeNameRequestor requestor = new MyTypeNameRequestor();
						int matchMode = SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE;
						try {
							new SearchEngine().searchAllTypeNames(null, matchMode, temp.toCharArray(), matchMode, IJavaSearchConstants.TYPE, scope, requestor,
									IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, new NullProgressMonitor());
							if (requestor.isNested()) {
								newString = temp + "$" + newString; //$NON-NLS-1$
							} else {
								newString = temp + "." + newString; //$NON-NLS-1$
							}
							if (testParent.lastIndexOf(".") != -1) //$NON-NLS-1$
								testParent = testParent.substring(0, testParent.lastIndexOf(".")); //$NON-NLS-1$
							else
								testParent = ""; //$NON-NLS-1$

						} catch (JavaModelException e) {
							Logger.getLogger().logError(e);
						}
					}
					sigParms = newString;
				}

			}

			if (sigParms.length() > 0) {
				char commaChar = COMMA.charAt(0);
				char[] sigParmsChars = sigParms.toCharArray();
				StringBuffer buf = new StringBuffer();
				for (int i = 0; i < sigParmsChars.length; i++) {
					if (sigParmsChars[i] != commaChar) {
						buf.append(sigParmsChars[i]);
					} else {
						addMethodParams(buf.toString());
						buf = new StringBuffer();
					}
				}
				addMethodParams(buf.toString());
			} else
				applyZeroParams();
		}
	}
public void removeMethodParams(String param) { 
	String myParams = getParms();
	if (myParams == null || myParams.length() == 0) {
		return;
	}
	StringTokenizer tok = new StringTokenizer(myParams);
	StringBuffer newParms = new StringBuffer();
	while (tok.hasMoreElements()) {
		String token = tok.nextToken();
		if (!token.equals(param)) {
			newParms.append(token);
			newParms.append(" "); //$NON-NLS-1$
		}
	}
	setParms(newParms.toString().trim());
}
/**
 * represents method comment.
 */
public boolean represents(Method aMethod) {
	if (aMethod != null) {
		if (isUnspecified() || typeClassImplementsInterface(aMethod.getJavaClass())) {
			if (isDefault())
				return true;
			else 
				if (getName().equals(aMethod.getName())) {
					if (hasMethodParams())
						return matchesParams(aMethod);
					return true;
				}
		}
	}					
	return false;
}
/**
 * Sets the id to be [MethodTransactionID| MethodPermissionID]_EJBNAME_MethodName,
 * or [MethodTransactionID| MethodPermissionID]_EJBNAME_MethodName_Parms, if parms exist
 */
public void setIdToReadableString() { 
	String aParms = getParms() == null ? "" : "_"+getParms().replace(' ', '_'); //$NON-NLS-1$ //$NON-NLS-2$
	String prefix = ""; //$NON-NLS-1$
	switch (MethodElementHelper.getContainedType(this)) {
		case MethodElementHelper.METHOD_PERMISSION :	
			prefix = ((XMIResource)eContainer.eResource()).getID(eContainer);
			break;
		case MethodElementHelper.METHOD_TRANSACTION :
			prefix = ((XMIResource)eContainer.eResource()).getID(eContainer);
			break;
	}
	((XMIResource)eResource()).setID(this,prefix + "_" + getEnterpriseBean().getName() + "_" + getName() + aParms); //$NON-NLS-1$ //$NON-NLS-2$
}
protected boolean typeClassImplementsInterface(JavaClass anInterface) {
	if (getTypeJavaClass() == null || anInterface == null) return false;
	return getTypeJavaClass().implementsInterface(anInterface);
}
/**
 * Return true if this MethodElement uniquely identifies
 * @aMethod.  Return false, even if the MethodElement represents
 * @aMethod (i.e., @aMethod is contained in its list of methods).
 */
public boolean uniquelyIdentifies(Method aMethod) {
	if (aMethod != null) {
		if (getTypeJavaClass() != null && 
	        typeClassImplementsInterface(aMethod.getJavaClass()) && 
	        getName().equals(aMethod.getName())) {
			if (hasMethodParams())
				return matchesParams(aMethod);
			return aMethod.listParametersWithoutReturn().length==0;
		}
	}
	return false;
}
	/**
	 * @generated This field/method will be replaced during code generation 
	 * The method-name element contains a name of an enterprise bean method,
	 * or the asterisk (*) character. The asterisk is used when the element
	 * denotes all the methods of an enterprise bean's remote and home
	 * interfaces.

	 */
	public String getName() {
		return name;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public void setName(String newName) {
		String oldName = name;
		name = newName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EjbPackage.METHOD_ELEMENT__NAME, oldName, name));
	}

	/**
	 * @generated This field/method will be replaced during code generation 
	 */
	public String getParms() {
		return parms;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public void setParms(String newParms) {
		String oldParms = parms;
		parms = newParms;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EjbPackage.METHOD_ELEMENT__PARMS, oldParms, parms));
	}

	/**
	 * @generated This field/method will be replaced during code generation 
	 */
	public MethodElementKind getType() {
		return type;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setType(MethodElementKind newType) {
		MethodElementKind oldType = type;
		type = newType == null ? TYPE_EDEFAULT : newType;
		boolean oldTypeESet = typeESet;
		typeESet = true;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EjbPackage.METHOD_ELEMENT__TYPE, oldType, type, !oldTypeESet));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void unsetType() {
		MethodElementKind oldType = type;
		boolean oldTypeESet = typeESet;
		type = TYPE_EDEFAULT;
		typeESet = false;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.UNSET, EjbPackage.METHOD_ELEMENT__TYPE, oldType, TYPE_EDEFAULT, oldTypeESet));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isSetType() {
		return typeESet;
	}

	/**
	 * @generated This field/method will be replaced during code generation 
	 * The description element is used by the ejb-jar file producer to provide text describing the parent element.  The description element should include any information that the ejb-jar file producer wants to provide to the consumer of the ejb-jar file (i.e. to the Deployer). Typically, the tools used by the ejb-jar file consumer will display the description when processing the parent element.
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public void setDescription(String newDescription) {
		String oldDescription = description;
		description = newDescription;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EjbPackage.METHOD_ELEMENT__DESCRIPTION, oldDescription, description));
	}

	/**
	 * @generated This field/method will be replaced during code generation 
	 */
	public EnterpriseBean getEnterpriseBean() {
		if (enterpriseBean != null && enterpriseBean.eIsProxy()) {
			InternalEObject oldEnterpriseBean = (InternalEObject)enterpriseBean;
			enterpriseBean = (EnterpriseBean)eResolveProxy(oldEnterpriseBean);
			if (enterpriseBean != oldEnterpriseBean) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, EjbPackage.METHOD_ELEMENT__ENTERPRISE_BEAN, oldEnterpriseBean, enterpriseBean));
			}
		}
		return enterpriseBean;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EnterpriseBean basicGetEnterpriseBean() {
		return enterpriseBean;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public void setEnterpriseBean(EnterpriseBean newEnterpriseBean) {
		EnterpriseBean oldEnterpriseBean = enterpriseBean;
		enterpriseBean = newEnterpriseBean;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EjbPackage.METHOD_ELEMENT__ENTERPRISE_BEAN, oldEnterpriseBean, enterpriseBean));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList getDescriptions() {
		if (descriptions == null) {
			descriptions = new EObjectContainmentEList(Description.class, this, EjbPackage.METHOD_ELEMENT__DESCRIPTIONS);
		}
		return descriptions;
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case EjbPackage.METHOD_ELEMENT__NAME:
				return getName();
			case EjbPackage.METHOD_ELEMENT__PARMS:
				return getParms();
			case EjbPackage.METHOD_ELEMENT__TYPE:
				return getType();
			case EjbPackage.METHOD_ELEMENT__DESCRIPTION:
				return getDescription();
			case EjbPackage.METHOD_ELEMENT__ENTERPRISE_BEAN:
				if (resolve) return getEnterpriseBean();
				return basicGetEnterpriseBean();
			case EjbPackage.METHOD_ELEMENT__DESCRIPTIONS:
				return getDescriptions();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case EjbPackage.METHOD_ELEMENT__NAME:
				setName((String)newValue);
				return;
			case EjbPackage.METHOD_ELEMENT__PARMS:
				setParms((String)newValue);
				return;
			case EjbPackage.METHOD_ELEMENT__TYPE:
				setType((MethodElementKind)newValue);
				return;
			case EjbPackage.METHOD_ELEMENT__DESCRIPTION:
				setDescription((String)newValue);
				return;
			case EjbPackage.METHOD_ELEMENT__ENTERPRISE_BEAN:
				setEnterpriseBean((EnterpriseBean)newValue);
				return;
			case EjbPackage.METHOD_ELEMENT__DESCRIPTIONS:
				getDescriptions().clear();
				getDescriptions().addAll((Collection)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void eUnset(int featureID) {
		switch (featureID) {
			case EjbPackage.METHOD_ELEMENT__NAME:
				setName(NAME_EDEFAULT);
				return;
			case EjbPackage.METHOD_ELEMENT__PARMS:
				setParms(PARMS_EDEFAULT);
				return;
			case EjbPackage.METHOD_ELEMENT__TYPE:
				unsetType();
				return;
			case EjbPackage.METHOD_ELEMENT__DESCRIPTION:
				setDescription(DESCRIPTION_EDEFAULT);
				return;
			case EjbPackage.METHOD_ELEMENT__ENTERPRISE_BEAN:
				setEnterpriseBean((EnterpriseBean)null);
				return;
			case EjbPackage.METHOD_ELEMENT__DESCRIPTIONS:
				getDescriptions().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case EjbPackage.METHOD_ELEMENT__NAME:
				return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
			case EjbPackage.METHOD_ELEMENT__PARMS:
				return PARMS_EDEFAULT == null ? parms != null : !PARMS_EDEFAULT.equals(parms);
			case EjbPackage.METHOD_ELEMENT__TYPE:
				return isSetType();
			case EjbPackage.METHOD_ELEMENT__DESCRIPTION:
				return DESCRIPTION_EDEFAULT == null ? description != null : !DESCRIPTION_EDEFAULT.equals(description);
			case EjbPackage.METHOD_ELEMENT__ENTERPRISE_BEAN:
				return enterpriseBean != null;
			case EjbPackage.METHOD_ELEMENT__DESCRIPTIONS:
				return descriptions != null && !descriptions.isEmpty();
		}
		return super.eIsSet(featureID);
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (name: ");
		result.append(name);
		result.append(", parms: ");
		result.append(parms);
		result.append(", type: ");
		if (typeESet) result.append(type); else result.append("<unset>");
		result.append(", description: ");
		result.append(description);
		result.append(')');
		return result.toString();
	}

}






