/*******************************************************************************
 * Copyright (c) 2001, 2004 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.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;

import org.eclipse.jem.java.Field;
import org.eclipse.jem.java.JavaClass;
import org.eclipse.jem.java.JavaHelpers;
import org.eclipse.jem.util.logger.LogEntry;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.j2ee.common.EjbRef;
import org.eclipse.jst.j2ee.common.EjbRefType;
import org.eclipse.jst.j2ee.common.EnvEntry;
import org.eclipse.jst.j2ee.common.EnvEntryType;
import org.eclipse.jst.j2ee.common.SecurityRole;
import org.eclipse.jst.j2ee.common.SecurityRoleRef;
import org.eclipse.jst.j2ee.ejb.CMPAttribute;
import org.eclipse.jst.j2ee.ejb.ContainerManagedEntity;
import org.eclipse.jst.j2ee.ejb.EJBJar;
import org.eclipse.jst.j2ee.ejb.EnterpriseBean;
import org.eclipse.jst.j2ee.ejb.Entity;
import org.eclipse.jst.j2ee.ejb.Session;
import org.eclipse.jst.j2ee.ejb.SessionType;
import org.eclipse.jst.j2ee.ejb.TransactionType;
import org.eclipse.jst.j2ee.internal.common.CommonPackage;
import org.eclipse.jst.j2ee.internal.ejb.EjbPackage;
import org.eclipse.wst.validation.internal.core.ValidationException;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.MessageLimitException;

/**
 * This class checks ejb-jar.xml for errors or potential errors.
 * If any problems are found, an error, warning, or info marker is added to the task list.
 *
 * 15.2.5.3 Declaration of security roles referenced from the bean's code
 * The Bean Provider is responsible for declaring in the security-role-ref elements of the deploy-ment
 * descriptor all the security role names used in the enterprise bean code. Declaring the security roles
 * references in the code allows the Application Assembler or Deployer to link the names of the security
 * roles used in the code to the security roles defined for an assembled application through the secu-rity-
 * role elements.
 * The Bean Provider must declare each security role referenced in the code using the secu-rity-
 * role-ref element as follows:
 *      Declare the name of the security role using the role-name element. The name must be the
 * security role name that is used as a parameter to the isCallerInRole(String role-Name)
 * method.
 *      Optional: Provide a description of the security role in the description element.
 * A security role reference, including the name defined by the role-name element, is scoped to the ses-sion
 * or entity bean element whose declaration contains the security-role-ref element.
 * The following example illustrates how an enterprise bean's references to security roles are declared in
 * the deployment descriptor.
 *    ...
 *    <enterprise-beans>
 *       ...
 *       <entity>
 *          <ejb-name>AardvarkPayroll</ejb-name>
 *          <ejb-class>com.aardvark.payroll.PayrollBean</ejb-class>
 *          ...
 *          <security-role-ref>
 *             <description>
 *                 This security role should be assigned to the
 *                 employees of the payroll department who are
 *                 allowed to update employees' salaries.
 *             </description>
 *             <role-name>payroll</role-name>
 *          </security-role-ref>
 *          ...
 *       </entity>
 *       ...
 *    </enterprise-beans>
 *    ...
 *
 * The deployment descriptor above indicates that the enterprise bean AardvarkPayroll makes the
 * security check using isCallerInRole("payroll") in its business method.
 *
 *
 * 15.3.3 Linking security role references to security roles
 * If the Application Assembler defines the security-role elements in the deployment descriptor, he
 * or she is also responsible for linking all the security role references declared in the secu-rity-
 * role-ref elements to the security roles defined in the security-role elements.
 * The Application Assembler links each security role reference to a security role using the role-link
 * element. The value of the role-link element must be the name of one of the security roles defined in
 * a security-role element.
 * A role-link element must be used even if the value of role-name is the same as the value of the
 * role-link reference.
 * The following deployment descriptor example shows how to link the security role reference named
 * payroll to the security role named payroll-department.
 *    ...
 *    <enterprise-beans>
 *       ...
 *       <entity>
 *          <ejb-name>AardvarkPayroll</ejb-name>
 *          <ejb-class>com.aardvark.payroll.PayrollBean</ejb-class>
 *          ...
 *          <security-role-ref>
 *             <description>
 *                This role should be assigned to the
 *                employees of the payroll department.
 *                Members of this role have access to
 *                anyone's payroll record.
 *
 *                The role has been linked to the
 *                payroll-department role.
 *             </description>
 *             <role-name>payroll</role-name>
 *             <role-link>payroll-department</role-link>
 *          </security-role-ref>
 *          ...
 *       </entity>
 *       ...
 *    </enterprise-beans>
 *    ...
 */
public class EnterpriseBean11VRule extends AValidationRule implements IMessagePrefixEjb11Constants {
	private static final Object ID = IValidationRuleList.EJB11_ENTERPRISEBEAN;
	private static final Object[] DEPENDS_ON = new Object[]{IValidationRuleList.EJB11_SESSION_BEANCLASS, IValidationRuleList.EJB11_SESSION_HOME, IValidationRuleList.EJB11_SESSION_REMOTE, IValidationRuleList.EJB11_BMP_BEANCLASS, IValidationRuleList.EJB11_BMP_HOME, IValidationRuleList.EJB11_BMP_KEYCLASS, IValidationRuleList.EJB11_BMP_REMOTE, IValidationRuleList.EJB11_CMP_BEANCLASS, IValidationRuleList.EJB11_CMP_HOME, IValidationRuleList.EJB11_CMP_KEYCLASS, IValidationRuleList.EJB11_CMP_REMOTE};
	private static final Map MESSAGE_IDS;

