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

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.jem.java.Field;
import org.eclipse.jem.java.JavaClass;
import org.eclipse.jem.java.JavaHelpers;
import org.eclipse.jem.java.JavaParameter;
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.ejb.EnterpriseBean;
import org.eclipse.wst.validation.internal.core.ValidationException;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;


/**
 * @version 1.0
 * @author
 */
public abstract class ATypeVRule extends AValidationRule implements IClassVRule, IEJBType {
	private static final int NO_FIELDS = 0;

	private long _methodList = NO_METHODS;
	private long _fieldList = NO_FIELDS;

	public final void validate(IEJBValidationContext vc, Object targetParent, Object target) throws ValidationException {
		vc.subtask(IEJBValidatorConstants.STATUS_VALIDATING, new String[]{((JavaClass) target).getJavaName()});

		Logger logger = vc.getMsgLogger();
		if (logger != null && logger.isLoggingLevel(Level.FINEST)) {
			LogEntry entry = vc.getLogEntry();
			entry.setSourceID("EJB20Validator - validate"); //$NON-NLS-1$
			entry.setText(getClass().getName() + "::validate(" + targetParent + ", " + target); //$NON-NLS-1$ //$NON-NLS-2$
			logger.write(Level.FINEST, entry);
		}

		try {
			vc.terminateIfCancelled();

			EnterpriseBean bean = (EnterpriseBean) targetParent;
			JavaClass clazz = (JavaClass) target;

			try {
				//clean up old reflection error on the clazz that is getting validated
				vc.removeMessages(clazz);
				// Check that all of the types in the bean reflected correctly,
				// and that the types' parents reflected correctly too.
				ValidationRuleUtility.isValidTypeHierarchy(bean, clazz);
			} catch (InvalidInputException exc) {
				reflectionError(vc, bean, clazz);
				return;
			}

			if (ValidationRuleUtility.isUnnamedPackage(clazz.getJavaPackage())) {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2041, IEJBValidationContext.INFO, bean, clazz, this);
				vc.addMessage(message);
			}

			try {
				validate(vc, bean, clazz);
				vc.terminateIfCancelled();

				List[] methodsExtendedList = getMethodsExtended(vc, bean, clazz);
				validate(vc, bean, clazz, clazz.listMethodExtended(), methodsExtendedList);
				vc.terminateIfCancelled();

				List[] fieldsExtendedList = getFieldsExtended(vc, bean, clazz);
				validate(vc, bean, clazz, clazz.listFieldExtended(), fieldsExtendedList);
				vc.terminateIfCancelled();

				validateSupertypes(vc, bean, clazz);
				vc.terminateIfCancelled();

				validateMethodsWhichMustExist(vc, bean, clazz);
				vc.terminateIfCancelled();
			} catch (InvalidInputException exc) {
				reflectionError(vc, bean, clazz);
				return;
			}
		} catch (ValidationCancelledException exc) {
			// remove any existing messages since they may be faulty
		}
	}

	protected final void validate(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Field[] fields, List[] fieldsExtendedLists) throws ValidationException {
		try {
			vc.terminateIfCancelled();

			Field field = null;
			for (int i = 0; i < fields.length; i++) {
				vc.terminateIfCancelled();
				field = fields[i];
				if (field == null) {
					Logger logger = vc.getMsgLogger();
					if (logger != null && logger.isLoggingLevel(Level.FINE)) {
						LogEntry entry = vc.getLogEntry();
						entry.setSourceID("EJB20Validator - validate fields"); //$NON-NLS-1$
						entry.setText("A field is null on " + clazz.getQualifiedName()); //$NON-NLS-1$
						logger.write(Level.FINE, entry);
					}
					continue;
				}
				try {
					Logger logger = vc.getMsgLogger();
					if (logger.isLoggingLevel(Level.FINEST)) {
						LogEntry entry = vc.getLogEntry();
						entry.setSourceID("EJB20Validator - validate fields"); //$NON-NLS-1$
						entry.setText("Validating field " + field.getName() + "on clazz " + clazz + " and isValid returns " + isValid(bean, clazz, field)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
						logger.write(Level.FINEST, entry);
					}

					if (isValid(bean, clazz, field)) {
						register(vc, bean, clazz, field, fieldsExtendedLists);
						validate(vc, bean, clazz, field, fieldsExtendedLists);
					}
				} catch (InvalidInputException e) {
					reflectionWarning(vc, bean, clazz, field, e);
				}
			}
			vc.terminateIfCancelled();
		} catch (ValidationCancelledException exc) {
			// remove any existing messages since they may be faulty
		}

	}

	protected final boolean isValid(EnterpriseBean bean, JavaClass clazz, Method method, List[] methodsExtendedLists) throws InvalidInputException {
		if (isOwnedByBase(bean, method)) {
			return false;
		}

		return ((getMethodType(bean, clazz, method, methodsExtendedLists) & EXCLUDED_METHOD) != EXCLUDED_METHOD);
	}

	protected final boolean isOwnedByBase(EnterpriseBean bean, Field field) throws InvalidInputException {
		if (field == null) {
			return false;
		}

		long[] baseTypes = getBaseTypes();
		if (baseTypes == null) {
			// no parents
			return false;
		}

		for (int i = 0; i < baseTypes.length; i++) {
			if (ClassUtility.getUtility().isClassType(bean, field.getJavaClass(), baseTypes[i])) {
				return true;
			}
		}
		return false;
	}

	protected final boolean isOwnedByBase(EnterpriseBean bean, Method method) throws InvalidInputException {
		if (method == null) {
			return false;
		}

		long[] baseTypes = getBaseTypes();
		if (baseTypes == null) {
			// no parents
			return false;
		}

		for (int i = 0; i < baseTypes.length; i++) {
			if (ClassUtility.getUtility().isClassType(bean, method.getJavaClass(), baseTypes[i])) {
				return true;
			}
		}
		return false;
	}

	protected final boolean isValid(EnterpriseBean bean, JavaClass clazz, Field field) throws InvalidInputException {
		if (isOwnedByBase(bean, field)) {
			return false;
		}

		return ((getFieldType(bean, clazz, field) & EXCLUDED_FIELD) != EXCLUDED_FIELD);
	}

	protected final void validate(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method[] methods, List[] methodsExtendedLists) throws ValidationException {
		try {
			vc.terminateIfCancelled();

			Method method = null;
			for (int i = 0; i < methods.length; i++) {
				vc.terminateIfCancelled();
				method = methods[i];
				if (method == null) {
					// No point adding a validation message, because the user can't do anything.
					// Log this condition.
					Logger logger = vc.getMsgLogger();
					if (logger != null && logger.isLoggingLevel(Level.FINE)) {
						LogEntry entry = vc.getLogEntry();
						entry.setSourceID("EJB20Validator - validate methods"); //$NON-NLS-1$
						entry.setText("On " + clazz.getQualifiedName() + ", there is a null method."); //$NON-NLS-1$ //$NON-NLS-2$
						logger.write(Level.FINE, entry);
					}
					continue;
				}
				try {
					Logger logger = vc.getMsgLogger();
					if (logger.isLoggingLevel(Level.FINEST)) {
						LogEntry entry = vc.getLogEntry();
						entry.setSourceID("EJB20Validator - validate methods"); //$NON-NLS-1$
						entry.setText("Validating method " + method.getMethodElementSignature() + " on clazz " + clazz + " and isValid returns " + isValid(bean, clazz, method, methodsExtendedLists)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
						logger.write(Level.FINEST, entry);
					}

					if (isValid(bean, clazz, method, methodsExtendedLists)) {
						register(vc, bean, clazz, method, methodsExtendedLists);
						if (isMethodAllowedToExist(bean, clazz, method, methodsExtendedLists)) {
							validate(vc, bean, clazz, method, methodsExtendedLists);
						} else {
							validateMethodWhichMustNotExist(vc, bean, clazz, method, methodsExtendedLists);
						}
					} else {
						if (!isOwnedByBase(bean, method)) {
							if ((MethodUtility.getUtility().getMethodTypeId(bean, clazz, method, methodsExtendedLists, this) & EXCLUDED_METHOD) == EXCLUDED_METHOD) {
								// unidentified method excluded
								IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb20Constants.CHKJ2502, IEJBValidationContext.INFO, bean, clazz, method, new String[]{method.getName()}, this);
								vc.addMessage(message);
							}
						}
					}
				} catch (InvalidInputException e) {
					reflectionWarning(vc, bean, clazz, method, e);
				}

			}
			vc.terminateIfCancelled();
		} catch (ValidationCancelledException exc) {
			// remove any existing messages since they may be faulty
		}

	}

	public final void register(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Field field, List[] fieldsExtendedList) throws InvalidInputException, ValidationCancelledException, ValidationException {
		_fieldList = (_fieldList | getFieldType(bean, clazz, field));
	}

	private boolean isDefaultConstructor(long methodType) {
		return ((methodType & IMethodAndFieldConstants.CONSTRUCTOR_NOPARM) == IMethodAndFieldConstants.CONSTRUCTOR_NOPARM);
	}

	private boolean doesPublicDefaultConstructorExist() {
		if ((_methodList & IMethodAndFieldConstants.CONSTRUCTOR_NOPARM) == IMethodAndFieldConstants.CONSTRUCTOR_NOPARM) {
			return true;
		}

		return false;
	}

	private boolean isDefaultConstructorInsertedByCompiler() {
		// If the default constructor is not in the list, and if there are no constructors,
		// the Java compiler will insert a default constructor.
		if ((_methodList & IMethodAndFieldConstants.CONSTRUCTOR) == IMethodAndFieldConstants.CONSTRUCTOR) {
			// There is a constructor, so return false.
			return false;
		}

		return true;
	}

	protected final boolean isMethodAllowedToExist(EnterpriseBean bean, JavaClass clazz, Method method, List[] methodsExtendedLists) {
		long[] methods = getMethodsWhichMustNotExist();
		if (methods != null) {
			for (int i = 0; i < methods.length; i++) {
				long methodType = methods[i];
				long existingMethodType = MethodUtility.getUtility().getMethodTypeId(bean, clazz, method, methodsExtendedLists, this);
				if ((existingMethodType & methodType) == methodType) {
					return false;
				}
			}
		}
		return true;
	}

	/*
	 * @see IValidationRule#reset()
	 */
	public void validateMethodsWhichMustExist(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz) throws InvalidInputException, ValidationCancelledException, ValidationException {
		long[] methods = getMethodsWhichMustExist();
		if (methods != null) {
			for (int i = 0; i < methods.length; i++) {
				long methodType = methods[i];
				boolean emitWarning = false;
				if (isDefaultConstructor(methodType)) {
					if (!doesPublicDefaultConstructorExist() && !isDefaultConstructorInsertedByCompiler()) {
						emitWarning = true;
					}
				} else {
					emitWarning = !exists(methodType);
				}

				if (emitWarning) {
					// IWAD4041 = This class must define a public constructor which takes no
					// parameters. Read section 7.10.1 of the EJB 2.0 specification.
					// IWAD4142 = {0} must exist. Read section 10.5.2 of the EJB 2.0 specification.
					// IWAD4173 = {0} must exist. Read section 10.6.2 of the EJB 2.0 specification.
					// IWAD4271 = {0} must exist. Read section 12.1.4.1 of the EJB 2.0
					// specification.
					// IWAD4290 = {0} must exist. Read section 12.2.2 of the EJB 2.0 specification.
					// IWAD4388 = {0} must exist. Read section 15.7.2 of the EJB 2.0 specification.
					IMethodType mType = MethodUtility.getUtility().getMethodType(methodType);
					if (mType == null) {
						// ummmm....oops. This case should never happen.
						Logger logger = vc.getMsgLogger();
						if (logger != null && logger.isLoggingLevel(Level.FINEST)) {
							LogEntry entry = vc.getLogEntry();
							entry.setSourceID("EJB20Validator - validate methods which must exist"); //$NON-NLS-1$
							entry.setText("Method type is null: " + methodType); //$NON-NLS-1$
							logger.write(Level.FINEST, entry);
						}
						continue;
					}

					IMessage message = MessageUtility.getUtility().getMessage(vc, mType.getMessageId_messageMissing(), IEJBValidationContext.WARNING, bean, clazz, new String[]{mType.getMethodName(bean, clazz, null)}, this);
					vc.addMessage(message);
				}
			}
		}
	}

	public final void validateMethodWhichMustNotExist(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method, List[] methodsExtendedLists) throws InvalidInputException, ValidationCancelledException, ValidationException {
		IMethodType mType = MethodUtility.getUtility().getMethodType(bean, clazz, method, methodsExtendedLists, this);
		if (mType == null) {
			// what happened?
			Logger logger = vc.getMsgLogger();
			if (logger != null && logger.isLoggingLevel(Level.FINEST)) {
				LogEntry entry = vc.getLogEntry();
				entry.setSourceID("EJB20Validator - validate method which must not exist"); //$NON-NLS-1$
				entry.setText("Method type is null: " + MethodUtility.getUtility().getMethodType(bean, clazz, method, methodsExtendedLists, this)); //$NON-NLS-1$
				logger.write(Level.FINEST, entry);
			}
			return;
		}


		IMessage message = MessageUtility.getUtility().getMessage(vc, mType.getMessageId_messageExists(), IEJBValidationContext.INFO, bean, clazz, method, new String[]{mType.getMethodName(bean, clazz, method)}, this);
		vc.addMessage(message);
	}

	public abstract long getFieldType(EnterpriseBean bean, JavaClass clazz, Field field);

	public abstract long[] getBaseTypes();

	public abstract int getMessageRemoteExceptionSeverity(); // is a missing (or present)
															 // RemoteException a warning or an
															 // error? See ILocalType and
															 // IRemoteType.

	public final long getMethodType(EnterpriseBean bean, JavaClass clazz, Method method, List[] methodsExtendedList) {
		if (method == null) {
			return EXCLUDED_METHOD;
		}
		long id = MethodUtility.getUtility().getMethodTypeId(bean, clazz, method, methodsExtendedList, this);
		if ((id & CLINIT) == CLINIT) {
			return EXCLUDED_METHOD;
		}
		return id;
	}

	public final void register(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method, List[] methodsExtendedList) throws InvalidInputException, ValidationCancelledException, ValidationException {
		_methodList = (_methodList | MethodUtility.getUtility().getMethodTypeId(bean, clazz, method, methodsExtendedList, this));
	}

	public final void validateSupertypes(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz) throws InvalidInputException, ValidationCancelledException, ValidationException {
		validateShouldBeSuperTypes(vc, bean, clazz);
		validateShouldNotBeSuperTypes(vc, bean, clazz);
	}

	/**
	 * @param vc
	 * @param bean
	 * @param clazz
	 * @throws InvalidInputException
	 */
	protected void validateShouldNotBeSuperTypes(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz) throws InvalidInputException {
		long[] types;
		// Test for types which can be supertypes, though it's either not recommended or should be
		// coded with caution
		types = getShouldNotBeSupertypes();
		if (types != null) {
			for (int i = 0; i < types.length; i++) {
				JavaHelpers superType = ClassUtility.getUtility().getSupertype(bean, types[i]);
				if (superType == null) {
					// no supertype
					continue;
				}

				if (ValidationRuleUtility.isAssignableFrom(clazz, superType)) {
					// IWAD4179 = Because this class implements {0}, "this" must not be passed as a
					// method argument or result. Read section 10.6.2 of the EJB 2.0 specification.
					// IWAD4292 = Because {0} implements {1}, "this" must not be passed as a method
					// argument or result. Read section 12.2.2 of the EJB 2.0 specification.
					// IWAD4043 = Because {0} implements {1}, "this" must not be passed as a method
					// argument or result. Read section 7.10.2 of the EJB 2.0 specification.
					IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2040, IEJBValidationContext.INFO, bean, clazz, this);
					vc.addMessage(message);
				}
			}
		}
	}

	/**
	 * @param vc
	 * @param bean
	 * @param clazz
	 * @throws InvalidInputException
	 */
	protected void validateShouldBeSuperTypes(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz) throws InvalidInputException {
		long[] types = getSupertypes();
		if (types != null) {
			for (int i = 0; i < types.length; i++) {
				JavaHelpers superType = ClassUtility.getUtility().getSupertype(bean, types[i]);
				if (superType == null) {
					// no supertype
					continue;
				}

				if (!ValidationRuleUtility.isAssignableFrom(clazz, superType)) {
					// IWAD4026 = This class must implement javax.ejb.SessionBean. Read section
					// 7.5.1, 7.10.2 of the EJB 2.0 specification.
					// IWAD4379 = This class must implement javax.ejb.MessageDrivenBean. Read
					// section 15.4.1, 15.7.2 of the EJB 2.0 specification.
					// IWAD4380 = This class must implement javax.jms.MessageListener. Read section
					// 15.4.1, 15.7.2 of the EJB 2.0 specification.
					// IWAD4170 = This class must implement java.ejb.EntityBean. Read section 10.6.2
					// of the EJB 2.0 specification.
					// IWAD4286 = This class must implement java.ejb.EntityBean. Read section 12.2.2
					// of the EJB 2.0 specification.
					IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2017, IEJBValidationContext.ERROR, bean, clazz, new String[]{superType.getJavaName()}, this);
					vc.addMessage(message);
				}
			}
		}
	}

	public void reset() {
		super.reset();
		_methodList = NO_METHODS;
		_fieldList = NO_FIELDS;
	}

	protected final void reflectionError(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz)  {
		IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2907, IEJBValidationContext.ERROR, bean, clazz, new String[]{clazz.getQualifiedName()}, this);
		vc.addMessage(message);
	}

	protected final void reflectionWarning(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Field field, InvalidInputException exc)  {
		vc.removeMessages(field);
		vc.removeMessages(clazz, field.getName());
		IMessage message = getReflectionWarning(vc, exc, bean, clazz, field);
		vc.addMessage(message);
	}

	protected final void reflectionWarning(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method, InvalidInputException exc)  {
		vc.removeMessages(method);
		vc.removeMessages(clazz, method.getSignature());
		IMessage message = getReflectionWarning(vc, exc, bean, clazz, method);
		vc.addMessage(message);
	}

	protected final IMessage getReflectionWarning(IEJBValidationContext vc, InvalidInputException exc, EnterpriseBean bean, JavaClass clazz, EObject fieldOrMethod) {
		if (exc == null) {
			return null;
		}

		JavaClass badClazz = exc.getJavaClass();
		String typeName = (badClazz == null) ? "?" : badClazz.getQualifiedName(); //$NON-NLS-1$
		IMessage message = null;

		if (fieldOrMethod instanceof Field) {
			String name = ((Field) fieldOrMethod).getName();
			message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2433, IEJBValidationContext.WARNING, bean, clazz, (Field) fieldOrMethod, new String[]{name, typeName}, this);
		} else if (fieldOrMethod instanceof Method) {
			String name = ((Method) fieldOrMethod).getMethodElementSignature();
			message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2433, IEJBValidationContext.WARNING, bean, clazz, (Method) fieldOrMethod, new String[]{name, typeName}, this);
		} else {
			String name = ((XMIResource) fieldOrMethod.eResource()).getID(fieldOrMethod);
			message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2433, IEJBValidationContext.WARNING, bean, clazz, new String[]{name, typeName}, this);
		}
		if (badClazz == null) {
			Logger logger = vc.getMsgLogger();
			if (logger != null && logger.isLoggingLevel(Level.FINEST)) {
				LogEntry entry = vc.getLogEntry();
				entry.setSourceID("getMessageId(IEJBValidationContext, InvalidInputException, boolean)"); //$NON-NLS-1$
				entry.setText("InvalidInputException thrown on unknown class"); //$NON-NLS-1$
				entry.setTargetException(exc);
				logger.write(Level.FINEST, entry);
			}
		}

		return message;
	}


	public final JavaClass getComponentInterface(EnterpriseBean bean) {
		if ((isRemote() & IEJBType.REMOTE) == IEJBType.REMOTE) {
			return bean.getRemoteInterface();
		}
		return bean.getLocalInterface();
	}

	public final boolean exists(long methodType) {
		return ((_methodList & methodType) == methodType);
	}

	public final JavaClass getHomeInterface(EnterpriseBean bean) {
		if ((isRemote() & IEJBType.REMOTE) == IEJBType.REMOTE) {
			return bean.getHomeInterface();
		}
		return bean.getLocalHomeInterface();
	}

	public boolean followRemoteExceptionRules(EnterpriseBean bean, Method method) throws InvalidInputException, ValidationCancelledException {
		if ((isRemote() & IEJBType.REMOTE) == IEJBType.REMOTE) {
			// must throw RemoteException or one of its parents (IOException or Exception)
			return ValidationRuleUtility.throwsRemoteExceptionOrParent(bean, method);
		} else if ((isRemote() & IEJBType.LOCAL) == IEJBType.LOCAL) {
			// must not throw RemoteException
			return ValidationRuleUtility.doesNotThrowRemoteException(bean, method);
		}

		return true;
	}

	public final void validateRMI_IIOPTypeRules(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method, List[] methodsExtendedList, boolean checkReturnType) throws InvalidInputException {
		if ((isRemote() & IEJBType.REMOTE) == IEJBType.REMOTE) {
			JavaParameter[] parms = method.listParametersWithoutReturn();

			for (int i = 0; i < parms.length; i++) {
				JavaParameter parm = parms[i];
				if (!ValidationRuleUtility.isLegalRMI_IIOPType(bean, parm.getJavaType())) {
					IMethodType mt = MethodUtility.getUtility().getMethodType(bean, clazz, method, methodsExtendedList, this);
					if (mt == null) {
						// log
					} else {
						IMessage message = MessageUtility.getUtility().getMessage(vc, mt.getMessageId_messageRMI_IIOPParm(), IEJBValidationContext.INFO, bean, clazz, method, new String[]{parm.getJavaType().getJavaName()}, this); // Can't
																																																								  // use
																																																								  // the
																																																								  // name
																																																								  // of
																																																								  // the
																																																								  // field,
																																																								  // because
																																																								  // when
																																																								  // it's
																																																								  // the
																																																								  // return
																																																								  // type
																																																								  // of
																																																								  // the
																																																								  // method,
																																																								  // it's
																																																								  // confusing
																																																								  // to
																																																								  // see
																																																								  // "result"
																																																								  // as
																																																								  // the
																																																								  // name
																																																								  // of
																																																								  // the
																																																								  // field.
						vc.addMessage(message);
					}
				}
			}

			if (checkReturnType) {
				if (!ValidationRuleUtility.isLegalRMI_IIOPType(bean, method.getReturnType())) {
					IMethodType mt = MethodUtility.getUtility().getMethodType(bean, clazz, method, methodsExtendedList, this);
					if (mt == null) {
						// log
					} else {
						IMessage message = MessageUtility.getUtility().getMessage(vc, mt.getMessageId_messageRMI_IIOPParm(), IEJBValidationContext.INFO, bean, clazz, method, new String[]{method.getReturnType().getJavaName()}, this); // Can't
																																																									  // use
																																																									  // the
																																																									  // name
																																																									  // of
																																																									  // the
																																																									  // field,
																																																									  // because
																																																									  // when
																																																									  // it's
																																																									  // the
																																																									  // return
																																																									  // type
																																																									  // of
																																																									  // the
																																																									  // method,
																																																									  // it's
																																																									  // confusing
																																																									  // to
																																																									  // see
																																																									  // "result"
																																																									  // as
																																																									  // the
																																																									  // name
																																																									  // of
																																																									  // the
																																																									  // field.
						vc.addMessage(message);
					}
				}
			}
		} else {
			// don't need to check
			return;
		}
	}

	public final boolean followRMI_IIOPInheritanceRules(EnterpriseBean bean, JavaClass clazz) {
		if ((isRemote() & IEJBType.REMOTE) == IEJBType.REMOTE) {
			return ValidationRuleUtility.isLegalRMI_IIOPInheritance(clazz);
		}
		return true;
	}

	public void validateSerialVersionUID(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Field field) {
		/*
		 * For now, do nothing. In future, check if the field is public & static?
		 */
	}

}
