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

import org.eclipse.jem.java.Field;
import org.eclipse.jem.java.JavaClass;
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;

/**
 * Insert the type's description here.
 * Creation date: (1/5/01 11:51:09 AM)
 * @author: Administrator
 */
public abstract class AValidateEJB extends AValidationRule {
	private List roleMethodNames;
	
	@Override
	public void reset() {
		super.reset();
		if(roleMethodNames != null) {
			roleMethodNames.clear();
			roleMethodNames = null; // in this case, clearing the list isn't enough, because it is legal to have zero role names. Must be null or we'll keep trying to reload the role names just because there are zero role names.
		}
	}
	
	/**
	 * Insert the method's description here.
	 * Creation date: (9/5/2001 12:36:39 PM)
	 * @return java.util.List
	 */
	protected List getRoleMethodNames(IEJBValidationContext vc, EnterpriseBean bean) {
		try {
			if (roleMethodNames == null && bean != null) {
				roleMethodNames = getRoleMethodNamesExtended(bean);
			}
			return roleMethodNames;
		}
		catch (Throwable exc) {
			Logger logger = vc.getMsgLogger();
			if (logger != null && logger.isLoggingLevel(Level.FINER)) {
				logger.write(Level.FINER, exc);
			}
			return Collections.EMPTY_LIST;
		}
	}
	
	protected boolean isEjbRelationshipRoleMethod(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method) {
		if (method == null)
			return false;
		List aRoleMethodNames = getRoleMethodNames(vc, bean);
		if(aRoleMethodNames != null && !aRoleMethodNames.isEmpty())
		  return aRoleMethodNames.contains(method.getName());
		return false;
	}
	
	/**
	 * Return true if the field can, and should, be validated.
	 * Filter out faulty fields (i.e., null), and fields which
	 * belong to the base type, whatever that is. (e.g. java.lang.Object)
	 */
	protected boolean isValid(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Field field, List[] fieldsExtendedLists) throws InvalidInputException {
		// The following call checks if the type reflected properly
		ValidationRuleUtility.isValidType(ValidationRuleUtility.getType(field));

		if (field.getName().equals(IMethodAndFieldConstants.FIELDNAME_SERIALVERSIONUID)) {
			return false;
		}

		return true;
	}
	
	/**
	 * Return true if the method can, and should, be validated.
	 * Filter out faulty methods (i.e., null), and methods which
	 * belong to the base type, whatever that is. (e.g. java.lang.Object)
	 */
	protected boolean isValid(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method, List[] methodsExtendedList) throws InvalidInputException {
		if (method == null) {
			throw new InvalidInputException();
		}
		return true;
	}

	/**
	 * This method actually does the validation. Since many of the classes do
	 * not validate fields now, implement this method as a no-op so that the
	 * classes compile. 
	 */
	public void primValidate(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Field field) throws InvalidInputException {
		//Default
	}
	
	/**
	 * This method actually does the validation.
	 */
	public abstract void primValidate(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method ejbMethod) throws InvalidInputException;
	
	/**
	 * This method does the actual checking (if ejbMethod exists).
	 */
	protected abstract void primValidateExistence(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method ejbMethod) throws InvalidInputException;
	
	protected abstract List[] getMethodsExtended(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz);
	protected abstract List[] getFieldsExtended(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz);
	
	protected final void reflectionError(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz)  {
		vc.removeMessages(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 e) {
		// One of two cases where we care if the type is on this class or not (i.e., not leaving it up to MessageUtility)
		String[] msgParm = null;
		String javaClassName = (e.getJavaClass() == null) ? "?" : e.getJavaClass().getQualifiedName(); //$NON-NLS-1$
		if(ValidationRuleUtility.onClass(clazz, field)) {
			msgParm = new String[] {String.valueOf(field.getName()), String.valueOf(javaClassName)};
		}
		else {
			msgParm = new String[] {javaClassName}; // MessageUtility will substitute in the name of the field
		}
		IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2433, IEJBValidationContext.WARNING, bean, clazz, field, msgParm, this);
		vc.addMessage(message);
	}
	