	private List _securityRoles = null;
	
	static {
		MESSAGE_IDS = new HashMap();
		
		MESSAGE_IDS.put(CHKJ2801, new String[]{CHKJ2801 + SPEC});
		MESSAGE_IDS.put(CHKJ2802_NAMED, new String[]{CHKJ2802_NAMED + SPEC});
		MESSAGE_IDS.put(CHKJ2802_UNNAMED, new String[]{CHKJ2802_UNNAMED + SPEC});
		MESSAGE_IDS.put(CHKJ2803_NAMED, new String[]{CHKJ2803_NAMED + SPEC});
		MESSAGE_IDS.put(CHKJ2803_UNNAMED, new String[]{CHKJ2803_UNNAMED + SPEC});
		MESSAGE_IDS.put(CHKJ2804_NAMED, new String[]{CHKJ2804_NAMED + SPEC});
		MESSAGE_IDS.put(CHKJ2804_UNNAMED, new String[]{CHKJ2804_UNNAMED + SPEC});
		MESSAGE_IDS.put(CHKJ2806, new String[]{CHKJ2806 + SPEC});
		MESSAGE_IDS.put(CHKJ2807, new String[]{CHKJ2807 + SPEC});
		MESSAGE_IDS.put(CHKJ2808, new String[]{CHKJ2808 + SPEC});
		MESSAGE_IDS.put(CHKJ2809, new String[]{CHKJ2809 + SPEC});

		MESSAGE_IDS.put(CHKJ2810_NAMED, new String[]{CHKJ2810_NAMED + SPEC});
		MESSAGE_IDS.put(CHKJ2810_UNNAMED, new String[]{CHKJ2810_UNNAMED + SPEC});
		MESSAGE_IDS.put(CHKJ2811_NAMED, new String[]{CHKJ2811_NAMED + SPEC});
		MESSAGE_IDS.put(CHKJ2811_UNNAMED, new String[]{CHKJ2811_UNNAMED + SPEC});
		MESSAGE_IDS.put(CHKJ2812, new String[]{CHKJ2812 + SPEC});

		MESSAGE_IDS.put(CHKJ2820, new String[]{CHKJ2820 + SPEC});
		MESSAGE_IDS.put(CHKJ2822, new String[]{CHKJ2822 + SPEC});
		MESSAGE_IDS.put(CHKJ2823, new String[]{CHKJ2823 + SPEC});
		MESSAGE_IDS.put(CHKJ2824, new String[]{CHKJ2824 + SPEC});
		MESSAGE_IDS.put(CHKJ2827, new String[]{CHKJ2827 + SPEC});
		MESSAGE_IDS.put(CHKJ2828, new String[]{CHKJ2828 + SPEC});

		MESSAGE_IDS.put(CHKJ2830, new String[]{CHKJ2830 + SPEC});
		MESSAGE_IDS.put(CHKJ2831, new String[]{CHKJ2831 + SPEC});
		MESSAGE_IDS.put(CHKJ2832, new String[]{CHKJ2832 + SPEC});
		MESSAGE_IDS.put(CHKJ2833, new String[]{CHKJ2833 + SPEC});
		MESSAGE_IDS.put(CHKJ2834, new String[]{CHKJ2834 + SPEC});
		MESSAGE_IDS.put(CHKJ2835, new String[]{CHKJ2835 + SPEC});
		MESSAGE_IDS.put(CHKJ2836, new String[]{CHKJ2836 + SPEC});
		MESSAGE_IDS.put(CHKJ2837, new String[]{CHKJ2837 + SPEC});
		MESSAGE_IDS.put(CHKJ2838, new String[]{CHKJ2838 + SPEC});
		MESSAGE_IDS.put(CHKJ2839, new String[]{CHKJ2839 + SPEC});
		
		MESSAGE_IDS.put(CHKJ2840, new String[]{CHKJ2840 + SPEC});
		MESSAGE_IDS.put(CHKJ2841, new String[]{CHKJ2841 + SPEC});

		MESSAGE_IDS.put(CHKJ2907, new String[]{CHKJ2907});
		MESSAGE_IDS.put(CHKJ2852, new String[]{CHKJ2852});
		
		MESSAGE_IDS.put(CHKJ2908, new String[]{CHKJ2908 + SPEC});
	}
	
	public final Map getMessageIds() {
		return MESSAGE_IDS;
	}
	
	public final Object[] getDependsOn() {
		return DEPENDS_ON;
	}
	
	public final Object getId() {
		return ID;
	}

	public Object getTarget(Object parent, Object clazz) {
		// If called as a dependent, parent will be this EnterpriseBean.
		return parent;
	}

	/**
	 * 6.5.3 The optional SessionSynchronization interface
	 *...
	 * Only a stateful Session bean with container-managed transaction demarcation may 
	 * implement the SessionSynchronization interface.
	 *...
	 * There is no need for a Session bean with bean-managed transaction to rely on the 
	 * synchronization call backs because the bean is in control of the commit the bean 
	 * knows when the transaction is about to be committed and it knows the outcome of the 
	 * transaction commit.
	 *...
	 */
	public boolean isValidSessionTypeElement(Session session) {
		// check syntax
		if (!session.isSetSessionType()) {
			return false;
		}

		if (session.getSessionType().getValue() == SessionType.STATEFUL) {
			return true;
		}

		if (session.getSessionType().getValue() == SessionType.STATELESS) {
			return true;
		}

		return false;
	}
	
