/*******************************************************************************
 * 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
 *******************************************************************************/

package org.eclipse.jst.j2ee.model.internal.validation;

import java.util.Iterator;
import java.util.Set;

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.jst.j2ee.ejb.EnterpriseBean;
import org.eclipse.jst.j2ee.ejb.Entity;
import org.eclipse.wst.validation.internal.core.ValidationException;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;


/**
 * This class checks entity bean classes for errors or potential errors.
 * If any problems are found, an error, warning, or info marker is added to the task list.
 *
 * The following paragraph is taken from
 * Enterprise JavaBeans Specification ("Specification")
 * Version: 1.1
 * Status: Final Release
 * Release: 12/17/99
 * Copyright 1999 Sun Microsystems, Inc.
 * 901 San Antonio Road, Palo Alto, CA 94303, U.S.A.
 * All rights reserved.
 *
 *
 * All 9.2.X sections describe BMP requirements.
 * If a CMP requirement is different than these, then the differences are
 * documented in 9.4.X sections.
 *
 * 9.1.5.1 Entity bean instance's view: ... The entity Bean Provider is responsible
 *    for implementing the following methods in the entity bean class:...
 *
 * 9.2.2 Enterprise bean class
 *   - The following are the requirements for an entity bean class:
 *      - The class must implement, directly or indirectly, the javax.ejb.EntityBean interface.
 *      - The class must be defined as public and must not be abstract.
 *      - The class must not be defined as final.
 *      - The class must define a public constructor that takes no arguments.
 *      - The class must not define the finalize() method.
 *   - The class may, but is not required to, implement the entity bean's remote interface [9]. 
 *     If the class implements the entity bean's remote interface, the class must provide no-op 
 *     implementations of the methods defined in the javax.ejb.EJBObject interface. The container 
 *     will never invoke these methods on the bean instances at runtime.
 *   - A no-op implementation of these methods is required to avoid 
 *     defining the entity bean class as abstract.
 *   - The entity bean class must implement the business methods, and the 
 *     ejbCreate, ejbPostCreate, and ejbFind<METHOD> methods as described 
 *     later in this section.
 *   - The entity bean class may have superclasses and/or superinterfaces. 
 *     If the entity bean has superclasses, the business methods, the 
 *     ejbCreate and ejbPostCreate methods, the finder methods, and the
 *     methods of the EntityBean interface may be implemented in the 
 *     enterprise bean class or in any of its superclasses.
 *   - The entity bean class is allowed to implement other methods (for 
 *     example helper methods invoked internally by the business methods) 
 *     in addition to the methods required by the EJB specification.
 *
 * 9.2.3 ejbCreate methods
 *   - The entity bean class may define zero or more ejbCreate(...) methods whose signatures 
 *     must follow these rules:
 *       - The method name must be ejbCreate.
 *       - The method must be declared as public.
 *       - The method must not be declared as final or static.
 *       - The return type must be the entity bean's primary key type.
 *       - The method argument and return value types must be legal types for RMI-IIOP.
 *       - The throws clause may define arbitrary application specific exceptions, 
 *         including the javax.ejb.CreateException.
 *       - Compatibility Note: EJB 1.0 allowed the ejbCreate method to throw the 
 *         java.rmi.RemoteException to indicate a non-application exception. This 
 *         practice is deprecated in EJB 1.1 -- an EJB 1.1 compliant enterprise bean 
 *         should throw the javax.ejb.EJBException or another java.lang.RuntimeException
 *         to indicate non-application exceptions to the Container (see Section 12.2.2).
 *   - The entity object created by the ejbCreate method must have a unique primary key. 
 *     This means that the primary key must be different from the primary keys of all 
 *     the existing entity objects within the same home. The ejbCreate method should 
 *     throw the DuplicateKeyException on an attempt to create an entity object with 
 *     a duplicate primary key. However, it is legal to reuse the primary key of a
 *     previously removed entity object.
 *
 * 9.2.4 ejbPostCreate methods
 *   - For each ejbCreate(...) method, the entity bean class must define a matching 
 *     ejbPostCreate(...) method, using the following rules:
 *        - The method name must be ejbPostCreate.
 *        - The method must be declared as public.
 *        - The method must not be declared as final or static.
 *        - The return type must be void.
 *        - The method arguments must be the same as the arguments of the matching ejbCreate(...) method.
 *        - The throws clause may define arbitrary application specific exceptions, including the javax.ejb.CreateException.
 *        - Compatibility Note: EJB 1.0 allowed the ejbPostCreate method to throw the 
 *          java.rmi.RemoteExceptionto indicate a non-application exception. This practice is deprecated in EJB 1.1 -- an EJB 1.1
 *          compliant enterprise bean should throw the javax.ejb.EJBException or another java.lang.RuntimeException
 *          to indicate non-application exceptions to the Container (see Section 12.2.2).
 *
 * 9.2.5 ejbFind methods
 *   - The entity bean class may also define additional ejbFind<METHOD>(...) finder methods.
 *   - The signatures of the finder methods must follow the following rules:
 *   - A finder method name must start with the prefix "ejbFind" 
 *     (e.g. ejbFindByPrimaryKey, ejbFindLargeAccounts, ejbFindLateShipments).
 *   - A finder method must be declared as public.
 *   - The method must not be declared as final or static.
 *   - The method argument types must be legal types for RMI-IIOP.
 *   - The return type of a finder method must be the entity bean's primary key type, 
 *     or a collection of primary keys (see Section Subsection 9.1.8).
 *   - The throws clause may define arbitrary application specific exceptions, including 
 *     the javax.ejb.FinderException.
 *   - Every entity bean must define the ejbFindByPrimaryKey method. The result type for 
 *     this method must be the primary key type (i.e. the ejbFindByPrimaryKey method must 
 *     be a single-object finder).
 *   - Compatibility Note: EJB 1.0 allowed the finder methods to throw the 
 *     java.rmi.RemoteException to indicate a non-application exception. 
 *     This practice is deprecated in EJB 1.1 -- an EJB 1.1 compliant enterprise bean 
 *     should throw the javax.ejb.EJBException or another java.lang.RuntimeException
 *     to indicate non-application exceptions to the Container (see Section 12.2.2).
 *
 * 9.2.6 Business methods
 *   - The entity bean class may define zero or more business methods whose signatures 
 *     must follow these rules:
 *        - The method names can be arbitrary, but they must not start with 'ejb' to 
 *          avoid conflicts with the callback methods used by the EJB architecture.
 *        - The business method must be declared as public.
 *        - The method must not be declared as final or static.
 *        - The method argument and return value types must be legal types for RMI-IIOP.
 *        - The throws clause may define arbitrary application specific exceptions.
 *        - Compatibility Note: EJB 1.0 allowed the business methods to throw the 
 *          java.rmi.RemoteException to indicate a non-application exception. This 
 *          practice is deprecated in EJB 1.1 -- an EJB 1.1 compliant enterprise bean 
 *          should throw the javax.ejb.EJBException or another java.lang.RuntimeException
 *          to indicate non-application exceptions to the Container (see Section 12.2.2).
 *...
 * 9.2.9 Entity bean's primary key class
 *...
 *  - The primary key type must be a legal Value Type in RMI-IIOP.
 *...
 *
 * 9.4.1 Container-managed fields
 *...
 *   - The following requirements ensure that an entity bean can be deployed in any 
 *     compliant container.
 *        - The Bean Provider must ensure that the Java programming language types 
 *          assigned to the container-managed fields are restricted to the following: 
 *          Java programming language primitive types, Java programming language 
 *          serializable types, and references of enterprise beans' remote or home 
 *          interfaces.
 *        - The Container Provider may, but is not required to, use Java programming 
 *          language Serialization to store the container-managed fields in the database. 
 *          If the container chooses a different approach, the effect should be equivalent 
 *          to that of Java programming language Serialization. The Container must also be 
 *          capable of persisting references to enterprise beans' remote and home interfaces 
 *          (for example, by storing their handle or primary key).
 *...
 *
 * 9.4.2 ejbCreate, ejbPostCreate
 *...
 *   - The ejbCreate(...) methods must be defined to return the primary key class type. 
 *     The implementation of the ejbCreate(...) methods should be coded to return a null. 
 *     The returned value is ignored by the Container.
 *...
 *
 * 9.4.6 finder methods
 *   - The entity Bean Provider does not write the finder (ejbFind<METHOD>(...)) methods.
 *...
 * 9.4.7 primary key type
 *   - The container must be able to manipulate the primary key type. Therefore, 
 *     the primary key type for an entity bean with container-managed persistence 
 *     must follow the rules in this subsection, in addition to those specified in 
 *     Subsection 9.2.9.
 *
 *     There are two ways to specify a primary key class for an entity bean with container-managed persistence:
 *        - Primary key that maps to a single field in the entity bean class.
 *        - Primary key that maps to multiple fields in the entity bean class.
 *     The second method is necessary for implementing compound keys, and the first method is convenient for
 *     single-field keys. Without the first method, simple types such as String would have to be wrapped in a
 *     user-defined class.
 * 
 *     9.4.7.1 Primary key that maps to a single field in the entity bean class
 *     The Bean Provider uses the primkey-field element of the deployment descriptor to specify the
 *     container-managed field of the entity bean class that contains the primary key. The field's type must be
 *     the primary key type.
 *
 *     9.4.7.2 Primary key that maps to multiple fields in the entity bean class
 *     The primary key class must be public, and must have a public constructor with no parameters.
 *     All fields in the primary key class must be declared as public.
 *     The names of the fields in the primary key class must be a subset of the names of the container-managed
 *     fields. (This allows the container to extract the primary key fields from an instance's container-managed
 *     fields, and vice versa.)
 *
 *     9.4.7.3 Special case: Unknown primary key class
 *     In special situations, the entity Bean Provider may choose not to specify the primary key class for an
 *     entity bean with container-managed persistence. This case usually happens when the entity bean does
 *     not have a natural primary key, and the Bean Provider wants to allow the Deployer to select the primary
 *     key fields at deployment time. The entity bean's primary key type will usually be derived from the primary
 *     key type used by the underlying database system that stores the entity objects. The primary key
 *     used by the database system may not be known to the Bean Provider.
 *     When defining the primary key for the enterprise bean, the Deployer may sometimes need to subclass
 *     the entity bean class to add additional container-managed fields (this typically happens for entity beans
 *     that do not have a natural primary key, and the primary keys are system-generated by the underlying
 *     database system that stores the entity objects).
 *     In this special case, the type of the argument of the findByPrimaryKey method must be declared as
 *     java.lang.Object, and the return value of ejbCreate() must be declared as
 *     java.lang.Object. The Bean Provider must specify the primary key class in the deployment
 *     descriptor as of the type java.lang.Object.
 *     The primary key class is specified at deployment time in the situations when the Bean Provider develops
 *     an entity bean that is intended to be used with multiple back-ends that provide persistence, and when
 *     these multiple back-ends require different primary key structures.
 *     Use of entity beans with a deferred primary key type specification limits the client application programming
 *     model, because the clients written prior to deployment of the entity bean may not use, in general,
 *     the methods that rely on the knowledge of the primary key type.
 *     The implementation of the enterprise bean class methods must be done carefully. For example, the meth-ods
 *     should not depend on the type of the object returned from EntityContext.getPrimaryKey(), because
 *     the return type is determined by the Deployer after the EJB class has been written.
 *
 */