	protected final void reflectionWarning(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method, InvalidInputException e) {
		// One of two cases where we care if the type is on this class or not (i.e., not leaving it up to MessageUtility)
		String[] msgParm = null;
		String javaClassName = (e.getJavaClass() == null) ? "?" : e.getJavaClass().getQualifiedName(); //$NON-NLS-1$
		if(ValidationRuleUtility.onClass(clazz, method)) {
			msgParm = new String[] {method.getMethodElementSignature(), javaClassName};
		}
		else {
			msgParm = new String[] {javaClassName}; // MessageUtility will substitute in the name of the field
		}
		IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2433, IEJBValidationContext.WARNING, bean, clazz, method, msgParm, this);
		vc.addMessage(message);
	}
	
	public final void validate(IEJBValidationContext vc, Object targetParent, Object target) throws ValidationException {
		vc.terminateIfCancelled();
		
		EnterpriseBean bean = (EnterpriseBean)targetParent;
		JavaClass clazz = (JavaClass)target;
		
		try {
			// check if all of the types in the bean reflected properly
			ValidationRuleUtility.isValidTypeHierarchy(bean, clazz);
			
			vc.subtask(IEJBValidatorConstants.STATUS_VALIDATING, new String[]{clazz.getQualifiedName()});
			validateClass(vc, bean, clazz);
			validateMethods(vc, bean, clazz);
			validateFields(vc, bean, clazz);
		}
		catch(InvalidInputException e) {
			reflectionError(vc, bean, clazz);
			return;
		}
		catch(ValidationCancelledException e) {
			throw e;
		}
	}

	/**
	 * This method should be called to avoid validating a Field more
	 * than once.  This is not used for checking the existence of a field.
	 */
	public final void validate(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Field field, List[] fieldsExtendedList) throws InvalidInputException {
		if (isValid(vc, bean, clazz, field, fieldsExtendedList)) {
			primValidate(vc, bean, clazz, field);
		}
	}
	
	/**
	 * This method should be called to avoid validating a Method more
	 * than once.  This is not used for checking the existence of a method.
	 */
	public final void validate(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method ejbMethod, List[] methodsExtendedList) throws InvalidInputException {
		if (isValid(vc, bean, clazz, ejbMethod, methodsExtendedList)) {
			primValidate(vc, bean, clazz, ejbMethod);
		}
	}
	/**
	 * Checks to see if @ejbMethod is one of the required methods.
	 */
	protected final void validateExistence(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method ejbMethod, List[] methodsExtendedList) throws InvalidInputException {
		if (isValid(vc, bean, clazz, ejbMethod, methodsExtendedList)) {
			primValidateExistence(vc, bean, clazz, ejbMethod);
		}
	}
	
	public void validateClass(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz) throws InvalidInputException {
		//Default
	}
	
	public final void validateFields(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz)  throws ValidationCancelledException, InvalidInputException, ValidationException {
		vc.terminateIfCancelled();

		// Whenever looping over an entire list, always use an 
		// iterator instead of a for loop, for performance reasons. 
		// If the list is an instance of a linked list, for example,
		// the get(i) call can take  a long time. 
		List fields = clazz.getFieldsExtended();
		Iterator iterator = fields.iterator();
		Field field = null;
		List[] fieldsExtendedList = getFieldsExtended(vc, bean, clazz);
		while (iterator.hasNext()) {
			vc.terminateIfCancelled();
			field = (Field) iterator.next();
			if (field == null) {
				Logger logger = vc.getMsgLogger();
				if (logger != null && logger.isLoggingLevel(Level.FINEST)) {
					LogEntry entry = vc.getLogEntry();
					entry.setSourceID("AValidateEJB.validateFields()"); //$NON-NLS-1$
					entry.setText("A field is null on " + clazz); //$NON-NLS-1$
					logger.write(Level.FINEST, entry);
				}
				continue;
			}
			try {
				validate(vc, bean, clazz, field, fieldsExtendedList);
			}
			catch (InvalidInputException e) {
				reflectionWarning(vc, bean, clazz, field, e);
			}
		}
		vc.terminateIfCancelled();
	}
	
	/**
	 * Verifies that a given method is RMI legal.
	 * This means that their argument and return values must be of valid types 
	 * for RMI/IIOP, and their throws clause must include the java.rmi.RemoteException.
	 */
	public final void validateLegalRMIMethod(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method) throws InvalidInputException {
		vc.terminateIfCancelled();
		validateLegalRMIMethodWithoutExceptions(vc, bean, clazz, method);
		validateLegalRMIMethodExceptions(vc, bean, clazz, method);
	}
	
	/**
	 * Verifies that a given method is RMI legal.
	 * This means that their argument and return values must be of valid types 
	 * for RMI/IIOP, and their throws clause must include the java.rmi.RemoteException.
	 */
	public final void validateLegalRMIMethodArguments(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method) throws InvalidInputException {
		vc.terminateIfCancelled();

		if (method == null) {
			return;
		}

		JavaParameter[] args = method.listParametersWithoutReturn();
		for (int i = 0; i < args.length; i++) {
			vc.terminateIfCancelled();

			if (!ValidationRuleUtility.isLegalRMI_IIOPType(bean, args[i].getJavaType())) {
				IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2413, IEJBValidationContext.INFO, bean, clazz, method, new String[]{args[i].getQualifiedName()}, this);
				vc.addMessage(message);
			}
		}
	}
	
	/**
	 * Verifies that a given method is RMI legal.
	 * This means that their argument and return values must be of valid types 
	 * for RMI/IIOP, and their throws clause must include the java.rmi.RemoteException.
	 */
	public final void validateLegalRMIMethodExceptions(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method) throws InvalidInputException {
		vc.terminateIfCancelled();

		if (method == null) {
			return;
		}

		if (!ValidationRuleUtility.throwsRemoteExceptionOrParent(bean, method)) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2414, IEJBValidationContext.ERROR, bean, clazz, method, new String[]{ITypeConstants.CLASSNAME_JAVA_RMI_REMOTEEXCEPTION}, this);
			vc.addMessage(message);
		}
	}
	
	/**
	 * Verifies that a given method is RMI legal, but doesn't check the exceptions.
	 * This means that the method's argument and return values must be of valid types 
	 * for RMI/IIOP.
	 */
	public final void validateLegalRMIMethodReturnType(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method) throws InvalidInputException {
		vc.terminateIfCancelled();
		if (method == null) {
			return;
		}

		if (!ValidationRuleUtility.isLegalRMI_IIOPType(bean, method.getReturnType())) {
			IMessage message = MessageUtility.getUtility().getMessage(vc, IMessagePrefixEjb11Constants.CHKJ2412, IEJBValidationContext.INFO, bean, clazz, method, this);
			vc.addMessage(message);
		}
	}
	
	/**
	 * Verifies that a given method is RMI legal, but doesn't check the exceptions.
	 * This means that the method's argument and return values must be of valid types 
	 * for RMI/IIOP.
	 */
	public final void validateLegalRMIMethodWithoutExceptions(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz, Method method) throws InvalidInputException {
		vc.terminateIfCancelled();
		validateLegalRMIMethodArguments(vc, bean, clazz, method);
		validateLegalRMIMethodReturnType(vc, bean, clazz, method);
	}
	
	/**
	 * Final check to see if required methods were detected.
	 */
	protected abstract void validateMethodExists(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz) throws InvalidInputException;
	
	public final void validateMethods(IEJBValidationContext vc, EnterpriseBean bean, JavaClass clazz)  throws ValidationCancelledException, InvalidInputException, ValidationException {
		vc.terminateIfCancelled();

		// Whenever looping over an entire list, always use an 
		// iterator instead of a for loop, for performance reasons. 
		// If the list is an instance of a linked list, for example,
		// the get(i) call can take  a long time. 
		Method[] ejbMethods = clazz.listMethodExtended();
		Method method = null;
		List[] methodsExtendedList = getMethodsExtended(vc, bean, clazz);
		for(int i=0; i<ejbMethods.length; i++) {
			vc.terminateIfCancelled();
			method = ejbMethods[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.FINEST)) {
					LogEntry entry = vc.getLogEntry();
					entry.setSourceID("AValidateEJB.validateMethods()"); //$NON-NLS-1$
					entry.setText("On " + clazz + ", there is a null method."); //$NON-NLS-1$  //$NON-NLS-2$
					logger.write(Level.FINEST, entry);
				}
				continue;
			}
			try {
				validateExistence(vc, bean, clazz, method, methodsExtendedList);
				validate(vc, bean, clazz, method, methodsExtendedList);
			}
			catch (InvalidInputException e) {
				reflectionWarning(vc, bean, clazz, method, e);
			}
		}
		validateMethodExists(vc, bean, clazz);
		vc.terminateIfCancelled();
	}
}
