/*******************************************************************************
 * 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.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;

import org.eclipse.jem.java.Method;
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.SecurityRole;
import org.eclipse.jst.j2ee.ejb.AssemblyDescriptor;
import org.eclipse.jst.j2ee.ejb.CMRField;
import org.eclipse.jst.j2ee.ejb.ContainerManagedEntity;
import org.eclipse.jst.j2ee.ejb.EJBJar;
import org.eclipse.jst.j2ee.ejb.EJBRelation;
import org.eclipse.jst.j2ee.ejb.EJBRelationshipRole;
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.MethodElement;
import org.eclipse.jst.j2ee.ejb.MethodPermission;
import org.eclipse.jst.j2ee.ejb.MethodTransaction;
import org.eclipse.jst.j2ee.ejb.MultiplicityKind;
import org.eclipse.jst.j2ee.ejb.Relationships;
import org.eclipse.jst.j2ee.ejb.RoleSource;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
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;

/**
 * @version 	1.0
 * @author
 */
public class EJBJar20VRule extends AValidationRule implements IMessagePrefixEjb20Constants {
	private static final Map MESSAGE_IDS;
	private DuplicatesTable _ejbName = null;
	private DuplicatesTable _asName = null;
	private DuplicatesTable _relationshipName = null;
	private DuplicatesTable _relationshipRoleName = null;
	private static final Object[] DEPENDS_ON = new Object[]{IValidationRuleList.EJB20_STATELESS_SESSION_BEANCLASS, IValidationRuleList.EJB20_STATELESS_SESSION_REMOTE, IValidationRuleList.EJB20_STATELESS_SESSION_HOME, IValidationRuleList.EJB20_STATELESS_SESSION_LOCAL, IValidationRuleList.EJB20_STATELESS_SESSION_LOCALHOME, IValidationRuleList.EJB20_STATEFUL_SESSION_BEANCLASS, IValidationRuleList.EJB20_STATEFUL_SESSION_REMOTE, IValidationRuleList.EJB20_STATEFUL_SESSION_HOME, IValidationRuleList.EJB20_STATEFUL_SESSION_LOCAL, IValidationRuleList.EJB20_STATEFUL_SESSION_LOCALHOME, IValidationRuleList.EJB20_CMP_BEANCLASS, IValidationRuleList.EJB20_CMP_REMOTE, IValidationRuleList.EJB20_CMP_HOME, IValidationRuleList.EJB20_CMP_LOCAL, IValidationRuleList.EJB20_CMP_LOCALHOME, IValidationRuleList.EJB20_CMP_KEYCLASS, IValidationRuleList.EJB20_BMP_BEANCLASS, IValidationRuleList.EJB20_BMP_REMOTE, IValidationRuleList.EJB20_BMP_HOME, IValidationRuleList.EJB20_BMP_LOCAL, IValidationRuleList.EJB20_BMP_LOCALHOME, IValidationRuleList.EJB20_BMP_KEYCLASS, IValidationRuleList.EJB20_MESSAGE_BEANCLASS, IValidationRuleList.EJB20_EJBEXT};
	