public abstract class AValidateEntityBean extends AValidateBean {
	protected final static String JAVAX_EJB_ENTITYBEAN = "javax.ejb.EntityBean"; //$NON-NLS-1$
	protected final static String SETENTITYCONTEXT = "setEntityContext"; //$NON-NLS-1$
	protected final static String UNSETENTITYCONTEXT = "unsetEntityContext"; //$NON-NLS-1$
	protected final static String EJBLOAD = "ejbLoad"; //$NON-NLS-1$
	protected final static String EJBSTORE = "ejbStore"; //$NON-NLS-1$
	protected final static String JAVAX_EJB_ENTITYCONTEXT = "javax.ejb.EntityContext"; //$NON-NLS-1$
	private boolean hasValidConstructor = false;
	private boolean hasAConstructor = false;
	private boolean hasSetEntityContext = false;
	private boolean hasUnsetEntityContext = false;
	private boolean hasEjbActivate = false;
	private boolean hasEjbPassivate = false;
	private boolean hasEjbRemove = false;
	private boolean hasEjbLoad = false;
	private boolean hasEjbStore = false;

	/**
	 * Given a bean's ejbFind method, return the matching find method from
	 * the home, if it exists. If not, return null.
	 */
	public Method getMatchingHomeFindMethodExtended(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method) throws InvalidInputException {
		vc.terminateIfCancelled();
		if (method == null) {
			return null;
		}

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

		return ValidationRuleUtility.getMethodExtended(bean.getHomeInterface(), method, IMethodAndFieldConstants.PREFIX_FIND);
	}
	/**
	 * getParentName method comment.
	 */
	protected String getParentName() {
		return JAVAX_EJB_ENTITYBEAN;
	}
	
