/*******************************************************************************
 * 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.jst.j2ee.common.CommonPackage;
import org.eclipse.jst.j2ee.common.SecurityRole;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveConstants;
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.J2EEVersionConstants;
import org.eclipse.wst.validation.core.IMessage;
import org.eclipse.wst.validation.core.MessageLimitException;
import org.eclipse.wst.validation.core.ValidationException;

import com.ibm.wtp.common.logger.LogEntry;
import com.ibm.wtp.common.logger.proxy.Logger;

/**
 * @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(IValidationContext vc, Throwable exc) {
		IMessage mssg = vc.getMessage();
		mssg.setId(IMessagePrefixEjb20Constants.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(IValidationContext vc, Object ruleId) {
		log(vc, ruleId + " = null"); //$NON-NLS-1$
		addInternalErrorMessage(vc, null);
	}
	
	protected void log(IValidationContext vc, String message) {
		Logger logger = vc.getMsgLogger();
		if (logger != null && logger.isLoggingLevel(Level.SEVERE)) {
			logger.write(Level.SEVERE, message);
		}
	}
	
	/*
	 * @see IValidationRule#validate(IValidationContext, Object, Object)
		 */
	public void validate(IValidationContext 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, IMessagePrefixEjb20Constants.CHKJ2852, IValidationContext.WARNING, bean, new String[]{ArchiveConstants.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, IMessagePrefixEjb20Constants.CHKJ2852, IValidationContext.WARNING, bean, new String[]{ArchiveConstants.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(IValidationContext 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(IValidationContext 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, IValidationContext.ERROR, cmp, this);
				vc.addMessage(message);
			}			
		}
	}
	
		

	protected void validateAssemblyDescriptorElement(IValidationContext 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, IMessagePrefixEjb20Constants.CHKJ2825, IValidationContext.WARNING, role, this);
						vc.addMessage(message);
					}
					else {
						IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2825, IValidationContext.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, IMessagePrefixEjb20Constants.CHKJ2826, IValidationContext.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, IMessagePrefixEjb20Constants.CHKJ2847, IValidationContext.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, IMessagePrefixEjb20Constants.CHKJ2846, IValidationContext.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, IMessagePrefixEjb20Constants.CHKJ2845, IValidationContext.WARNING, mp, this);
				vc.addMessage(message);
			}
		}
	}

	protected void validateUniqueAbstractSchemaNames(IValidationContext 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, IValidationContext.ERROR, wrapper.getBean(), new String[]{wrapper.getBean().getAbstractSchemaName()}, this);
			vc.addMessage(message);
		}
	}
	
	protected void validateUniqueEjbNames(IValidationContext 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, IMessagePrefixEjb20Constants.CHKJ2895, IValidationContext.WARNING, wrapper.getBean(), new String[]{wrapper.getBean().getName()}, this);
			vc.addMessage(message);
		}
	}

	protected void validateRelationships(IValidationContext 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, IValidationContext.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, IValidationContext.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, IValidationContext.INFO, role, this);
							vc.addMessage(message);
						}
					}
				}
				
				RoleSource sourceRoleSource = role.getSource();
				if(sourceRoleSource == null) {
					IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2821, IValidationContext.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, IValidationContext.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, IValidationContext.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, IValidationContext.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, IValidationContext.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, IValidationContext.INFO, relation, this);
				vc.addMessage(message);
			}
		}
		
		validateUniqueRelationNames(vc, ejbJar);
	}
	
	protected void validateUniqueRelationNames(IValidationContext 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, IValidationContext.INFO, wrapper.getRelation(), new String[]{wrapper.getRelation().getName()}, this);
			vc.addMessage(message);
		}
	}
	
	protected void validateUniqueRelationshipRoleNames(IValidationContext 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, IValidationContext.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(IValidationContext 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, IMessagePrefixEjb20Constants.CHKJ2814, IValidationContext.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, IMessagePrefixEjb20Constants.CHKJ2843, IValidationContext.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, IMessagePrefixEjb20Constants.CHKJ2842, IValidationContext.WARNING, element, this);
							vc.addMessage(message);
						}
					}
				}
			}
			else {
				// error
				IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2844, IValidationContext.WARNING, element, this);
				vc.addMessage(message);
			}
		}

		return hasValidMethod;
	}

	protected void validateClientJAR(IValidationContext 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, IMessagePrefixEjb20Constants.CHKJ2875, IValidationContext.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;
		}
	}
}