	static {
		MESSAGE_IDS = new HashMap();
		
		MESSAGE_IDS.put(CHKJ2800_NAMED, new String[]{CHKJ2800_NAMED+SPEC});
		MESSAGE_IDS.put(CHKJ2800_UNNAMED, new String[]{CHKJ2800_UNNAMED+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(CHKJ2805_NAMED, new String[]{CHKJ2805_NAMED+SPEC});
		MESSAGE_IDS.put(CHKJ2805_UNNAMED, new String[]{CHKJ2805_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(CHKJ2814, new String[]{CHKJ2814+SPEC});
		MESSAGE_IDS.put(CHKJ2816, new String[]{CHKJ2816+SPEC});
		MESSAGE_IDS.put(CHKJ2817, new String[]{CHKJ2817+SPEC});
		MESSAGE_IDS.put(CHKJ2818, new String[]{CHKJ2818+SPEC});
		MESSAGE_IDS.put(CHKJ2820, new String[]{CHKJ2820+SPEC});
		MESSAGE_IDS.put(CHKJ2821, new String[]{CHKJ2821+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(CHKJ2825, new String[]{CHKJ2825+SPEC});
		MESSAGE_IDS.put(CHKJ2826, new String[]{CHKJ2826+SPEC});
		MESSAGE_IDS.put(CHKJ2827, new String[]{CHKJ2827+SPEC});
		MESSAGE_IDS.put(CHKJ2828, new String[]{CHKJ2828+SPEC});
		MESSAGE_IDS.put(CHKJ2829, new String[]{CHKJ2829+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(CHKJ2841, new String[]{CHKJ2841+SPEC});
		MESSAGE_IDS.put(CHKJ2842, new String[]{CHKJ2842+SPEC});
		MESSAGE_IDS.put(CHKJ2843, new String[]{CHKJ2843+SPEC});
		MESSAGE_IDS.put(CHKJ2844, new String[]{CHKJ2844+SPEC});
		MESSAGE_IDS.put(CHKJ2845, new String[]{CHKJ2845+SPEC});
		MESSAGE_IDS.put(CHKJ2846, new String[]{CHKJ2846+SPEC});
		MESSAGE_IDS.put(CHKJ2847, new String[]{CHKJ2847+SPEC});
		MESSAGE_IDS.put(CHKJ2848, new String[]{CHKJ2848+SPEC});
		MESSAGE_IDS.put(CHKJ2850, new String[]{CHKJ2850+SPEC});
		MESSAGE_IDS.put(CHKJ2854, new String[]{CHKJ2854+SPEC});
		MESSAGE_IDS.put(CHKJ2855, new String[]{CHKJ2855+SPEC});
		MESSAGE_IDS.put(CHKJ2856, new String[]{CHKJ2856+SPEC});
		MESSAGE_IDS.put(CHKJ2857, new String[]{CHKJ2857+SPEC});
		MESSAGE_IDS.put(CHKJ2858, new String[]{CHKJ2858+SPEC});
		MESSAGE_IDS.put(CHKJ2859, new String[]{CHKJ2859+SPEC});
		MESSAGE_IDS.put(CHKJ2860, new String[]{CHKJ2860+SPEC});
		MESSAGE_IDS.put(CHKJ2866, new String[]{CHKJ2866+SPEC});
		MESSAGE_IDS.put(CHKJ2867, new String[]{CHKJ2867+SPEC});
		MESSAGE_IDS.put(CHKJ2868, new String[]{CHKJ2868+SPEC});
		MESSAGE_IDS.put(CHKJ2869, new String[]{CHKJ2869+SPEC});
		MESSAGE_IDS.put(CHKJ2871, new String[]{CHKJ2871+SPEC});
		MESSAGE_IDS.put(CHKJ2872, new String[]{CHKJ2872+SPEC});
		MESSAGE_IDS.put(CHKJ2873, new String[]{CHKJ2873+SPEC});
		MESSAGE_IDS.put(CHKJ2874, new String[]{CHKJ2874+SPEC});
		MESSAGE_IDS.put(CHKJ2875, new String[]{CHKJ2875 + SPEC});
		MESSAGE_IDS.put(CHKJ2895, new String[]{CHKJ2895+SPEC});
		MESSAGE_IDS.put(CHKJ2852, new String[]{CHKJ2852});
		MESSAGE_IDS.put(CHKJ2907, new String[]{CHKJ2907});
	}
	
	public EJBJar20VRule() {
		_ejbName = new DuplicatesTable();
		_asName = new DuplicatesTable();
		_relationshipName = new DuplicatesTable();
		_relationshipRoleName = new DuplicatesTable();
	}
	
	public Object[] getDependsOn() {
		// EJBJar doesn't depend on anything else
		return DEPENDS_ON;
	}

	public Object getId() {
		return IValidationRuleList.EJB20_EJBJAR;
	}

	public Map getMessageIds() {
		return MESSAGE_IDS;
	}

	public Object getTarget(Object parent, Object clazz) {
		// Since this rule doesn't depend on another rule, this
		// method (which is called on a dependent rule) will never
		// be called.
		return null;
	}

	/*
	 * @see IValidationRule#reset()
	 */
	public void reset() {
		super.reset();
		_ejbName.clear();
		_asName.clear();
		_relationshipName.clear();
		_relationshipRoleName.clear();
	}

	protected void addInternalErrorMessage(IEJBValidationContext vc, Throwable exc) {
		IMessage mssg = vc.getMessage();
		mssg.setId(IEJBValidatorMessageConstants.CHKJ2900);
		vc.addMessage(mssg);

		if(exc != null) {
			Logger logger = vc.getMsgLogger();
			if (logger != null && logger.isLoggingLevel(Level.SEVERE)) {
				logger.write(Level.SEVERE, exc);
			}
		}
	}
	
	protected void logMissingRule(IEJBValidationContext vc, Object ruleId) {
		log(vc, ruleId + " = null"); //$NON-NLS-1$
		addInternalErrorMessage(vc, null);
	}
	
	protected void log(IEJBValidationContext vc, String message) {
		Logger logger = vc.getMsgLogger();
		if (logger != null && logger.isLoggingLevel(Level.SEVERE)) {
			logger.write(Level.SEVERE, message);
		}
	}
	
	/*
	 * @see IValidationRule#validate(IEJBValidationContext, Object, Object)
		 */
	public void validate(IEJBValidationContext vc, Object targetParent, Object target) throws ValidationCancelledException, ValidationException {
		Logger logger = vc.getMsgLogger();
		if(logger != null && logger.isLoggingLevel(Level.FINEST)) {
			LogEntry entry = vc.getLogEntry();
			entry.setSourceID("EJBJar20VRule - validate"); //$NON-NLS-1$
			entry.setText(getClass().getName() + "::validate(" + targetParent + ", " + target); //$NON-NLS-1$ //$NON-NLS-2$
			logger.write(Level.FINEST, entry);
		}
		
		EJBJar ejbJar = (EJBJar) target;
		List beans = ejbJar.getEnterpriseBeans();
		Iterator iterator = beans.iterator();
		EnterpriseBean bean = null;
		while (iterator.hasNext()) {
			try {
				bean = (EnterpriseBean) iterator.next();

				register(vc, ejbJar, bean);
	
				Object id = null;			
				switch(bean.getVersionID()) {
					case J2EEVersionConstants.EJB_1_0_ID:
					case J2EEVersionConstants.EJB_1_1_ID:
						id = IValidationRuleList.EJB11_ENTERPRISEBEAN;
						break;
					case J2EEVersionConstants.EJB_2_0_ID:
					case J2EEVersionConstants.EJB_2_1_ID: 
						id = IValidationRuleList.EJB20_ENTERPRISEBEAN;
						break; 
					default:
						// What version is it then?
						if(bean instanceof ContainerManagedEntity) {
							validateCMPVersionElement(vc, ejbJar, (ContainerManagedEntity)bean);
						}
						else {
							// log
							log(vc, "!bean.isVersion1_X() && !bean.isVersion2_X()"); //$NON-NLS-1$
						}
						continue;
				}				 
				
				IValidationRule vRule = EJBValidationRuleFactory.getFactory().getRule(vc, id);
				if(vRule == null) {
					logMissingRule(vc, id);
					continue;
				}
				try {
					vRule.preValidate(vc, ejbJar, bean);
					vRule.validate(vc, ejbJar, bean);
					vRule.postValidate(vc, ejbJar, bean);
				}
				catch(ValidationCancelledException exc) {
					// Clean up the messages which are on the task list? Or is it nicer to leave them behind?
					throw exc;
				}
				catch(MessageLimitException e) {
					throw e;
				}
				catch(ValidationException e) {
					throw e;
				}
				catch(Throwable exc) {
					addInternalErrorMessage(vc, exc);
				}
				finally {
					EJBValidationRuleFactory.getFactory().release(vRule);
				}
				
			}
			catch (MessageLimitException e) {
				throw e;
			}
			catch(ValidationCancelledException e) {
				throw e;
			}
			catch(ValidationException exc) {
				// something goes wrong, just proceed with the next bean
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2852, IEJBValidationContext.WARNING, bean, new String[]{J2EEConstants.EJBJAR_DD_SHORT_NAME, bean.getName()}, this);
				vc.addMessage(message);
				if (logger.isLoggingLevel(Level.SEVERE)) {
					logger.write(Level.SEVERE, exc);
				}
			}
			catch (Throwable exc) {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2852, IEJBValidationContext.WARNING, bean, new String[]{J2EEConstants.EJBJAR_DD_SHORT_NAME, bean.getName()}, this);
				vc.addMessage(message);
				if (logger.isLoggingLevel(Level.SEVERE)) {
					logger.write(Level.SEVERE, exc);
				}
			}
		}

		// Since the assembly descriptor is not specific to a bean, validate it once, after all bean processing is complete.
		validateAssemblyDescriptorElement(vc, ejbJar);
		//TODO The Datasource validation will be done by the extensions
		validateUniqueEjbNames(vc, ejbJar);
		validateUniqueAbstractSchemaNames(vc, ejbJar);
		validateRelationships(vc, ejbJar);
		validateClientJAR(vc, ejbJar);
	}
	
	protected void register(IEJBValidationContext vc, EJBJar ejbJar, EnterpriseBean bean) {
		// To check if every bean name is unique, need to build a list
		_ejbName.add(new EjbNameWrapper(bean));
		
		if((bean instanceof ContainerManagedEntity) && bean.getVersionID() >= J2EEVersionConstants.EJB_2_0_ID) {
			// To check if every bean name is unique, need to build a list
			_asName.add(new ASNameWrapper((ContainerManagedEntity)bean));
		}
	}

	protected void validateCMPVersionElement(IEJBValidationContext vc, EJBJar ejbJar, ContainerManagedEntity cmp) {
		if(cmp.eIsSet(EjbPackage.eINSTANCE.getContainerManagedEntity_Version())) {
			String version = cmp.getVersion();
			if(! (ContainerManagedEntity.VERSION_1_X.equals(version) || ContainerManagedEntity.VERSION_2_X.equals(version))) {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2872, IEJBValidationContext.ERROR, cmp, this);
				vc.addMessage(message);
			}			
		}
	}
	
		

	protected void validateAssemblyDescriptorElement(IEJBValidationContext vc, EJBJar ejbJar) {
		vc.terminateIfCancelled();

		// Validate the security roles, if they're defined in the assembly-descriptor.
		if (ejbJar == null) {
			// nothing to validate
			return;
		}

		/**
		 * Need to build up a list of duplicate role names, but the validation message
		 * needs to be registered against the duplicate SecurityRole instance.
		 * (Without the instance, we cannot get line numbers.)
		 *
		 * This class wrappers the SecurityRol 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 RoleWrapper {
			private SecurityRole _role = null;

			public RoleWrapper(SecurityRole role) {
				_role = role;
			}

			public boolean equals(Object o) {
				if (o instanceof RoleWrapper) {
					RoleWrapper other = (RoleWrapper) o;
					return _role.getRoleName().equals(other.getRole().getRoleName());
				}
				return false;
			}

			public SecurityRole getRole() {
				return _role;
			}
		}

		AssemblyDescriptor assemblyDescriptor = ejbJar.getAssemblyDescriptor();
		if (assemblyDescriptor == null) {
			// nothing to validate
			return;
		}

		List roles = assemblyDescriptor.getSecurityRoles();
		if (roles != null) {
			DuplicatesTable roleNames = new DuplicatesTable();
			SecurityRole role = null;
			Iterator roleIt = roles.iterator();
			while (roleIt.hasNext()) {
				vc.terminateIfCancelled();
				// Check that the role-name element has been set
				role = (SecurityRole) roleIt.next();
				if ((role == null) || (!role.eIsSet(CommonPackage.eINSTANCE.getSecurityRole_RoleName())) || (role.getRoleName().equals(""))) { //$NON-NLS-1$
					// role-name not set
					if(role == null) {
						IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2825, IEJBValidationContext.WARNING, role, this);
						vc.addMessage(message);
					}
					else {
						IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2825, IEJBValidationContext.WARNING, assemblyDescriptor, this);
						vc.addMessage(message);
					}
				}
				else {
					// Build up hashtable to check for duplicate role-names.
					roleNames.add(new RoleWrapper(role));
				}
			}

			// Check that there are no duplicate role-names. (15.3.1)
			if (roleNames.containsDuplicates()) {
				List duplicates = roleNames.getDuplicates();
				Iterator iterator = duplicates.iterator();
				while (iterator.hasNext()) {
					IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2826, IEJBValidationContext.WARNING, ((RoleWrapper) iterator.next()).getRole(), this);
					vc.addMessage(message);
				}
			}
			roleNames.clear();
		}

		List methTrans = assemblyDescriptor.getMethodTransactions();
		MethodTransaction mt = null;
		Iterator iterator = methTrans.iterator();
		while (iterator.hasNext()) {
			vc.terminateIfCancelled();

			try {
				mt = (MethodTransaction) iterator.next();
			}
			catch (Throwable exc) {
				Logger logger = vc.getMsgLogger();
				if (logger != null && logger.isLoggingLevel(Level.FINER)) {
					logger.write(Level.FINER, exc);
				}
				mt = null;
			}

			if (mt == null) {
				Logger logger = vc.getMsgLogger();
				if (logger != null && logger.isLoggingLevel(Level.FINEST)) {
					LogEntry entry = vc.getLogEntry();
					entry.setSourceID("EJBJar20VRule.validateAssemblyDescriptorElement"); //$NON-NLS-1$
					entry.setText("mt is null"); //$NON-NLS-1$
					logger.write(Level.FINEST, entry);
				}
				continue;
			}

			boolean hasValidMethod = validateMethodElements(vc, ejbJar, mt.getMethodElements());
			if (!hasValidMethod) {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2847, IEJBValidationContext.WARNING, mt, this);
				vc.addMessage(message);
			}
		}

		List methodPermissions = assemblyDescriptor.getMethodPermissions();
		iterator = methodPermissions.iterator();
		while (iterator.hasNext()) {
			MethodPermission mp = (MethodPermission) iterator.next();

			boolean hasValidMethod = validateMethodElements(vc, ejbJar, mp.getMethodElements());
			if (!hasValidMethod) {
				// 15.3.2, p. 229, a <method-permission> must have at least one method listed (and that method must be found)
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2846, IEJBValidationContext.WARNING, mp, this);
				vc.addMessage(message);
			}

			// at least one security-role must be defined
			List mproles = mp.getRoles();
			if (((mproles == null) || (mproles.size() == 0)) && (!mp.isSetUnchecked())) {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2845, IEJBValidationContext.WARNING, mp, this);
				vc.addMessage(message);
			}
		}
	}

	protected void validateUniqueAbstractSchemaNames(IEJBValidationContext vc, EJBJar ejbJar) {
		List names = _asName.getDuplicates();
		if(names.size() == 0) {
			return;
		}
		
		Iterator iterator = names.iterator();
		while(iterator.hasNext()) {
			ASNameWrapper wrapper = (ASNameWrapper)iterator.next();
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2854, IEJBValidationContext.ERROR, wrapper.getBean(), new String[]{wrapper.getBean().getAbstractSchemaName()}, this);
			vc.addMessage(message);
		}
	}
	
	protected void validateUniqueEjbNames(IEJBValidationContext vc, EJBJar ejbJar) {
		List names = _ejbName.getDuplicates();
		if(names.size() == 0) {
			return;
		}
		
		Iterator iterator = names.iterator();
		while(iterator.hasNext()) {
			EjbNameWrapper wrapper = (EjbNameWrapper)iterator.next();
			IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2895, IEJBValidationContext.WARNING, wrapper.getBean(), new String[]{wrapper.getBean().getName()}, this);
			vc.addMessage(message);
		}
	}

	protected void validateRelationships(IEJBValidationContext vc, EJBJar ejbJar) {
		Relationships relationships = ejbJar.getRelationshipList();
		if(relationships == null) {
			return;
		}
		
		List ejbRelationList = relationships.getEjbRelations();
		Iterator iterator = ejbRelationList.iterator();
		while(iterator.hasNext()) {
			EJBRelation relation = (EJBRelation)iterator.next();
			
			_relationshipName.add(new EJBRelationNameWrapper(relation));
			
			boolean atLeastOneCmrFieldExists = false;
			List roles = relation.getRelationshipRoles();
			Iterator roleIterator = roles.iterator();
			while(roleIterator.hasNext()) {
				EJBRelationshipRole role = (EJBRelationshipRole)roleIterator.next();
				
				_relationshipRoleName.add(new EJBRelationshipRoleNameWrapper(role));

				boolean validMultiplicity = role.isSetMultiplicity();
				if(!validMultiplicity) {
					IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2818, IEJBValidationContext.INFO, role, this);
					vc.addMessage(message);
				}
	
				// 10.3.4.2 
				// The cascade-delete element can only be specified for an ejb-relationship-role
				// element contained in an ejb-relation element if the *other* ejb-relationship-role
				// element in the same ejb-relation element specifies a multiplicity of One.
				EJBRelationshipRole oppositeRole = role.getOpposite();
				if(role.isSetCascadeDelete()) {
					boolean isOtherMultiplicityOne = ((oppositeRole.isSetMultiplicity()) && (oppositeRole.getMultiplicity().getValue() == MultiplicityKind.ONE));
					if(!isOtherMultiplicityOne) {
						IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2848, IEJBValidationContext.INFO, role, this);
						vc.addMessage(message);
					}
				}
				
				CMRField cmrField = role.getCmrField();
				if(cmrField != null) {
					atLeastOneCmrFieldExists = true;
					if(cmrField.eIsSet(EjbPackage.eINSTANCE.getCMRField_CollectionType())) {
						String cmrFieldType = cmrField.getCollectionTypeName();
						if((!ITypeConstants.CLASSNAME_JAVA_UTIL_COLLECTION.equals(cmrFieldType)) &&
							(!ITypeConstants.CLASSNAME_JAVA_UTIL_SET.equals(cmrFieldType))) {
							// CHKJ2868: The value of the <cmr-field-type> element must be either "java.util.Collection" or "java.util.Set" (EJB 2.0: 10.3.13, 22.5).
							IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2868, IEJBValidationContext.INFO, role, this);
							vc.addMessage(message);
						}
					}
				}
				
				RoleSource sourceRoleSource = role.getSource();
				if(sourceRoleSource == null) {
					IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2821, IEJBValidationContext.INFO, role, new String[]{role.getName()}, this);
					vc.addMessage(message);
					continue;
				}

				Entity sourceEntity = sourceRoleSource.getEntityBean();
				if(sourceEntity == null) {
					IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2821, IEJBValidationContext.INFO, role, new String[]{role.getName()}, this);
					vc.addMessage(message);
				}
				else if(sourceEntity.isContainerManagedEntity()) {
					// CHKJ2866: <cmr-field> {0} must be defined on {1} (EJB 2.0: 22.5).
					if(cmrField != null) {
						ContainerManagedEntity cmp = (ContainerManagedEntity)sourceEntity;
						List cmrFields = cmp.getCMRFields();
						boolean found_cmrField = false;
						if((cmrFields != null) && (cmrFields.size() > 0)) {
							found_cmrField = cmrFields.contains(cmrField);
						}
						
						if(!found_cmrField) {
							IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2866, IEJBValidationContext.INFO, role, new String[]{cmrField.getName(), sourceEntity.getName()}, this);
							vc.addMessage(message);
						}
					}
				}
				else {
					// CHKJ2871: <ejb-name> {0} must refer to a CMP bean (EJB 2.0: 10.3.2, 10.3.13).
					IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2871, IEJBValidationContext.INFO, role, new String[]{sourceEntity.getName()}, this);
					vc.addMessage(message);
				}
				
				RoleSource oppositeRoleSource = oppositeRole.getSource();
				if(oppositeRoleSource == null) {
					// Do not emit an error message - when we iterate to the role where
					// this is the source, this error will be detected.
					continue;
				}

				Entity targetEntity = oppositeRoleSource.getEntityBean();
				if(targetEntity == null) {
					// Do not emit an error message - when we iterate to the role where
					// this is the source, this error will be detected.
				}
				else if(targetEntity.getLocalInterface() == null) {
					// Does the target of this role have a local interface?
					// CHKJ2867: This bean can have only unidirectional relationships to other beans (EJB 2.0: 10.3.2).
					IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2867, IEJBValidationContext.INFO, oppositeRole, this);
					vc.addMessage(message);
				}
			}
			
			// Verify unique role names within the <ejb-relation>
			validateUniqueRelationshipRoleNames(vc, ejbJar);
			_relationshipRoleName.clear();
			
			if(!atLeastOneCmrFieldExists) {
				// CHKJ2869I: At least one <ejb-relationship-role> must define a <cmr-field> (EJB 2.0: 10.3.2, 10.3.13, 22.5).
				IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2869, IEJBValidationContext.INFO, relation, this);
				vc.addMessage(message);
			}
		}
		
		validateUniqueRelationNames(vc, ejbJar);
	}
	
	protected void validateUniqueRelationNames(IEJBValidationContext vc, EJBJar ejbJar) {
		List names = _relationshipName.getDuplicates();
		if(names.size() == 0) {
			return;
		}
		
		Iterator iterator = names.iterator();
		while(iterator.hasNext()) {
			EJBRelationNameWrapper wrapper = (EJBRelationNameWrapper)iterator.next();
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2816, IEJBValidationContext.INFO, wrapper.getRelation(), new String[]{wrapper.getRelation().getName()}, this);
			vc.addMessage(message);
		}
	}
	
	protected void validateUniqueRelationshipRoleNames(IEJBValidationContext vc, EJBJar ejbJar) {
		List names = _relationshipRoleName.getDuplicates();
		if(names.size() == 0) {
			return;
		}
		
		Iterator iterator = names.iterator();
		while(iterator.hasNext()) {
			EJBRelationshipRoleNameWrapper wrapper = (EJBRelationshipRoleNameWrapper)iterator.next();
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2817, IEJBValidationContext.INFO, wrapper.getRelationshipRole(), new String[]{wrapper.getRelationshipRole().getName()}, this);
			vc.addMessage(message);
		}
	}
	
	/**
	 * Both section 11.4.1 and 15.3.2 need the <method> element. Also refer
	 * to 16.5 for syntax.
	 *
	 * Return true if at least one of the methods referenced by this list of 
	 * MethodElement can be found.
	*/
	protected boolean validateMethodElements(IEJBValidationContext vc, EJBJar ejbJar, List elements) {
		if ((elements == null) || (elements.size() == 0)) {
			return false;
		}

		boolean hasValidMethod = false;
		Iterator iterator = elements.iterator();
		while (iterator.hasNext()) {
			vc.terminateIfCancelled();
			MethodElement element = (MethodElement) iterator.next();

			EnterpriseBean bean = element.getEnterpriseBean();
			if (bean == null) {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2814, IEJBValidationContext.WARNING, element, this);
				vc.addMessage(message);
				continue;
			}

			if (element.getName() != null) {
				String name = element.getName();

				Method[] methods = element.getMethods(); // get all methods which will be retrieved for the given method-permission
				boolean hasMethods = ((methods != null) && (methods.length > 0));

				if (!hasMethods) {
					// warning
					IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2843, IEJBValidationContext.WARNING, element, new String[] { bean.getName()}, this);
					vc.addMessage(message);
				}
				else {
					hasValidMethod = true; // a <method-permission> must have at least one method (15.3.2, p.229)
					if (name.equals("*")) { //$NON-NLS-1$
						List params = element.getMethodParams();
						if ((params != null) && (params.size() > 0)) {
							// warning
							IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2842, IEJBValidationContext.WARNING, element, this);
							vc.addMessage(message);
						}
					}
				}
			}
			else {
				// error
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2844, IEJBValidationContext.WARNING, element, this);
				vc.addMessage(message);
			}
		}

		return hasValidMethod;
	}

	protected void validateClientJAR(IEJBValidationContext vc, EJBJar ejbJar) {
		String clientJARName = ejbJar.getEjbClientJar();
		if(clientJARName == null) {
			// No client JAR specified; everything's okay.
			return;
		}
		
		Boolean exists = (Boolean)vc.loadModel(EJBValidatorModelEnum.EJB_CLIENTJAR, new Object[]{clientJARName});
		if(exists == null) {
			// Helper doesn't support load model. WAS?
			// Can't perform this check, so just return.
			return;
		}
		
		if(!exists.booleanValue()) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2875, IEJBValidationContext.ERROR, ejbJar, new String[]{clientJARName}, this);
			vc.addMessage(message);
		}
	}
	