	public boolean isFrameworkMethod(String name) {
		if (name == null) {
			return false;
		}

		if (super.isFrameworkMethod(name)) {
			return true;
		}
		// check for entity-specific methods
		else if (name.equals(IMethodAndFieldConstants.METHODNAME_EJBLOAD)) {
			return true;
		}
		else if (name.equals(IMethodAndFieldConstants.METHODNAME_EJBSTORE)) {
			return true;
		}
		else if (name.equals(IMethodAndFieldConstants.METHODNAME_SETENTITYCONTEXT)) {
			return true;
		}
		else if (name.equals(IMethodAndFieldConstants.METHODNAME_UNSETENTITYCONTEXT)) {
			return true;
		}

		return false;
	}
	
	/**
	 * Checks that the methods in the entity bean class follow the EJB 1.1. specification,
	 * and that there are no missing required methods.
	 *
	 * 9.2.2 Enterprise bean class
	 *...
	 *   - The following are the requirements for an entity bean class:
	 *...
	 *      - The class must define a public constructor that takes no arguments.
	 *      - The class must not define the finalize() method.
	 *...
	 *   - The entity bean class must implement the business methods, and the 
	 *     ejbCreate, ejbPostCreate, and ejbFind<METHOD> methods as described 
	 *     later in this section.
	 *   - The entity bean class may have superclasses and/or superinterfaces. 
	 *     If the entity bean has superclasses, the business methods, the 
	 *     ejbCreate and ejbPostCreate methods, the finder methods, and the
	 *     methods of the EntityBean interface may be implemented in the 
	 *     enterprise bean class or in any of its superclasses.
	 *   - The entity bean class is allowed to implement other methods (for 
	 *     example helper methods invoked internally by the business methods) 
	 *     in addition to the methods required by the EJB specification.
	 */
	public void primValidate(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method ejbMethod) throws InvalidInputException {
		// Can't invoke an abstract method
		//super.primValidate(ejbMethod);

		vc.terminateIfCancelled();

		String name = ejbMethod.getName();
		if (name.equals(IMethodAndFieldConstants.METHODNAME_EJBCREATE))
			validateEjbCreateMethod(vc, bean, clazz, ejbMethod);
		else if (name.equals(IMethodAndFieldConstants.METHODNAME_EJBPOSTCREATE))
			validateEjbPostCreateMethod(vc, bean, clazz, ejbMethod);
		else if (name.equals(IMethodAndFieldConstants.METHODNAME_FINALIZE))
			validateFinalize(vc, bean, clazz, ejbMethod);
		else if (name.startsWith(IMethodAndFieldConstants.PREFIX_EJBFIND))
			validateEjbFindMethod(vc, bean, clazz, ejbMethod);
		else if (isBusinessMethod(vc, bean, clazz, ejbMethod))
			validateBusinessMethod(vc, bean, clazz, ejbMethod);
		else
			validateHelperMethod(vc, bean, clazz, ejbMethod);

		vc.terminateIfCancelled();
	}
	
	/**
	 * Checks to see if @ejbMethod is one of the required methods.
	 */
	protected void primValidateExistence(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method ejbMethod) throws InvalidInputException {
		// Can't invoke an abstract method
		//super.validateExistence(ejbMethod);

		vc.terminateIfCancelled();

		String name = ejbMethod.getName();
		if (!hasSetEntityContext && name.equals(IMethodAndFieldConstants.METHODNAME_SETENTITYCONTEXT)) {
			JavaParameter[] params = ejbMethod.listParametersWithoutReturn();
			if (params.length == 1) {
				if (ValidationRuleUtility.isAssignableFrom(params[0].getJavaType(), ValidationRuleUtility.getType(ITypeConstants.CLASSNAME_JAVAX_EJB_ENTITYCONTEXT, bean))) {
					hasSetEntityContext = true;
				}
			}
		}
		else if (!hasUnsetEntityContext && name.equals(IMethodAndFieldConstants.METHODNAME_UNSETENTITYCONTEXT)) {
			if (ejbMethod.listParametersWithoutReturn().length == 0) {
				hasUnsetEntityContext = true;
			}
		}
		else if (!hasEjbActivate && name.equals(IMethodAndFieldConstants.METHODNAME_EJBACTIVATE)) {
			if (ejbMethod.listParametersWithoutReturn().length == 0) {
				hasEjbActivate = true;
			}
		}
		else if (!hasEjbPassivate && name.equals(IMethodAndFieldConstants.METHODNAME_EJBPASSIVATE)) {
			if (ejbMethod.listParametersWithoutReturn().length == 0) {
				hasEjbPassivate = true;
			}
		}
		else if (!hasEjbRemove && name.equals(IMethodAndFieldConstants.METHODNAME_EJBREMOVE)) {
			if (ejbMethod.listParametersWithoutReturn().length == 0) {
				hasEjbRemove = true;
			}
		}
		else if (!hasEjbLoad && name.equals(IMethodAndFieldConstants.METHODNAME_EJBLOAD)) {
			if (ejbMethod.listParametersWithoutReturn().length == 0) {
				hasEjbLoad = true;
			}
		}
		else if (!hasEjbStore && name.equals(IMethodAndFieldConstants.METHODNAME_EJBSTORE)) {
			if (ejbMethod.listParametersWithoutReturn().length == 0) {
				hasEjbStore = true;
			}
		}
		else if (!hasValidConstructor && ejbMethod.isConstructor()) {
			hasAConstructor = true;
			if (ValidationRuleUtility.isPublic(ejbMethod) && (ejbMethod.listParametersWithoutReturn().length == 0)) {
				hasValidConstructor = true;
			}
		}

		vc.terminateIfCancelled();

	}
	
