/*******************************************************************************
 * 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.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.CommonPackage;
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.EjbPackage;
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.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();
	}
}