	class ASNameWrapper {
		private ContainerManagedEntity _bean = null;

		public ASNameWrapper(ContainerManagedEntity bean) {
			_bean = bean;
		}

		public boolean equals(Object o) {
			if (o instanceof ASNameWrapper) {
				ASNameWrapper other = (ASNameWrapper)o;
				if((_bean.getAbstractSchemaName() == null) && (other.getBean().getAbstractSchemaName() == null)) {
					return true;
				}
				else if(_bean.getAbstractSchemaName() == null) {
					return false;
				}
				else if(other.getBean().getAbstractSchemaName() == null) {
					return false;
				}
				return _bean.getAbstractSchemaName().equals(other.getBean().getAbstractSchemaName());
			}
			return false;
		}

		public int hashCode() {
			if((getBean() != null) && (getBean().getAbstractSchemaName() != null)) {
				return getBean().getAbstractSchemaName().hashCode();
			}
			return super.hashCode();
		}

		public ContainerManagedEntity getBean() {
			return _bean;
		}
	}

	/**
	 * Need to build up a list of duplicate EJB names, but the validation message
	 * needs to be registered against the duplicate EnterpriseBean instance.
	 * (Without the instance, we cannot get line numbers.)
	 *
	 * This class wrappers the EnterpriseBean 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 EjbNameWrapper {
		private EnterpriseBean _bean = null;

		public EjbNameWrapper(EnterpriseBean bean) {
			_bean = bean;
		}

		public boolean equals(Object o) {
			if (o instanceof EjbNameWrapper) {
				EjbNameWrapper other = (EjbNameWrapper)o;
				if((_bean.getName() == null) && (other.getBean().getName() == null)) {
					return true;
				}
				else if(_bean.getName() == null) {
					return false;
				}
				else if(other.getBean().getName() == null) {
					return false;
				}
				return _bean.getName().equals(other.getBean().getName());
			}
			return false;
		}
		
		public int hashCode() {
			if((getBean() != null) && (getBean().getName() != null)) {
				return getBean().getName().hashCode();
			}
			return super.hashCode();
		}

		public EnterpriseBean getBean() {
			return _bean;
		}
	}

	/**
	 * Need to build up a list of duplicate relation names, but the validation message
	 * needs to be registered against the duplicate EnterpriseBean instance.
	 * (Without the instance, we cannot get line numbers.)
	 *
	 * This class wrappers the EnterpriseBean 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 EJBRelationNameWrapper {
		private EJBRelation _relation = null;

		public EJBRelationNameWrapper(EJBRelation rel) {
			_relation = rel;
		}

		public boolean equals(Object o) {
			if (o instanceof EJBRelationNameWrapper) {
				EJBRelationNameWrapper other = (EJBRelationNameWrapper)o;
				if((_relation.getName() == null) && (other.getRelation().getName() == null)) {
					return true;
				}
				else if(_relation.getName() == null) {
					return false;
				}
				else if(other.getRelation().getName() == null) {
					return false;
				}
				return _relation.getName().equals(other.getRelation().getName());
			}
			return false;
		}
		
		public int hashCode() {
			if((getRelation() != null) && (getRelation().getName() != null)) {
				return getRelation().getName().hashCode();
			}
			return super.hashCode();
		}

		public EJBRelation getRelation() {
			return _relation;
		}
	}

	/**
	 * Need to build up a list of duplicate relation names, but the validation message
	 * needs to be registered against the duplicate EnterpriseBean instance.
	 * (Without the instance, we cannot get line numbers.)
	 *
	 * This class wrappers the EnterpriseBean 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 EJBRelationshipRoleNameWrapper {
		private EJBRelationshipRole _relationshipRole = null;

		public EJBRelationshipRoleNameWrapper(EJBRelationshipRole role) {
			_relationshipRole = role;
		}

		public boolean equals(Object o) {
			if (o instanceof EJBRelationshipRoleNameWrapper) {
				EJBRelationshipRoleNameWrapper other = (EJBRelationshipRoleNameWrapper)o;
				if((_relationshipRole.getRoleName() == null) && (other.getRelationshipRole().getRoleName() == null)) {
					return true;
				}
				else if(_relationshipRole.getRoleName() == null) {
					return false;
				}
				else if(other.getRelationshipRole().getRoleName() == null) {
					return false;
				}
				return _relationshipRole.getRoleName().equals(other.getRelationshipRole().getRoleName());
			}
			return false;
		}
		
		public int hashCode() {
			if((getRelationshipRole() != null) && (getRelationshipRole().getRoleName() != null)) {
				return getRelationshipRole().getRoleName().hashCode();
			}
			return super.hashCode();
		}

		public EJBRelationshipRole getRelationshipRole() {
			return _relationshipRole;
		}
	}
}