	/**
	 * 9.2.6 Business methods
	 *   - The entity bean class may define zero or more business methods whose signatures 
	 *     must follow these rules:
	 *        - The method names can be arbitrary, but they must not start with 'ejb' to 
	 *          avoid conflicts with the callback methods used by the EJB architecture.
	 *        - The business method must be declared as public.
	 *        - The method must not be declared as final or static.
	 *        - The method argument and return value types must be legal types for RMI-IIOP.
	 *        - The throws clause may define arbitrary application specific exceptions.
	 *        - Compatibility Note: EJB 1.0 allowed the business methods to throw the 
	 *          java.rmi.RemoteException to indicate a non-application exception. This 
	 *          practice is deprecated in EJB 1.1 -- an EJB 1.1 compliant enterprise bean 
	 *          should throw the javax.ejb.EJBException or another java.lang.RuntimeException
	 *          to indicate non-application exceptions to the Container (see Section 12.2.2).
	 */
	public void validateBusinessMethod(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method) throws InvalidInputException {
		vc.terminateIfCancelled();

		super.validateBusinessMethod(vc, bean, clazz, method); // make sure that name does not start with 'ejb'

		// The method must be declared as public.
		if (!ValidationRuleUtility.isPublic(method)) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2408_bus, IEJBValidationContext.ERROR, bean, clazz, method, this);
			vc.addMessage(message);
		}

		// The method must not be declared as final or static.
		if (method.isStatic()) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2410_bus, IEJBValidationContext.ERROR, bean, clazz, method, this);
			vc.addMessage(message);
		}

		if (method.isFinal()) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2409_bus, IEJBValidationContext.ERROR, bean, clazz, method, this);
			vc.addMessage(message);
		}

		// The method argument and return value types must be legal types for RMI-IIOP.
		validateLegalRMIMethodWithoutExceptions(vc, bean, clazz, method);

		// The throws clause may define arbitrary application specific exceptions.
		// Compatibility Note: EJB 1.0 allowed the business methods to throw the 
		// java.rmi.RemoteException to indicate a non-application exception. This 
		// practice is deprecated in EJB 1.1 -- an EJB 1.1 compliant enterprise bean 
		// should throw the javax.ejb.EJBException or another java.lang.RuntimeException
		// to indicate non-application exceptions to the Container (see Section 12.2.2).
		validateBusinessMethodNoRemoteException(vc, bean, clazz, method);
	}
	
	protected void validateBusinessMethodNoRemoteException(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method) throws InvalidInputException {
		// EJB 2.0 added "throws InvalidInputException" above
		validateNoRemoteException(vc, bean, clazz, method, IMessagePrefixEjb11Constants.CHKJ2400_bus);
	}
	
	/**
	 * 9.2.2 Enterprise bean class
	 *   - The following are the requirements for an entity bean class:
	 *      - The class must implement, directly or indirectly, the javax.ejb.EntityBean interface.
	 *      - The class must be defined as public and must not be abstract.
	 *      - The class must not be defined as final.
	 *...
	 *   - The class may, but is not required to, implement the entity bean's remote interface [9]. 
	 *     If the class implements the entity bean's remote interface, the class must provide no-op 
	 *     implementations of the methods defined in the javax.ejb.EJBObject interface. The container 
	 *     will never invoke these methods on the bean instances at runtime.
	 *   - A no-op implementation of these methods is required to avoid 
	 *     defining the entity bean class as abstract.
	 *   - The entity bean class must implement the business methods, and the 
	 *     ejbCreate, ejbPostCreate, and ejbFind<METHOD> methods as described 
	 *     later in this section.
	 *   - The entity bean class may have superclasses and/or superinterfaces. 
	 *     If the entity bean has superclasses, the business methods, the 
	 *     ejbCreate and ejbPostCreate methods, the finder methods, and the
	 *     methods of the EntityBean interface may be implemented in the 
	 *     enterprise bean class or in any of its superclasses.
	 *   - The entity bean class is allowed to implement other methods (for 
	 *     example helper methods invoked internally by the business methods) 
	 *     in addition to the methods required by the EJB specification.
	 */
	public void validateClass(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz) throws InvalidInputException {
		// All of the above checks are performed by ValidateBean.
		super.validateClass(vc, bean, clazz);

		// Plus, check that at least one field exists on the bean.
		verifyFieldExists(vc, bean, clazz);
	}
	
	/**
	 * 9.2.3 ejbCreate methods
	 *   - The entity bean class may define zero or more ejbCreate(...) methods whose signatures 
	 *     must follow these rules:
	 *       - The method name must be ejbCreate.
	 *       - The method must be declared as public.
	 *       - The method must not be declared as final or static.
	 *       - The return type must be the entity bean's primary key type.
	 *       - The method argument and return value types must be legal types for RMI-IIOP.
	 *       - The throws clause may define arbitrary application specific exceptions, 
	 *         including the javax.ejb.CreateException.
	 *       - Compatibility Note: EJB 1.0 allowed the ejbCreate method to throw the 
	 *         java.rmi.RemoteException to indicate a non-application exception. This 
	 *         practice is deprecated in EJB 1.1 -- an EJB 1.1 compliant enterprise bean 
	 *         should throw the javax.ejb.EJBException or another java.lang.RuntimeException
	 *         to indicate non-application exceptions to the Container (see Section 12.2.2).
	 *   - The entity object created by the ejbCreate method must have a unique primary key. 
	 *     This means that the primary key must be different from the primary keys of all 
	 *     the existing entity objects within the same home. The ejbCreate method should 
	 *     throw the DuplicateKeyException on an attempt to create an entity object with 
	 *     a duplicate primary key. However, it is legal to reuse the primary key of a
	 *     previously removed entity object.
	 *
	 * 9.2.8 Entity bean's home interface
	 * The following are the requirements for the entity bean's home interface:
	 *   - Each create method must be named "create", and it must match one of the 
	 *     ejbCreate methods defined in the enterprise Bean class. The matching 
	 *     ejbCreate method must have the same number and types of its arguments. 
	 *     (Note that the return type is different.)
	 *   - All the exceptions defined in the throws clause of the matching ejbCreate 
	 *     and ejbPostCreate methods of the enterprise Bean class must be included in 
	 *     the throws clause of the matching create method of the home interface 
	 *     (i.e the set of exceptions defined for the create method must be a superset
	 *     of the union of exceptions defined for the ejbCreate and ejbPostCreate methods)
	 *...
	 *
	 * 9.4.2 ejbCreate, ejbPostCreate
	 *...
	 *   - The ejbCreate(...) methods must be defined to return the primary key class type. 
	 *     The implementation of the ejbCreate(...) methods should be coded to return a null. 
	 *     The returned value is ignored by the Container.
	 *...
	 */
	public void validateEjbCreateMethod(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method) throws InvalidInputException {
		vc.terminateIfCancelled();
		// The method which calls this method has already tested that the method name is ejbCreate.
		if (method == null)
			return;

		// The method must be declared as public.
		if (!ValidationRuleUtility.isPublic(method)) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2408_ejbCreate, IEJBValidationContext.ERROR, bean, clazz, method, this);
			vc.addMessage(message);
		}

		// The method must not be declared as final or static.
		if (method.isStatic()) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2410_ejbCreate, IEJBValidationContext.ERROR, bean, clazz, method, this);
			vc.addMessage(message);
		}

		if (method.isFinal()) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2409_ejbCreate, IEJBValidationContext.ERROR, bean, clazz, method, this);
			vc.addMessage(message);
		}

		// The method argument and return value types must be legal types for RMI-IIOP.
		// But if the bean uses java.lang.Object for a key, don't check if it's serializable.
		if(ValidationRuleUtility.usesUnknownPrimaryKey(bean)) {
			validateLegalRMIMethodArguments(vc, bean, clazz, method);
		}
		else {
			validateLegalRMIMethodWithoutExceptions(vc, bean, clazz, method);
		}	
		
		// The return type must be the entity bean's primary key type; unless this is
		// a CMP, and an unkonwn primary key class is used. Read section 9.4.7.3.
		validateEjbCreateMethod_keyDep(vc, bean, clazz, method);

		// The throws clause may define arbitrary application specific exceptions, 
		// including the javax.ejb.CreateException.
		// Compatibility Note: EJB 1.0 allowed the ejbPostCreate method to throw 
		// the java.rmi.RemoteException to indicate a non-application exception. 
		// This practice is deprecated in EJB 1.1 -- an EJB 1.1 compliant enterprise 
		// bean should throw the javax.ejb.EJBException or another 
		// java.lang.RuntimeException to indicate non-application exceptions to the 
		// Container (see Section 12.2.2).
		validateNoRemoteException(vc, bean, clazz, method, IMessagePrefixEjb11Constants.CHKJ2400_ejbCreate);

		// Verify that there is a matching ejbPostCreate method for this ejbCreate method.
		Method ejbPostCreateMethod = ValidationRuleUtility.getMethodExtended(clazz, IMethodAndFieldConstants.METHODNAME_EJBPOSTCREATE, method.listParametersWithoutReturn());
		if (ejbPostCreateMethod == null) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2002, IEJBValidationContext.WARNING, bean, clazz, method, this);
			vc.addMessage(message);
		}

		// Check for a matching create method on the home, and that the exceptions on
		// this method are a subset of the exceptions of the matching method on the home.
		validateEjbCreateMethod_homeDep(vc, bean, clazz, method);
	}
	
	/**
	 * 9.2.3 ejbCreate methods
	 *   - The entity bean class may define zero or more ejbCreate(...) methods whose signatures 
	 *     must follow these rules:
	 *       - The method name must be ejbCreate.
	 *       - The method must be declared as public.
	 *       - The method must not be declared as final or static.
	 *       - The return type must be the entity bean's primary key type.
	 *       - The method argument and return value types must be legal types for RMI-IIOP.
	 *       - The throws clause may define arbitrary application specific exceptions, 
	 *         including the javax.ejb.CreateException.
	 *       - Compatibility Note: EJB 1.0 allowed the ejbCreate method to throw the 
	 *         java.rmi.RemoteException to indicate a non-application exception. This 
	 *         practice is deprecated in EJB 1.1 -- an EJB 1.1 compliant enterprise bean 
	 *         should throw the javax.ejb.EJBException or another java.lang.RuntimeException
	 *         to indicate non-application exceptions to the Container (see Section 12.2.2).
	 *   - The entity object created by the ejbCreate method must have a unique primary key. 
	 *     This means that the primary key must be different from the primary keys of all 
	 *     the existing entity objects within the same home. The ejbCreate method should 
	 *     throw the DuplicateKeyException on an attempt to create an entity object with 
	 *     a duplicate primary key. However, it is legal to reuse the primary key of a
	 *     previously removed entity object.
	 *
	 * 9.2.8 Entity bean's home interface
	 * The following are the requirements for the entity bean's home interface:
	 *   - Each create method must be named "create", and it must match one of the 
	 *     ejbCreate methods defined in the enterprise Bean class. The matching 
	 *     ejbCreate method must have the same number and types of its arguments. 
	 *     (Note that the return type is different.)
	 *   - All the exceptions defined in the throws clause of the matching ejbCreate 
	 *     and ejbPostCreate methods of the enterprise Bean class must be included in 
	 *     the throws clause of the matching create method of the home interface 
	 *     (i.e the set of exceptions defined for the create method must be a superset
	 *     of the union of exceptions defined for the ejbCreate and ejbPostCreate methods)
	 *...
	 *
	 * 9.4.2 ejbCreate, ejbPostCreate
	 *...
	 *   - The ejbCreate(...) methods must be defined to return the primary key class type. 
	 *     The implementation of the ejbCreate(...) methods should be coded to return a null. 
	 *     The returned value is ignored by the Container.
	 *...
	 */
	public void validateEjbCreateMethod_keyDep(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method) throws InvalidInputException {
		vc.terminateIfCancelled();

		// The method which calls this method has already tested that the method name is ejbCreate.
		if (method == null)
			return;

		// Unknown primary key class (section 9.4.7.3) is also validated by this
		// check, because the primary key must be of type java.lang.Object, and
		// the ejbCreate must return java.lang.Object.
		JavaHelpers primaryKey = null;
		if(ValidationRuleUtility.usesUnknownPrimaryKey(bean)) {
			primaryKey = ValidationRuleUtility.getType(ITypeConstants.CLASSNAME_JAVA_LANG_OBJECT, bean);
		}
		else {
			primaryKey = ((Entity) bean).getPrimaryKey();
		}

		// The return type must be the entity bean's primary key type.
		vc.terminateIfCancelled();
		JavaHelpers parmType = method.getReturnType();

		if (!ValidationRuleUtility.isAssignableFrom(parmType, primaryKey)) {
			// if the parameter type is java.lang.Object, could be section 9.4.7.3
			String keyName = (primaryKey == null) ? IEJBValidatorConstants.NULL_PRIMARY_KEY : primaryKey.getJavaName();
			String[] msgParm = {keyName};
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2406, IEJBValidationContext.WARNING, bean, clazz, method, msgParm, this);
			vc.addMessage(message);
		}
	}
	
	/**
	 * 9.2.5 ejbFind methods
	 *   - The entity bean class may also define additional ejbFind<METHOD>(...) finder methods.
	 *   - The signatures of the finder methods must follow the following rules:
	 *   - A finder method name must start with the prefix "ejbFind" 
	 *     (e.g. ejbFindByPrimaryKey, ejbFindLargeAccounts, ejbFindLateShipments).
	 *   - A finder method must be declared as public.
	 *   - The method must not be declared as final or static.
	 *   - The method argument types must be legal types for RMI-IIOP.
	 *   - The return type of a finder method must be the entity bean's primary key type, 
	 *     or a collection of primary keys (see Section Subsection 9.1.8).
	 *   - The throws clause may define arbitrary application specific exceptions, including 
	 *     the javax.ejb.FinderException.
	 *   - Every entity bean must define the ejbFindByPrimaryKey method. The result type for 
	 *     this method must be the primary key type (i.e. the ejbFindByPrimaryKey method must 
	 *     be a single-object finder).
	 *   - Compatibility Note: EJB 1.0 allowed the finder methods to throw the 
	 *     java.rmi.RemoteException to indicate a non-application exception. 
	 *     This practice is deprecated in EJB 1.1 -- an EJB 1.1 compliant enterprise bean 
	 *     should throw the javax.ejb.EJBException or another java.lang.RuntimeException
	 *     to indicate non-application exceptions to the Container (see Section 12.2.2).
	 *
	 * 9.4.6 finder methods
	 *   - The entity Bean Provider does not write the finder (ejbFind<METHOD>(...)) methods.
	 *
	 * 9.4.7.3 (CMP) Special case: Unknown primary key class.
	 *   - In this special case, the type of the argument of the findByPrimaryKey method 
	 *     must be declared as java.lang.Object, and the return value of ejbCreate() must 
	 *     be declared as java.lang.Object. The Bean Provider must specify the primary key 
	 *     class in the deployment descriptor as of the type java.lang.Object.
	 *  (This does not need to be validated directly, since CMPs don't implement finder methods.
	 */
	public void validateEjbFindMethod(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method) throws InvalidInputException {
		// This method is a no-op so that the dependency classes don't have to implement it.
		// (This method will never be called in a dependency class.)
	}
	
	/**
	 * 9.2.5 ejbFind methods
	 *   - The entity bean class may also define additional ejbFind<METHOD>(...) finder methods.
	 *   - The signatures of the finder methods must follow the following rules:
	 *   - A finder method name must start with the prefix "ejbFind" 
	 *     (e.g. ejbFindByPrimaryKey, ejbFindLargeAccounts, ejbFindLateShipments).
	 *   - A finder method must be declared as public.
	 *   - The method must not be declared as final or static.
	 *   - The method argument types must be legal types for RMI-IIOP.
	 *   - The return type of a finder method must be the entity bean's primary key type, 
	 *     or a collection of primary keys (see Section Subsection 9.1.8).
	 *   - The throws clause may define arbitrary application specific exceptions, including 
	 *     the javax.ejb.FinderException.
	 *   - Every entity bean must define the ejbFindByPrimaryKey method. The result type for 
	 *     this method must be the primary key type (i.e. the ejbFindByPrimaryKey method must 
	 *     be a single-object finder).
	 *   - Compatibility Note: EJB 1.0 allowed the finder methods to throw the 
	 *     java.rmi.RemoteException to indicate a non-application exception. 
	 *     This practice is deprecated in EJB 1.1 -- an EJB 1.1 compliant enterprise bean 
	 *     should throw the javax.ejb.EJBException or another java.lang.RuntimeException
	 *     to indicate non-application exceptions to the Container (see Section 12.2.2).
	 *
	 * 9.4.6 finder methods
	 *   - The entity Bean Provider does not write the finder (ejbFind<METHOD>(...)) methods.
	 *
	 * 9.4.7.3 (CMP) Special case: Unknown primary key class.
	 *   - In this special case, the type of the argument of the findByPrimaryKey method 
	 *     must be declared as java.lang.Object, and the return value of ejbCreate() must 
	 *     be declared as java.lang.Object. The Bean Provider must specify the primary key 
	 *     class in the deployment descriptor as of the type java.lang.Object.
	 *  (This does not need to be validated directly, since CMPs don't implement finder methods.
	 */
	public void validateEjbFindMethod_homeDep(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method) throws InvalidInputException {
		// All the exceptions defined in the throws clause of the matching ejbCreate 
		// and ejbPostCreate methods of the enterprise Bean class must be included in 
		// the throws clause of the matching create method of the home interface 
		// (i.e the set of exceptions defined for the create method must be a superset
		// of the union of exceptions defined for the ejbCreate and ejbPostCreate methods)
		JavaClass home = bean.getHomeInterface();
		ValidationRuleUtility.isValidTypeHierarchy(bean, home);

		String methodName = IMethodAndFieldConstants.PREFIX_F + method.getName().substring(4); // e.g. if the home method is named findX, then the bean method will be named ejbFindX
		Method homeMethod = ValidationRuleUtility.getMethodExtended(home, method, methodName);
		if (homeMethod == null) {
			// Then this method shouldn't have been called; unless the method exists on the remote, this bean method isn't a business method.
			return;
		}
		Set exceptions = ValidationRuleUtility.getNotSubsetExceptions(bean, method, homeMethod);
		if (exceptions.size() > 0) {
			Iterator iterator = exceptions.iterator();
			while (iterator.hasNext()) {
				JavaClass exc = (JavaClass) iterator.next();
				String[] msgParm = { exc.getQualifiedName(), home.getQualifiedName()};
				IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2420, IEJBValidationContext.ERROR, bean, clazz, method, msgParm, this);
				vc.addMessage(message);
			}
		}
	}
	
	/**
	 * Checks that the ejbPostCreate method follows the EJB 1.1. specification.
	 *
	 * 9.2.4 ejbPostCreate methods
	 * - For each ejbCreate(...) method, the entity bean class must define a matching 
	 *   ejbPostCreate(...) method, using the following rules:
	 *    - The method name must be ejbPostCreate.
	 *    - The method must be declared as public.
	 *    - The method must not be declared as final or static.
	 *    - The return type must be void.
	 *    - The method arguments must be the same as the arguments of the matching 
	 *      ejbCreate(...) method.
	 *    - The throws clause may define arbitrary application specific exceptions, 
	 *      including the javax.ejb.CreateException.
	 *      Compatibility Note: EJB 1.0 allowed the ejbPostCreate method to throw 
	 *      the java.rmi.RemoteException to indicate a non-application exception. 
	 *      This practice is deprecated in EJB 1.1 -- an EJB 1.1 compliant enterprise 
	 *      bean should throw the javax.ejb.EJBException or another 
	 *      java.lang.RuntimeException to indicate non-application exceptions to the 
	 *      Container (see Section 12.2.2).
	 *...
	*/
	public void validateEjbPostCreateMethod(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method) throws InvalidInputException {
		vc.terminateIfCancelled();
		// The method which calls this method has already tested that the method name is ejbPostCreate.
		if (method == null)
			return;

		// The method must be declared as public.
		if (!ValidationRuleUtility.isPublic(method)) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2408_ejbPostCreate, IEJBValidationContext.ERROR, bean, clazz, method, this);
			vc.addMessage(message);
		}

		// The method must not be declared as final or static.
		if (method.isStatic()) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2410_ejbPostCreate, IEJBValidationContext.ERROR, bean, clazz, method, this);
			vc.addMessage(message);
		}

		if (method.isFinal()) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2409_ejbPostCreate, IEJBValidationContext.ERROR, bean, clazz, method, this);
			vc.addMessage(message);
		}

		vc.terminateIfCancelled();

		// The return type must be void.
		JavaHelpers parmType = method.getReturnType();
		String returnTypeName = ((parmType == null) ? "" : parmType.getQualifiedName()); //$NON-NLS-1$
		if (!returnTypeName.equals(ITypeConstants.VOID)) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2418, IEJBValidationContext.ERROR, bean, clazz, method, this);
			vc.addMessage(message);
		}

		// The throws clause may define arbitrary application specific exceptions, 
		// including the javax.ejb.CreateException.
		// Compatibility Note: EJB 1.0 allowed the ejbPostCreate method to throw 
		// the java.rmi.RemoteException to indicate a non-application exception. 
		// This practice is deprecated in EJB 1.1 -- an EJB 1.1 compliant enterprise 
		// bean should throw the javax.ejb.EJBException or another 
		// java.lang.RuntimeException to indicate non-application exceptions to the 
		// Container (see Section 12.2.2).
		validateNoRemoteException(vc, bean, clazz, method, IMessagePrefixEjb11Constants.CHKJ2400_ejbPostCreate);

		// Verify that the ejbPostCreate method has a matching ejbCreate method.
		Method ejbCreateMethod = ValidationRuleUtility.getMethodExtended(clazz, IMethodAndFieldConstants.METHODNAME_EJBCREATE, method.listParametersWithoutReturn());
		if (ejbCreateMethod == null) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2028, IEJBValidationContext.WARNING, bean, clazz, method, this);
			vc.addMessage(message);
		}

		validateEjbPostCreateMethod_homeDep(vc, bean, clazz, method);
	}
	
	/**
	 * Checks that the ejbPostCreate method follows the EJB 1.1. specification.
	 *
	 * 9.2.4 ejbPostCreate methods
	 * - For each ejbCreate(...) method, the entity bean class must define a matching 
	 *   ejbPostCreate(...) method, using the following rules:
	 *    - The method name must be ejbPostCreate.
	 *    - The method must be declared as public.
	 *    - The method must not be declared as final or static.
	 *    - The return type must be void.
	 *    - The method arguments must be the same as the arguments of the matching 
	 *      ejbCreate(...) method.
	 *    - The throws clause may define arbitrary application specific exceptions, 
	 *      including the javax.ejb.CreateException.
	 *      Compatibility Note: EJB 1.0 allowed the ejbPostCreate method to throw 
	 *      the java.rmi.RemoteException to indicate a non-application exception. 
	 *      This practice is deprecated in EJB 1.1 -- an EJB 1.1 compliant enterprise 
	 *      bean should throw the javax.ejb.EJBException or another 
	 *      java.lang.RuntimeException to indicate non-application exceptions to the 
	 *      Container (see Section 12.2.2).
	 *...
	*/
	public void validateEjbPostCreateMethod_homeDep(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method) throws InvalidInputException {
		vc.terminateIfCancelled();

		// The method which calls this method has already tested that the method name is ejbPostCreate.
		if (method == null) {
			return;
		}

		JavaClass homeIntf = bean.getHomeInterface();
		ValidationRuleUtility.isValidTypeHierarchy(bean, homeIntf);

		Method createMethod = getMatchingHomeCreateMethodExtended(vc, bean, clazz, method);
		if (createMethod == null) {
			// If the ejbCreate method is inherited from a component parent, it is likely
			// that the corresponding create method does not exist on the home.
			// Since our tools generate the component inheritance code, suppress this warning.

			// ejbCreate methods which are inherited via component inheritance, but do not
			// have a method on their immediate home, are filtered out via the isValid(Method) method.

			// The validateEjbCreateMethod checks for a matching create method, but just in
			// case the ejbCreate method is missing, check for it here too.
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2029, IEJBValidationContext.WARNING, bean, clazz, method, new String[] { homeIntf.getName()}, this);
			vc.addMessage(message);

			// Can't check the exceptions of a method which doesn't exist.
			return;
		}

		// Whether this is from a component inheritance or not, if the method exists on the
		// home, check that the method follows the spec.

		// Section 6.10.6 (session), 9.2.8 (entity), declare that all exceptions declared
		// on the ejbCreate, ejbPostCreate methods must be defined in the throws clause of
		// the matching create of the home interface.
		Set exceptions = ValidationRuleUtility.getNotSubsetExceptions(bean, method, createMethod);
		if (exceptions.size() > 0) {
			Iterator iterator = exceptions.iterator();
			while (iterator.hasNext()) {
				JavaClass exc = (JavaClass) iterator.next();
				String[] msgParm = { exc.getQualifiedName(), homeIntf.getQualifiedName()};
				IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2420, IEJBValidationContext.ERROR, bean, clazz, method, msgParm, this);
				vc.addMessage(message);
			}
		}
	}
	
	/**
	 * 9.2.2 Enterprise bean class
	 *...
	 *   - The following are the requirements for an entity bean class:
	 *...
	 *      - The class must not define the finalize() method.
	 *...
	 */
	protected void validateFinalize(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method) {
		if (method == null) {
			return;
		}

		// If it's "finalize()", the ejb bean shouldn't have the method.
		if (method.listParametersWithoutReturn().length == 0) {
			// This is a warning, not an error, because EJB 1.0 allowed the finalize() method to be called. EJB 1.1 (section 6.10.2) specifically prohibits it.
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2007, IEJBValidationContext.WARNING, bean, clazz, method, new String[] { clazz.getQualifiedName()}, this);
			vc.addMessage(message);
		}
	}
	
	/**
	 * 9.2.2 Enterprise bean class
	 *...
	 *   - The following are the requirements for an entity bean class:
	 *...
	 *      - The class must define a public constructor that takes no arguments.
	 *...
	 *
	 * EJB spec 1.1, p. 105 explains why this method does not check for at least one ejbCreate method.
	 *    [6] An entity enterprise Bean has no ejbCreate(...) and ejbPostCreate(...) 
	 *    methods if it does not define any create methods in its home interface. 
	 *    Such an entity enterprise Bean does not allow the clients to create new 
	 *    EJB objects. The enterprise Bean restricts the clients to accessing entities 
	 *    that were created through direct database inserts.
	 */
	protected void validateMethodExists(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz) throws InvalidInputException {
		final String[] modelObjectName = new String[] { clazz.getQualifiedName()};
		if (!hasValidConstructor && hasAConstructor) {
			// If a public constructor with no arguments does not exist explicitly,
			// Java will insert one as long as there are no constructors defined in the
			// class. If there is a constructor, Java does not insert a default constructor.
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2006, IEJBValidationContext.ERROR, bean, clazz, modelObjectName, this);
			vc.addMessage(message);
		}

		if (!hasSetEntityContext) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2033, IEJBValidationContext.WARNING, bean, clazz, this);
			vc.addMessage(message);
		}

		if (!hasUnsetEntityContext) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2034, IEJBValidationContext.WARNING, bean, clazz, this);
			vc.addMessage(message);
		}

		if (!hasEjbActivate) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2035, IEJBValidationContext.WARNING, bean, clazz, this);
			vc.addMessage(message);
		}

		if (!hasEjbPassivate) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2036, IEJBValidationContext.WARNING, bean, clazz, this);
			vc.addMessage(message);
		}

		if (!hasEjbRemove) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2037, IEJBValidationContext.WARNING, bean, clazz, this);
			vc.addMessage(message);
		}

		if (!hasEjbLoad) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2038, IEJBValidationContext.WARNING, bean, clazz, this);
			vc.addMessage(message);
		}

		if (!hasEjbStore) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2039, IEJBValidationContext.WARNING, bean, clazz, this);
			vc.addMessage(message);
		}
	}
	
	/**
	 * Check that at least one field exists on the bean class.
	 */
	public abstract void verifyFieldExists(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz) throws InvalidInputException;

	/*
	 * @see IValidationRule#preValidate(IEJBValidationContext, Object, Object)
	 */
	public void preValidate(IEJBValidationContext vc, Object targetParent, Object target) throws ValidationCancelledException, ValidationException {
		super.preValidate(vc, targetParent, target);
		hasValidConstructor = false;
		hasAConstructor = false;
		hasSetEntityContext = false;
		hasUnsetEntityContext = false;
		hasEjbActivate = false;
		hasEjbPassivate = false;
		hasEjbRemove = false;
		hasEjbLoad = false;
		hasEjbStore = false;
		
	}

}
