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

/**
 * @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(ValidationException e) {
					throw e;
				}
				catch(Throwable exc) {
					addInternalErrorMessage(vc, exc);
				}
				finally {
					EJBValidationRuleFactory.getFactory().release(vRule);
				}
				
			}
			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);
				}
				
				if( oppositeRole == null )
					continue;
				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;
		}
	}
}