	public boolean isValidTransactionTypeElement(Session sessionBean) {
		if (!sessionBean.isSetTransactionType()) {
			return false;
		}

		if (sessionBean.getTransactionType().getValue() == TransactionType.BEAN) {
			return true;
		}

		if (sessionBean.getTransactionType().getValue() == TransactionType.CONTAINER) {
			return true;
		}

		return false;
	}
	
	
	/**
	 * If the bean components (home interface, remote interface, bean class, and primary
	 * key) can all be found and reflected, return true. Else, add a validation error
	 * against the bean, and return false.
	 */
	public boolean validateBeanComponents(IEJBValidationContext vc, EJBJar ejbJar, EnterpriseBean bean) {
		boolean isValid = true;
		// Don't need to check if the bean is null, because this method will
		// not be called if it is.
		try {
			ValidationRuleUtility.isValidTypeHierarchy(bean, bean.getEjbClass());
		}
		catch (InvalidInputException exc) {
			if (bean.eIsSet(EjbPackage.eINSTANCE.getEnterpriseBean_EjbClass())) {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2802_NAMED, IEJBValidationContext.ERROR, bean, new String[] { bean.getEjbClass().getQualifiedName()}, this);
				vc.addMessage(message);
			}
			else {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2802_UNNAMED, IEJBValidationContext.ERROR, bean, this);
				vc.addMessage(message);
			}
			isValid = false;
		}

		try {
			ValidationRuleUtility.isValidTypeHierarchy(bean, bean.getHomeInterface());
		}
		catch (InvalidInputException exc) {
			if (bean.eIsSet(EjbPackage.eINSTANCE.getEnterpriseBean_HomeInterface())) {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2803_NAMED, IEJBValidationContext.ERROR, bean, new String[] { bean.getHomeInterfaceName()}, this);
				vc.addMessage(message);
			}
			else {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2803_UNNAMED, IEJBValidationContext.ERROR, bean, this);
				vc.addMessage(message);
			}
			isValid = false;
		}

		try {
			ValidationRuleUtility.isValidTypeHierarchy(bean, bean.getRemoteInterface());
		}
		catch (InvalidInputException exc) {
			if (bean.eIsSet(EjbPackage.eINSTANCE.getEnterpriseBean_RemoteInterface())) {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2804_NAMED, IEJBValidationContext.ERROR, bean, new String[] { bean.getRemoteInterfaceName()}, this);
				vc.addMessage(message);
			}
			else {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2804_UNNAMED, IEJBValidationContext.ERROR, bean, this);
				vc.addMessage(message);
			}
			isValid = false;
		}

		if (bean.isEntity()) {
			JavaClass primaryKey = ((Entity) bean).getPrimaryKey();
			try {
				ValidationRuleUtility.isValidTypeHierarchy(bean, primaryKey);
			}
			catch (InvalidInputException exc) {
				if (((Entity) bean).eIsSet(EjbPackage.eINSTANCE.getEntity_PrimaryKey())) {
					IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2810_NAMED, IEJBValidationContext.ERROR, bean, new String[] { ((Entity) bean).getPrimaryKeyName()}, this);
					vc.addMessage(message);
				}
				else {
					IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2810_UNNAMED, IEJBValidationContext.ERROR, bean, this);
					vc.addMessage(message);
				}
				isValid = false;
			}
		}
		return isValid;
	}
	
	public void validateCMPFieldElement(IEJBValidationContext vc, EJBJar ejbJar, EnterpriseBean bean) {
		if (bean instanceof ContainerManagedEntity) {
			// check syntax of tag is okay
			ContainerManagedEntity cmp = (ContainerManagedEntity) bean;
			List fields = cmp.getPersistentAttributes();
			if ((fields == null) || (fields.size() == 0)) {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2812, IEJBValidationContext.ERROR, bean, new String[] { bean.getEjbClassName()}, this);
				vc.addMessage(message);
				return;
			}

			boolean mapsToMultipleFields = !ValidationRuleUtility.isPrimitivePrimaryKey((ContainerManagedEntity) bean);
			Iterator iterator = fields.iterator();
			Field field = null;
			List fieldNames = new ArrayList(fields.size());
			while (iterator.hasNext()) {
				CMPAttribute attrib = (CMPAttribute) iterator.next();
				if (attrib == null) {
					Logger logger = vc.getMsgLogger();
					if (logger != null && logger.isLoggingLevel(Level.FINEST)) {
						LogEntry entry = vc.getLogEntry();
						entry.setSourceID("DDValidator.validateCMPFieldElement(EnterpriseBean)"); //$NON-NLS-1$
						entry.setText("CMPAttribute is null."); //$NON-NLS-1$
						logger.write(Level.FINEST, entry);
					}
					continue;
				}

				field = attrib.getField();
				if (field == null) {
					if (attrib.getName() != null) {
						IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2811_NAMED, IEJBValidationContext.ERROR, bean, new String[] { attrib.getName(), bean.getEjbClassName()}, this);
						vc.addMessage(message);
					}
					else {
						IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2811_UNNAMED, IEJBValidationContext.ERROR, bean, this);
						vc.addMessage(message);
					}
					continue;
				}
				else if (field.getName().equals(IMethodAndFieldConstants.FIELDNAME_SERIALVERSIONUID)) {
					// not a customer-entered field
					continue;
				}

				fieldNames.add(field.getName());

				try {
					// If the field is not a valid type
					ValidationRuleUtility.isValidType(ValidationRuleUtility.getType(field));
				}
				catch (InvalidInputException exc) {
					// field not identified
					IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2830, IEJBValidationContext.WARNING, bean, new String[] { field.getName()}, this);
					vc.addMessage(message);
				}
			}

			// 9.4.7.2
			if (mapsToMultipleFields && !ValidationRuleUtility.usesUnknownPrimaryKey(cmp)) {
				List primKeyFields = cmp.getPrimaryKey().getFieldsExtended();

				// (9.4.7.1 is validated in validatePrimKeyClassElement(bean)
				// check if the primary key class' fields exist in the container-managed fields
				iterator = primKeyFields.iterator();

				while (iterator.hasNext()) {
					Field keyField = (Field) iterator.next();
					if ((keyField.getName() != null) && (keyField.getName().equals(IMethodAndFieldConstants.FIELDNAME_SERIALVERSIONUID))) {
						// not a customer-entered field
						continue;
					}

					if (!fieldNames.contains(keyField.getName())) {
						IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2831, IEJBValidationContext.WARNING, bean, new String[] { keyField.getName()}, this);
						vc.addMessage(message);
					}
				}
			}

		}
	}
	
	/**
	 * This validateDeploymentDescriptor is called if the EJBJar could load, which means
	 * that the syntax of the JAR is (mostly) correct.
	 *
	 * EJB spec 1.1, section C.4, "Added the requirement for the Bean Provider to specify whether the
	 * enterprise bean uses a bean-managed or container-managed transaction."
	 */
	public void validate(IEJBValidationContext vc, Object targetParent, Object target) {
		EJBJar ejbJar = null;
		if(targetParent instanceof EnterpriseBean) {
			// running as a dependent
			ejbJar = (EJBJar)vc.loadModel(EJBValidatorModelEnum.EJB_MODEL);
		}
		else {
			ejbJar = (EJBJar)targetParent;
		}
		EnterpriseBean bean = (EnterpriseBean)target;
		
		validate(vc, ejbJar, bean);
	}
		
	public void validate(IEJBValidationContext vc, EJBJar ejbJar, EnterpriseBean bean) {
		if (bean == null) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2908, IEJBValidationContext.WARNING, bean, this);
			vc.addMessage(message);

			// If bean isn't valid, don't perform any of the other
			// validation checks on it.
			return;
		}

		try {
			// Check if the class exists, etc.
			boolean reflected = validateBeanComponents(vc, ejbJar, bean); // assume everything will reflect properly

			validateEnterpriseTypeElement(vc, ejbJar, bean);
			validateEJBNameElement(vc, ejbJar, bean);
			validateReentrantElement(vc, ejbJar, bean);
			validateSessionTypeElement(vc, ejbJar, bean);
			validateTransactionTypeElement(vc, ejbJar, bean);
			validatePersistenceTypeElement(vc, ejbJar, bean);
			validateEnvironmentEntries(vc, ejbJar, bean);

			if (!reflected) {
				// Something didn't reflect properly, so don't continue with the
				// rest of the checks. Some metadata will be nonsense.
				return;
			}

			if (bean.isContainerManagedEntity()) {
				ContainerManagedEntity cmp = (ContainerManagedEntity) bean;
				if (cmp.getPrimKeyField() != null && !cmp.getPrimKeyField().eIsProxy()) {
					// Don't validate the fields if it's neither a primitive primary key nor a compound primary key.
					// If the user was attempting a primitive primary key, but did a typo in ejb-jar.xml,
					// the user will see a lot of strange messages logged against the fields in the primitive primary key.
					validateCMPFieldElement(vc, ejbJar, bean);
				}
			}

			validatePrimKeyClassElement(vc, ejbJar, bean);
			validateEJBRef(vc, ejbJar, bean);
			validateSecurityRoleRefElement(vc, ejbJar, bean);
		}
		catch (MessageLimitException e) {
			throw e;
		}
		catch(ValidationCancelledException e) {
			throw e;
		}
		/* unreachable catch block
		catch(ValidationException exc) {
			// If there's a problem, proceed with the next bean.
			IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorConstants.CHKJ2852, IEJBValidationContext.WARNING, bean, new String[] { bean.getName() }, this);
			vc.addMessage(message);
			MsgLogger logger = vc.getMsgLogger();
			if (logger.isLoggingLevel(Level.FINER)) {
				logger.write(Level.FINER, exc);
			}
		}
		*/
		catch (Throwable exc) {
			// If there's a problem, proceed with the next bean.
			IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2852, IEJBValidationContext.WARNING, bean, new String[] { bean.getName() }, this);
			vc.addMessage(message);
			Logger logger = vc.getMsgLogger();
			if (logger != null && logger.isLoggingLevel(Level.SEVERE)) {
				logger.write(Level.SEVERE, exc);
			}
		}
	}
	
	public void validateEJBNameElement(IEJBValidationContext vc, EJBJar ejbJar, EnterpriseBean bean) {
		if (bean == null) {
			return;
		}

		String name = bean.getName();
		if ((name == null) || (name.equals(""))) { //$NON-NLS-1$
			IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2801, IEJBValidationContext.ERROR, bean, this);
			vc.addMessage(message);
		}
	}
	
	/**
	 * Validate section 14.3 of the EJB 1.1 specification.
	 *
	 * 14.3 EJB References
	 *   14.3.1 Bean Provider's responsibilities
	 *     14.3.1.1 EJB reference programming interfaces
	 *     14.3.1.2 Declaration of EJB references in deployment descriptor
	 *   14.3.2 Application Assembler's responsibilities
	 *   14.3.3 Deployer's responsibility
	 *   14.3.4 Container Provider's responsibility
	 */
	public void validateEJBRef(IEJBValidationContext vc, EJBJar ejbJar, EnterpriseBean bean) {
		if (bean == null) {
			return;
		}

		List ejbRefs = bean.getEjbRefs();
		if ((ejbRefs == null) || (ejbRefs.size() == 0)) {
			return;
		}

		Iterator iterator = ejbRefs.iterator();
		EjbRef ref = null;
		while (iterator.hasNext()) {
			ref = (EjbRef) iterator.next();
			if (ref == null) {
				Logger logger = vc.getMsgLogger();
				if (logger != null && logger.isLoggingLevel(Level.FINEST)) {
					LogEntry entry = vc.getLogEntry();
					entry.setSourceID("DDValidator.validateEJBRef(EnterpriseBean)"); //$NON-NLS-1$
					entry.setText("EjbRef is null in " + bean.getName()); //$NON-NLS-1$
					logger.write(Level.FINEST, entry);
				}
				continue;
			}
			// 14.3.1.1
			// Info mssg. "EJB spec recommends that all references to other enterprise beans be organized in the ejb subcontext of the bean's environment"
			EnterpriseBean namedEjb = null;
			if (ref.eIsSet(CommonPackage.eINSTANCE.getEjbRef_Link())) {
				// Load the EJB identified by the reference, if it exists.
				namedEjb = ejbJar.getEnterpiseBeanFromRef(ref);
				if (namedEjb != null) {
					// if it's null, let the EAR validator report it
					Integer ejbType = new Integer(ref.getType().getValue());
					boolean wrongType = false; // is the EJB, identified by ejb-link, of the type specified in the ejb-ref-type element?
					String type = (namedEjb instanceof Session) ? "Session" : "Entity"; //$NON-NLS-1$  //$NON-NLS-2$
					if (ejbType == null) {
						// Neither session nor entity?
						wrongType = true;
					}
					else if (ejbType.intValue() == EjbRefType.SESSION) {
						if (!(namedEjb instanceof Session)) {
							wrongType = true;
						}
					}
					else if (ejbType.intValue() == EjbRefType.ENTITY) {
						if (!(namedEjb instanceof Entity)) {
							wrongType = true;
						}
					}
					else {
						wrongType = true;
					}
					if (wrongType) {
						String[] parms = { namedEjb.getName(), type };
						IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2835, IEJBValidationContext.INFO, bean, parms, this);
						vc.addMessage(message);
					}
				}
			}

			// 14.3.1.2, 14.3.2, 14.3.4
			// Check that ejb-ref-name, ejb-ref-type, home, and remote have been defined, and exist
			validateHomeRef(vc, ejbJar, ref, namedEjb);
			validateRemoteRef(vc, ejbJar, ref, namedEjb);

			// 14.3.1.1
			// Info mssg. "EJB spec recommends that all references to other enterprise beans be organized in the ejb subcontext of the bean's environment"
			if (ref.getName() != null) {
				// If ejb name isn't set, that error would have been caught by one of the validateRef methods
				// Don't duplicate that effort here.
				String ejbName = ref.getName();
				if (!ejbName.startsWith("ejb/")) { //$NON-NLS-1$
					IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2838, IEJBValidationContext.INFO, bean, this);
					vc.addMessage(message);
				}
			}
		}
	}
	
	public void validateEnterpriseTypeElement(IEJBValidationContext vc, EJBJar ejbJar, EnterpriseBean bean) {
		// Attempt in vain to validate the enterprise type element here, because 
		// if it's not specified, there's a syntax error, and the 
		// validateDeploymentDescriptor(IReporter, IValidationContext) would have been 
		// called instead.
		/*
		if(! (bean.isSession() || bean.isEntity() )) {
			// no tag specified
			String beanName = (bean.getName() == null) ? "" : bean.getName();
			addValidationMessage(IEJBValidationContext.ERROR, IMessagePrefixEjb11Constants.EJB_DD_INVALID_ENTERPRISETYPE, new String[]{beanName}, bean);
		}
		*/
	}
	
	/**
	 * Validate section 14.3 of the EJB 1.1 specification.
	 *
	 * 14.2.1.2 Declaration of environment entries
	 */
	public void validateEnvironmentEntries(IEJBValidationContext vc, EJBJar ejbJar, EnterpriseBean bean) {
		if (bean == null) {
			return;
		}

		List envEntries = bean.getEnvironmentProperties();
		if ((envEntries == null) || (envEntries.size() == 0)) {
			return;
		}

		EnvEntry envEntry = null;
		Iterator iterator = envEntries.iterator();
		DuplicatesTable envNames = new DuplicatesTable();
		while (iterator.hasNext()) {
			envEntry = (EnvEntry) iterator.next();
			if (envEntry == null) {
				Logger logger = vc.getMsgLogger();
				if (logger != null && logger.isLoggingLevel(Level.FINEST)) {
					LogEntry entry = vc.getLogEntry();
					entry.setSourceID("DDValidator.validateEnvironmentEntries(EnterpriseBean)"); //$NON-NLS-1$
					entry.setText("EjbEntry is null in " + bean.getName()); //$NON-NLS-1$
					logger.write(Level.FINEST, entry);
				}
				continue;
			}

			if (envEntry.getName() != null) {
				envNames.add(envEntry.getName());
			}
			else {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2839, IEJBValidationContext.WARNING, bean, this);
				vc.addMessage(message);
			}

			if (envEntry.isSetType()) {
				// 14.2.1.2; type must be one of these types: String, Integer, Boolean, Double, Byte, Short, Long, and Float.
				int type = envEntry.getType().getValue();
				if (!((type == EnvEntryType.BOOLEAN) || (type == EnvEntryType.BYTE) || (type == EnvEntryType.DOUBLE) || (type == EnvEntryType.FLOAT) || (type == EnvEntryType.INTEGER) || (type == EnvEntryType.LONG) || (type == EnvEntryType.SHORT) || (type == EnvEntryType.STRING))) {
					IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2840, IEJBValidationContext.WARNING, bean, this);
					vc.addMessage(message);
				}
			}
			else {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2840, IEJBValidationContext.WARNING, bean, this);
				vc.addMessage(message);
			}
		}

		if (envNames.containsDuplicates()) {
			Iterator dups = envNames.getDuplicates().iterator();
			while (dups.hasNext()) {
				String name = (String) dups.next();
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2841, IEJBValidationContext.WARNING, bean, new String[] { name }, this);
				vc.addMessage(message);
			}
		}
	}
	
	/**
	 * If the metadata from the EjbRef is not valid, add a validation message.
	 *
	 * @parm EjbRef The <ejb-ref> element this method validates.
	 * @parm EnterpriseBean If the <ejb-ref> uses an <ejb-link>, this is the enterprise bean identified by that link. If the link doesn't exist, or if the user has identified a bean which doesn't exist, this parameter will be null.
	 */
	protected void validateHomeRef(IEJBValidationContext vc, EJBJar ejbJar, EjbRef ref, EnterpriseBean namedEjb) {
		boolean validType = true;
		EnterpriseBean bean = (EnterpriseBean)ref.eContainer();
		if (ref.eIsSet(CommonPackage.eINSTANCE.getEjbRef_Home())) {
			try {
				String homeName = ref.getHome();
				JavaHelpers type = ValidationRuleUtility.getType(homeName, bean);
				// Check that the home specified in the <home> element of the <ejb-ref> element
				// exists.
				ValidationRuleUtility.isValidType(type);

				if (namedEjb != null) {
					// Check that the home specified in the <home> element
					// is assignable to the home used by the named EJB in the
					// <ejb-link> element.
					JavaClass intfType = namedEjb.getHomeInterface();
					ValidationRuleUtility.isValidType(intfType);

					// Make sure that the identified home/remote interface in the ejb-ref
					// is of the same type as the one used by the bean.
					if (!ValidationRuleUtility.isAssignableFrom(type.getWrapper(), intfType)) {
						String[] parms = { namedEjb.getName(), intfType.getName()};
						IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2836, IEJBValidationContext.INFO, bean, parms, this);
						vc.addMessage(message);
					}
				}
			}
			catch (InvalidInputException exc) {
				validType = false;
			}
		}
		else {
			validType = false;
		}

		if (!validType) {
			String[] parms = { ref.getHome()};
			IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2832, IEJBValidationContext.INFO, bean, parms, this);
			vc.addMessage(message);
		}
	}
	
	public void validatePersistenceTypeElement(IEJBValidationContext vc, EJBJar ejbJar, EnterpriseBean bean) {
		// Attempt in vain to validate the persistence type element here, because 
		// if it's not specified, there's a syntax error, and the 
		// validateDeploymentDescriptor(IReporter, IValidationContext) would have been 
		// called instead.
		if (bean.isEntity()) {
			// check syntax
			Entity entityBean = (Entity) bean;
			if (!(entityBean.isContainerManagedEntity() || entityBean.isBeanManagedEntity())) {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2809, IEJBValidationContext.ERROR, bean, this);
				vc.addMessage(message);
			}
		}
	}
	/**
	 * If the primary key class reflected properly, return true. Else, return false.
	 */
	public void validatePrimKeyClassElement(IEJBValidationContext vc, EJBJar ejbJar, EnterpriseBean bean) {
		if (bean.isEntity()) {
			// check syntax
			if (bean instanceof ContainerManagedEntity) {
				ContainerManagedEntity cmp = (ContainerManagedEntity) bean;
				JavaClass clas = cmp.getPrimaryKey();
				if (clas != null && !clas.eIsProxy() && !isValidPrimKeyField(cmp,clas)) {
					// 9.4.7.1
					// user has specified both a prim-key-class and a primkey-field
					// can't use the CMPAttribute's field's name, because the primitive primary key returned is null
					IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2828, IEJBValidationContext.ERROR, bean, this);
					vc.addMessage(message);
				}
			}
		}
	}
	
	/**
	 * If the primary key is specified in the xml, answer whether it is the same as the derived primaryKeyAttribute
	 */
	public static boolean isValidPrimKeyField(ContainerManagedEntity cmp, JavaClass clas) {
		return cmp.getPrimaryKeyName().equals(clas.getJavaName()); 
	}
	
	public void validateReentrantElement(IEJBValidationContext vc, EJBJar ejbJar, EnterpriseBean bean) {
		if (bean.isEntity()) {
			// check syntax
			Entity entity = (Entity) bean;
			if (!entity.isSetReentrant()) {
				// Can only test if the reentrant attribute is set, because the model defaults it
				// to some boolean value if it isn't set.
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2806, IEJBValidationContext.ERROR, bean, this);
				vc.addMessage(message);
			}
		}
	}
	
	/**
	 * If the metadata from the EjbRef is not valid, add a validation message.
	 *
	 * @parm EjbRef The ref whose home this method checks.
	 * @parm EnterpriseBean If the EjbRef uses an <ejb-link> element, this is the enterprise bean identified by that element. It may be null, if the user has made a mistake.
	 */
	protected void validateRemoteRef(IEJBValidationContext vc, EJBJar ejbJar, EjbRef ref, EnterpriseBean namedEjb) {
		boolean validType = true;
		EnterpriseBean bean = (EnterpriseBean)ref.eContainer();
		if (ref.eIsSet(CommonPackage.eINSTANCE.getEjbRef_Remote())) {
			try {
				String remoteName = ref.getRemote();
				JavaHelpers type = ValidationRuleUtility.getType(remoteName, bean);
				// Check that the home specified in the <home> element of the <ejb-ref> element
				// exists.
				ValidationRuleUtility.isValidType(type);

				if (namedEjb != null) {
					// Check that the home specified in the <home> element
					// is assignable to the home used by the named EJB in the
					// <ejb-link> element.
					JavaClass intfType = namedEjb.getRemoteInterface();
					ValidationRuleUtility.isValidType(intfType);

					// Make sure that the identified home/remote interface in the ejb-ref
					// is of the same type as the one used by the bean.
					if (!ValidationRuleUtility.isAssignableFrom(type.getWrapper(), intfType)) {
						String[] parms = { namedEjb.getName(), intfType.getName()};
						IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2837, IEJBValidationContext.INFO, bean, parms, this);
						vc.addMessage(message);
					}
				}
			}
			catch (InvalidInputException exc) {
				validType = false;
			}
		}
		else {
			validType = false;
		}

		if (!validType) {
			String[] parms = { ref.getRemote()};
			IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2833, IEJBValidationContext.INFO, bean, parms, this);
			vc.addMessage(message);
		}
	}
	
	/**
	 * 15.2.5.3 Declaration of security roles referenced from the bean's code
	 * The Bean Provider is responsible for declaring in the security-role-ref 
	 * elements of the deployment descriptor all the security role names used 
	 * in the enterprise bean code. Declaring the security roles references in
	 * the code allows the Application Assembler or Deployer to link the names 
	 * of the security roles used in the code to the security roles defined for 
	 * an assembled application through the security-role elements.
	 * The Bean Provider must declare each security role referenced in the code
	 * using the security-role-ref element as follows:
	 *      Declare the name of the security role using the role-name element. 
	 * The name must be the security role name that is used as a parameter to 
	 * the isCallerInRole(String role-Name) method.
	 *      Optional: Provide a description of the security role in the 
	 * description element. A security role reference, including the name defined 
	 * by the role-name element, is scoped to the session or entity bean element 
	 * whose declaration contains the security-role-ref element. The following 
	 * example illustrates how an enterprise bean's references to security roles 
	 * are declared in the deployment descriptor.
	 *    ...
	 *    <enterprise-beans>
	 *       ...
	 *       <entity>
	 *          <ejb-name>AardvarkPayroll</ejb-name>
	 *          <ejb-class>com.aardvark.payroll.PayrollBean</ejb-class>
	 *          ...
	 *          <security-role-ref>
	 *             <description>
	 *                 This security role should be assigned to the
	 *                 employees of the payroll department who are
	 *                 allowed to update employees' salaries.
	 *             </description>
	 *             <role-name>payroll</role-name>
	 *          </security-role-ref>
	 *          ...
	 *       </entity>
	 *       ...
	 *    </enterprise-beans>
	 *    ...
	 *
	 * The deployment descriptor above indicates that the enterprise bean 
	 * AardvarkPayroll makes the security check using isCallerInRole("payroll")
	 * in its business method.
	 *
	 *
	 * 15.3.3 Linking security role references to security roles
	 * If the Application Assembler defines the security-role elements in the 
	 * deployment descriptor, he or she is also responsible for linking all the 
	 * security role references declared in the security-role-ref elements to the 
	 * security roles defined in the security-role elements. The Application 
	 * Assembler links each security role reference to a security role using the 
	 * role-link element. The value of the role-link element must be the name of 
	 * one of the security roles defined in a security-role element.
	 * A role-link element must be used even if the value of role-name is the 
	 * same as the value of the role-link reference.
	 * The following deployment descriptor example shows how to link the security 
	 * role reference named payroll to the security role named payroll-department.
	 *    ...
	 *    <enterprise-beans>
	 *       ...
	 *       <entity>
	 *          <ejb-name>AardvarkPayroll</ejb-name>
	 *          <ejb-class>com.aardvark.payroll.PayrollBean</ejb-class>
	 *          ...
	 *          <security-role-ref>
	 *             <description>
	 *                This role should be assigned to the
	 *                employees of the payroll department.
	 *                Members of this role have access to
	 *                anyone's payroll record.
	 *
	 *                The role has been linked to the
	 *                payroll-department role.
	 *             </description>
	 *             <role-name>payroll</role-name>
	 *             <role-link>payroll-department</role-link>
	 *          </security-role-ref>
	 *          ...
	 *       </entity>
	 *       ...
	 *    </enterprise-beans>
	 *    ...
	 *
	 */
	public void validateSecurityRoleRefElement(IEJBValidationContext vc, EJBJar ejbJar, EnterpriseBean bean) {
		if (bean == null) {
			return;
		}

		/**
		 * Need to build up a list of duplicate role names, but the validation message
		 * needs to be registered against the duplicate SecurityRoleRef instance.
		 * (Without the instance, we cannot get line numbers.)
		 *
		 * This class wrappers the SecurityRolRef instance so that the wrapper's
		 * implemention of equals compares the names, but the validation message will
		 * still be able to get the ref from the duplicate name.
		 */
		class RoleRefWrapper {
			private SecurityRoleRef _ref = null;

			public RoleRefWrapper(SecurityRoleRef ref) {
				_ref = ref;
			}

			public boolean equals(Object o) {
				if (o instanceof RoleRefWrapper) {
					RoleRefWrapper other = (RoleRefWrapper) o;
					return _ref.getName().equals(other.getRoleRef().getName());
				}
				return false;
			}

			public SecurityRoleRef getRoleRef() {
				return _ref;
			}
		}

		boolean areSRolesDefined = ((_securityRoles != null) && (_securityRoles.size() > 0));

		List securityRoleRefs = bean.getSecurityRoleRefs();
		if ((securityRoleRefs != null) && (securityRoleRefs.size() != 0)) {
			// Check that each security role ref refers to a security role,
			// if security roles are defined in the assembly descriptor,
			// and that each referenced security role exists.
			DuplicatesTable roleRefNames = new DuplicatesTable();
			for (int i = 0; i < securityRoleRefs.size(); i++) {
				SecurityRoleRef ref = (SecurityRoleRef) securityRoleRefs.get(i);

				// Check that the role name is set (15.2.5.3)
				String roleName = ref.getName();
				if ((roleName == null) || (roleName.equals(""))) { //$NON-NLS-1$
					roleName = ""; //$NON-NLS-1$
					String beanName = (bean.getName() == null) ? "" : bean.getName(); //$NON-NLS-1$
					IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2822, IEJBValidationContext.WARNING, ref, new String[] { beanName }, this);
					vc.addMessage(message);
				}
				else {
					// Build up the list of names, to check for duplicates
					roleRefNames.add(new RoleRefWrapper(ref));
				}

				// Check that the role link is set (15.3.3)
				String roleLink = ref.getLink();
				boolean isLinkDefined = ((ref.eIsSet(CommonPackage.eINSTANCE.getSecurityRoleRef_Link())) && (roleLink != null) && (!roleLink.equals(""))); //$NON-NLS-1$

				if ((areSRolesDefined) && (!isLinkDefined)) {
					// must have role link defined (15.3.3)
					IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2823, IEJBValidationContext.WARNING, ref, this);
					vc.addMessage(message);
				}
				else if ((!areSRolesDefined) && (isLinkDefined)) {
					// must not have role link defined (15.2.5.3)
					IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2827, IEJBValidationContext.WARNING, ref, this);
					vc.addMessage(message);
				}
				else if (areSRolesDefined && isLinkDefined) {
					// check that the role listed in the link exists. (15.3.3)
					Iterator iterator = _securityRoles.iterator();
					boolean roleExists = false;
					while(iterator.hasNext()) {
						SecurityRole role = (SecurityRole)iterator.next();
						if(role.getRoleName().equals(roleLink)) {
							roleExists = true;
							break;
						}
					}
					if (!roleExists) {
						IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2824, IEJBValidationContext.WARNING, ref, new String[] { roleName }, this);
						vc.addMessage(message);
					}
				}
			}

			// Check for duplicates
			// Check that there are no duplicate role-names. (15.3.1)
			if (roleRefNames.containsDuplicates()) {
				List duplicates = roleRefNames.getDuplicates();
				Iterator iterator = duplicates.iterator();
				while (iterator.hasNext()) {
					IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2820, IEJBValidationContext.WARNING, ((RoleRefWrapper) iterator.next()).getRoleRef(), this);
					vc.addMessage(message);
				}
			}
			roleRefNames.clear();
		}
	}
	
	/**
	 * 6.5.3 The optional SessionSynchronization interface
	 *...
	 * Only a stateful Session bean with container-managed transaction demarcation may 
	 * implement the SessionSynchronization interface.
	 *...
	 * There is no need for a Session bean with bean-managed transaction to rely on the 
	 * synchronization call backs because the bean is in control of the commit the bean 
	 * knows when the transaction is about to be committed and it knows the outcome of the 
	 * transaction commit.
	 *...
	 */
	public void validateSessionTypeElement(IEJBValidationContext vc, EJBJar ejbJar, EnterpriseBean bean) {
		if (bean.isSession()) {
			Session session = (Session) bean;

			// check syntax
			boolean isValidSess = isValidSessionTypeElement(session);
			if (!isValidSess) {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2807, IEJBValidationContext.ERROR, session, this);
				vc.addMessage(message);
			}
		}
	}
	
	public void validateTransactionTypeElement(IEJBValidationContext vc, EJBJar ejbJar, EnterpriseBean bean) {
		if (bean.isSession()) {
			// check syntax
			Session sessionBean = (Session) bean;
			if (!isValidTransactionTypeElement(sessionBean)) {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2808, IEJBValidationContext.ERROR, bean, this);
				vc.addMessage(message);
			}
		}
	}
	
	/*
	 * @see IValidationRule#reset()
	 */
	public void reset() {
		super.reset();
		_securityRoles = null;
	}

	/*
	 * @see IValidationRule#preValidate(IEJBValidationContext, Object, Object)
	 */
	public void preValidate(IEJBValidationContext vc, Object targetParent, Object target) throws ValidationCancelledException, ValidationException {
		super.preValidate(vc, targetParent, target);

		EJBJar ejbJar = (EJBJar)vc.loadModel(EJBValidatorModelEnum.EJB_MODEL);
		if(ejbJar == null) {
			return;
		}
		
		if(ejbJar.getAssemblyDescriptor() == null) {
			return;
		}
		_securityRoles = ejbJar.getAssemblyDescriptor().getSecurityRoles();
	}
}
