/*******************************************************************************
 * 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.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jem.java.JavaClass;
import org.eclipse.jem.java.JavaRefFactory;
import org.eclipse.jst.j2ee.common.EnvEntry;
import org.eclipse.jst.j2ee.common.SecurityRole;
import org.eclipse.jst.j2ee.common.SecurityRoleRef;
import org.eclipse.jst.j2ee.common.internal.impl.EJBLocalRefImpl;
import org.eclipse.jst.j2ee.common.internal.impl.EjbRefImpl;
import org.eclipse.jst.j2ee.common.internal.impl.ResourceRefImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.EARFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.WARFile;
import org.eclipse.jst.j2ee.core.internal.plugin.J2EECorePlugin;
import org.eclipse.jst.j2ee.ejb.EnterpriseBean;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.webapplication.AuthConstraint;
import org.eclipse.jst.j2ee.webapplication.ContextParam;
import org.eclipse.jst.j2ee.webapplication.ErrorCodeErrorPage;
import org.eclipse.jst.j2ee.webapplication.ErrorPage;
import org.eclipse.jst.j2ee.webapplication.ExceptionTypeErrorPage;
import org.eclipse.jst.j2ee.webapplication.Filter;
import org.eclipse.jst.j2ee.webapplication.FilterMapping;
import org.eclipse.jst.j2ee.webapplication.FormLoginConfig;
import org.eclipse.jst.j2ee.webapplication.HTTPMethodType;
import org.eclipse.jst.j2ee.webapplication.InitParam;
import org.eclipse.jst.j2ee.webapplication.JSPType;
import org.eclipse.jst.j2ee.webapplication.LoginConfig;
import org.eclipse.jst.j2ee.webapplication.MimeMapping;
import org.eclipse.jst.j2ee.webapplication.SecurityConstraint;
import org.eclipse.jst.j2ee.webapplication.Servlet;
import org.eclipse.jst.j2ee.webapplication.ServletMapping;
import org.eclipse.jst.j2ee.webapplication.SessionConfig;
import org.eclipse.jst.j2ee.webapplication.TagLibRef;
import org.eclipse.jst.j2ee.webapplication.TransportGuaranteeType;
import org.eclipse.jst.j2ee.webapplication.UserDataConstraint;
import org.eclipse.jst.j2ee.webapplication.WebApp;
import org.eclipse.jst.j2ee.webapplication.WebResourceCollection;
import org.eclipse.jst.j2ee.webapplication.WelcomeFile;
import org.eclipse.jst.j2ee.webapplication.WelcomeFileList;
import org.eclipse.wst.common.frameworks.internal.plugin.WTPCommonPlugin;
import org.eclipse.wst.validation.internal.ResourceConstants;
import org.eclipse.wst.validation.internal.ResourceHandler;
import org.eclipse.wst.validation.internal.core.Message;
import org.eclipse.wst.validation.internal.core.ValidationException;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
import org.eclipse.wst.validation.internal.provisional.core.IValidationContext;

// import org.eclipse.jst.j2ee.internal.plugin.nls.ResourceHandler;

public class WarValidator extends J2EEValidator implements WARMessageConstants {
	protected WARFile warFile;
	protected WebApp webDD;
	private Hashtable httpMethods = null;

	// Optional child validators
	// protected WebExtValidator webExtValidator;
	// protected WebBndValidator webBndValidator;


	/**
	 * RelationshipMapValidator constructor comment.
	 */
	public WarValidator() {
		super();
	}

	/**
	 * Will construct a HashTable of roles, and check for duplicates and null entries
	 * 
	 * @return java.util.Hashtable
	 * @param roles
	 *            org.eclipse.emf.common.util.EList
	 */
	public Hashtable getAndValidateSecurityRoles(EList roles) {

		Hashtable secRoles = new Hashtable();
		if (roles.isEmpty())
			return (secRoles);

		Iterator sRoles = roles.iterator();

		while (sRoles.hasNext()) {
			
			if( _reporter.isCancelled() ){
				String msg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED);			
				status = WTPCommonPlugin.createCancelStatus(msg);
			}
			
			SecurityRole role = (SecurityRole) sRoles.next();


			String name = role.getRoleName();
			if (name != null)
				name = name.trim();
			if (name == null || name.equals("")) { //$NON-NLS-1$
				String[] parms = new String[1];
				parms[0] = WARValidationResourceHandler.of_Type_Security_Role_Name_6;
				addError(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms, role);
				continue;
			}
			if (secRoles.get(name) != null) { // Check for dups

				String[] parms = new String[1];
				parms[0] = name;
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_DUPLICATE_ENTRY, parms, role);
				continue;
			}
			secRoles.put(name, "Yea"); //$NON-NLS-1$
		}


		return secRoles;
	}

	/**
	 * <p>
	 * Answer the id of the resource bundle which is used by the receiver.
	 * </p>
	 */
	@Override
	public String getBaseName() {
		return WAR_CATEGORY;
	}

	// Messaging helpers ...

	/**
	 * Returns the name of the Validator, as it should be displayed in the UI.
	 * 
	 * @see J2EEValidator#getName
	 */

	@Override
	public String getName() {
		return WARValidationResourceHandler.Web_Archive_Validator_8;
	}

	// Messaging helpers ...

	/**
	 * Returns the name of the Validator, as it should be displayed in the UI.
	 * 
	 * @see J2EEValidator#getName
	 */

	@Override
	public String getName(Locale locale) {
		return getMessage(null, "webArchiveValidator.name", locale); //$NON-NLS-1$
	}

	/**
	 * This is a utility function used by the validateSecurityConstraints.
	 * 
	 * @return boolean
	 */
	protected boolean isHttpMethod(String method) {


		if (httpMethods == null) { // Need to construct the Hashtable, once
			String[] mList = {
				"GET", //$NON-NLS-1$
				"PUT",  //$NON-NLS-1$
				"HEAD",  //$NON-NLS-1$
				"TRACE",  //$NON-NLS-1$
				"POST",  //$NON-NLS-1$
				"DELETE",  //$NON-NLS-1$
				"OPTIONS", //$NON-NLS-1$
				//WEBDAV
				"ACK",  //$NON-NLS-1$
				"ACL",  //$NON-NLS-1$
				"BASELINE-CONTROL",  //$NON-NLS-1$
				"BIND",  //$NON-NLS-1$
				"BYE",  //$NON-NLS-1$
				"CANCEL",  //$NON-NLS-1$
				"CHECKIN",  //$NON-NLS-1$
				"CHECKOUT",  //$NON-NLS-1$
				"COPY",  //$NON-NLS-1$
				"ERRORRESPONSE",  //$NON-NLS-1$
				"INFO",  //$NON-NLS-1$
				"INVITE",  //$NON-NLS-1$
				"LABEL",  //$NON-NLS-1$
				"LOCK",  //$NON-NLS-1$
				"MERGE",  //$NON-NLS-1$
				"MESSAGE",  //$NON-NLS-1$
				"MKACTIVITY",  //$NON-NLS-1$
				"MKCOL",  //$NON-NLS-1$
				"MKWORKSPACE",  //$NON-NLS-1$
				"MOVE",  //$NON-NLS-1$
				"NOTIFY",  //$NON-NLS-1$
				"PRACK",  //$NON-NLS-1$
				"PROPFIND",  //$NON-NLS-1$
				"PROPPATCH",  //$NON-NLS-1$
				"PROVISIONALRESPONSE",  //$NON-NLS-1$
				"PUBLISH",  //$NON-NLS-1$
				"REBIND",  //$NON-NLS-1$
				"REDIRECTRESPONSE",  //$NON-NLS-1$
				"REGISTER",  //$NON-NLS-1$
				"REPORT",  //$NON-NLS-1$
				"REQUEST",  //$NON-NLS-1$
				"RESPONSE",  //$NON-NLS-1$
				"SEARCH",  //$NON-NLS-1$
				"SUCCESSRESPONSE",  //$NON-NLS-1$
				"UNBIND",  //$NON-NLS-1$
				"UNCHECKOUT",  //$NON-NLS-1$
				"UNLOCK",  //$NON-NLS-1$
				"UPDATE",  //$NON-NLS-1$
				"VERSION-CONTROL"//$NON-NLS-1$
			}; 

			httpMethods = new Hashtable();
			for (int i = 0; i < mList.length; i++)
				httpMethods.put(mList[i], "bla"); //$NON-NLS-1$
		}
		String compare = method.trim();
		return (httpMethods.get(compare) != null);
	}

	/**
	 * WAR validation is driven by 3 prong approach: o XML/DTD validation (this is now handled by
	 * the XML Validator) o Consistent web.xml data entry validation beyond DTD e.g., duplicate
	 * entries, null entries etc. This is also driven by this validator. o web.xml reference to
	 * resources in the "file system". This will not be provided by this validator. In the workbench
	 * this function is already provided by the link builder.
	 * 
	 */
	public void validate() throws ValidationException {
		validateMimeMapping();
		validateContextParameters();
		validateTagLibs();
		validateServletMappings(webDD.getServletMappings());
		validateWelcomeFileList(webDD.getFileList());
		validateErrorPages(webDD.getErrorPages());
		validateSecurityAndServlets();
		validateFilters(webDD.getFilters());
		validateFilterMappings(webDD.getFilterMappings());
		validateRefs();
		validateLoginConfig(webDD.getLoginConfig());
		validateEnvironmentEntries(webDD.getEnvironmentProperties());
		validateOther();
		validate14();
	}

	/**
	 * 
	 */
	private void validate14() {
		int versionId = webDD.getVersionID();
		if (versionId == J2EEVersionConstants.WEB_2_4_ID) {
			validateUrlPattern();
		}
	}

	/**
	 * 
	 */
	private void validateUrlPattern() {
		List servletMappings = webDD.getServletMappings();
		for (int i = 0; i < servletMappings.size(); i++) {
			ServletMapping mapping = (ServletMapping) servletMappings.get(i);
			String urlPattern = mapping.getUrlPattern();
			int newLineChar = urlPattern.indexOf(Character.LINE_SEPARATOR);
			if (newLineChar != -1) {
				String[] parms = new String[2];
				parms[0] = urlPattern;
				parms[1] = mapping.getServlet().getDisplayName();
				addError(WAR_CATEGORY, MESSAGE_URL_PATTERN_END_WITH_CARRAIGE_RETURN, parms, mapping);
			}
		}

	}

	/**
	 * This is the method which performs the validation on the MOF model. <br>
	 * <br>
	 * <code>helper</code> and <code>reporter</code> may not be null. <code>changedFiles</code>
	 * may be null, if a full build is desired. <br>
	 * <br>
	 * <code>helper</code> loads a EObject. The EObject is the root of the MOF model about to be
	 * validated. When this object is traversed, you can reach every element in the MOF model which
	 * needs to be validated. <br>
	 * <br>
	 * <code>reporter</code> is an instance of an IReporter interface, which is used for
	 * interaction with the user. <br>
	 * <br>
	 * <code>changedFiles</code> is an array of file names which have changed since the last
	 * validation. If <code>changedFiles</code> is null, or if it is an empty array, then a full
	 * build is performed. Otherwise, validation on just the files listed in the Vector is
	 * performed.
	 */
	@Override
	public void validate(IValidationContext inHelper, IReporter inReporter) throws ValidationException {
		validateInJob(inHelper, inReporter);
	}
	
	
	@Override
	public IStatus validateInJob(IValidationContext inHelper, IReporter inReporter) throws ValidationException {
		status = super.validateInJob(inHelper, inReporter);
		

		// First remove all previous msg. for this project
		_reporter.removeAllMessages(this, null); // Note the WarHelper will return web.xml with a
													// null object as well

		if( !_reporter.isCancelled()){
			
			warFile = (WARFile) _helper.loadModel(WAR_MODEL_NAME);
			
			try {
				if (warFile != null) {
					webDD = warFile.getDeploymentDescriptor();
					validate();
				} else {
					IMessage errorMsg = new Message(getBaseName(), IMessage.HIGH_SEVERITY, ERROR_INVALID_WAR_FILE);
					status = WTPCommonPlugin.createErrorStatus( errorMsg.getText( getClass().getClassLoader() ));
					throw new ValidationException(errorMsg);
				}
	
			} catch (ValidationException ex) {
				throw ex;
			} catch (Exception e) {
				String[] parms = new String[1];
				parms[0] = e.toString();
				IMessage errorMsg = new Message(getBaseName(), IMessage.HIGH_SEVERITY, ERROR_WAR_VALIDATION_FAILED, parms);
				status = WTPCommonPlugin.createErrorStatus(errorMsg.getText( getClass().getClassLoader() ));
				throw new ValidationException(errorMsg, e);
			}
		}else{
			String msg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED);			
			status = WTPCommonPlugin.createCancelStatus(msg);
		}
		return status;
	}

	/**
	 * This validator can be used for validation when the reporter and helper have been supplied via
	 * the constructor.
	 */
	public void validate(Object aWarFile) throws ValidationException {

		try {
			warFile = (WARFile) aWarFile;
			webDD = warFile.getDeploymentDescriptor();

			validate();

		} catch (Exception e) {
			J2EECorePlugin.logError(e);
			String[] parms = new String[1];
			parms[0] = e.toString();
			IMessage errorMsg = new Message(getBaseName(), IMessage.HIGH_SEVERITY, ERROR_WAR_VALIDATION_FAILED, parms);
			throw new ValidationException(errorMsg);
		}
	}

	/**
	 * The auth-constraint element indicates the user roles that should be permitted access to this
	 * resource collection. The role used here must appear in a security-role-ref element. <!ELEMENT
	 * auth-constraint (description?, role-name*)> The role-name element contains the name of a
	 * security role. <!ELEMENT role-name (#PCDATA)> Creation date: (7/6/2001 3:39:34 PM)
	 * 
	 * @param authConstraint
	 *            org.eclipse.jst.j2ee.internal.webapplication.AuthConstraint
	 */
	public void validateAuthConstraint(AuthConstraint authConstraint, Hashtable secRoles) {

		EList roleList = authConstraint.getRoles();

		if (roleList != null && !roleList.isEmpty()) {
			Iterator authRoles = roleList.iterator();
			Hashtable remember = new Hashtable();
			while (authRoles.hasNext()) {
				String role = (String) authRoles.next();
				if (role == null || role.trim().equals("")) { //$NON-NLS-1$
					String[] parms = new String[1];
					parms[0] = WARValidationResourceHandler.of_Type_Role_Name_19;
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms, authConstraint);
					continue;
				}
				if (remember.get(role.trim()) != null) {
					String[] parms = new String[1];
					parms[0] = role;
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_DUPLICATE_ENTRY, parms, authConstraint);
					continue;
				}
				remember.put(role.trim(), "Yea"); //$NON-NLS-1$
				validateAuthSecRole("", role, secRoles, authConstraint); //$NON-NLS-1$
			}
		}
	}

	/**
	 * Insert the method's description here. Creation date: (7/5/2001 2:20:02 PM)
	 */
	public void validateContextParameters() {

		// we must verify that every param-name is unique;
		// param-name appears in context parameters, filter
		// and servlets. We must check each.
		Hashtable remember = new Hashtable();

		// check context parameters - each param-name should be unique within the web application
		Iterator cparams = webDD.getContexts().iterator();
		while (cparams.hasNext()) {
			
			if( _reporter.isCancelled() ){
				String msg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED);			
				status = WTPCommonPlugin.createCancelStatus(msg);
			}
			
			ContextParam context = (ContextParam) cparams.next();

			String name = context.getParamName();
			if (name != null)
				name = name.trim();

			if (name == null || name.equals("")) { //$NON-NLS-1$
				String[] parms = new String[1];
				parms[0] = WARValidationResourceHandler.of_Type_Parameter_Name_25;

				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms, context);
				continue;
			}
			// if (remember.get(name + value) != null) { // Check for dups
			if (remember.get(name) != null) { // Check for dups
				String[] parms = new String[1];
				parms[0] = WARValidationResourceHandler.of_Type_Parameter_Name_25 + ": " + name; //$NON-NLS-1$
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_DUPLICATE_ENTRY, parms, context);
				continue;
			}
			// remember.put(name + value, "Yea");
			remember.put(name, "Yea"); //$NON-NLS-1$
		}


		// check servlet init-param - each param-name should be unique within a servlet
		Iterator servlets = webDD.getServlets().iterator();
		while (servlets.hasNext()) {
			Servlet nextServlet = (Servlet) servlets.next();
			Iterator params = nextServlet.getParams().iterator();
			remember.clear();
			while (params.hasNext()) {
				InitParam initParam = (InitParam) params.next();
				String name = initParam.getParamName();

				if (name != null)
					name = name.trim();

				if (name == null || name.equals("")) { //$NON-NLS-1$ 
					String[] parms = new String[1];
					parms[0] = WARValidationResourceHandler.of_Type_Parameter_Name_32;
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms, initParam);
					continue;
				}
				if (remember.get(name) != null) { // Check for dups

					String[] parms = new String[1];
					parms[0] = WARValidationResourceHandler.of_Type_Parameter_Name_25 + ": " + name; //$NON-NLS-1$
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_DUPLICATE_ENTRY, parms, initParam);
					continue;
				}
				remember.put(name, "Yea"); //$NON-NLS-1$
			}
		}

		// check filter init-param - each param-name should be unique within a filter
		Iterator filters = webDD.getFilters().iterator();
		while (filters.hasNext()) {
			Filter nextFilter = (Filter) filters.next();
			Iterator params = nextFilter.getInitParams().iterator();
			remember.clear();
			while (params.hasNext()) {
				InitParam initParam = (InitParam) params.next();
				String name = initParam.getParamName();

				if (name != null)
					name = name.trim();

				if (name == null || name.equals("")) { //$NON-NLS-1$ 
					String[] parms = new String[1];
					parms[0] = WARValidationResourceHandler.of_Type_Parameter_Name_39;
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms, initParam);
					continue;
				}
				if (remember.get(name) != null) { // Check for dups
					String[] parms = new String[1];
					parms[0] = WARValidationResourceHandler.of_Type_Parameter_Name_25 + ": " + name; //$NON-NLS-1$
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_DUPLICATE_ENTRY, parms, initParam);
					continue;
				}
				remember.put(name, "Yea"); //$NON-NLS-1$
			}
		}

	}

	/**
	 * Validate EJB references.
	 */

	public void validateEJBRefs(EjbRefImpl eref) {
		// try {

		EARFile earFile = warFile.getEARFile();
		EnterpriseBean eb = null;

		if (earFile != null)
			eb = earFile.getEnterpiseBeanFromRef(eref, warFile.getURI());

		if (!(eb == null)) {
			List ejbRefs = eb.getEjbRefs();

			int numRefs = ejbRefs.size();

			Set refSet = new HashSet(numRefs);

			for (int refNo = 0; refNo < numRefs; refNo++) {
				String nextName = ((EjbRefImpl) (ejbRefs.get(refNo))).getName();

				String[] parms = new String[1];
				parms[0] = eb.getName();
				if (!(refSet.add(nextName))) {
					addWarning(WAR_CATEGORY, ERROR_EAR_DUPLICATE_ROLES, parms, ejbRefs.get(refNo));
				}
			}
		}

		// } catch (UncontainedModuleFileException ue) {
		// String[] parms = new String[1];
		// parms[0] = warFile.getName();
		// addError(EREF_CATEGORY, ERROR_EAR_UNCONTAINED_MODULE_FILE_EXCEPTION, parms);
		// }
	}

	/**
	 * validate for duplicates in EAR Roles
	 */

	public void validateEJBRefs(List ejbRefs) {
		int numRefs = ejbRefs.size();
		Hashtable remember = new Hashtable();
		for (int refNo = 0; refNo < numRefs; refNo++) {
			EjbRefImpl eref = (EjbRefImpl) ejbRefs.get(refNo);
			if (eref.isSetType()) {
				String type = eref.getType().getName();
				if (type == null) {
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_EJB_REF_TYPE, null, eref); // Type
																										// must
																										// be
																										// of
																										// ENTITY
																										// or
																										// FOO
				}
			}
			if (eref.getName() != null) {
				String name = eref.getName();
				name = name.trim();

				if (name.equals("")) { //$NON-NLS-1$
					String[] parms = new String[1];
					parms[0] = WARValidationResourceHandler.of_Type_ejb_ref_name_44;
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms, eref);
					continue;
				}
				if (remember.get(name) != null) { // check for duplicates
					String[] parms = new String[1];
					parms[0] = name;
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_DUPLICATE_EJB_REF, parms, eref);
					continue;
				}
				remember.put(name, "Yea"); //$NON-NLS-1$
			} else {
				String[] parms = new String[1];
				parms[0] = WARValidationResourceHandler.of_Type_ejb_ref_name_44;
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms, eref);
				continue;
			}


			validateEJBRefs(eref);
			validateEJBRefManadatoryElements(eref, webDD.getDisplayName());
		}
	}


	/**
	 * validate for duplicates in EAR Roles
	 */

	public void validateEJBLocalRefs(List ejbRefs) {
		int numRefs = ejbRefs.size();
		Hashtable remember = new Hashtable();
		for (int refNo = 0; refNo < numRefs; refNo++) {
			EJBLocalRefImpl eref = (EJBLocalRefImpl) ejbRefs.get(refNo);
			if (eref.isSetType()) {
				String type = eref.getType().getName();
				if (type == null) {
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_EJB_REF_TYPE, null, eref); // Type
																										// must
																										// be
																										// of
																										// ENTITY
																										// or
																										// FOO
				}
			}
			if (eref.getName() != null) {
				String name = eref.getName();
				name = name.trim();

				if (name.equals("")) { //$NON-NLS-1$
					String[] parms = new String[1];
					parms[0] = WARValidationResourceHandler.of_Type_ejb_ref_name_44;
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms, eref);
					continue;
				}
				if (remember.get(name) != null) { // check for duplicates
					String[] parms = new String[1];
					parms[0] = name;
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_DUPLICATE_EJB_REF, parms, eref);
					continue;
				}
				remember.put(name, "Yea"); //$NON-NLS-1$
			} else {
				String[] parms = new String[1];
				parms[0] = WARValidationResourceHandler.of_Type_ejb_ref_name_44;
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms, eref);
				continue;
			}


			// validateEJBRefs(eref);
			// validateEJBRefManadatoryElements(eref, webDD.getDisplayName());
		}
	}

	/**
	 * Link build should verify location of exception class
	 */

	public void validateErrorPages(EList errorPageList) {
		if (errorPageList == null || errorPageList.isEmpty())
			return;
		Iterator errorPages = errorPageList.iterator();

		while (errorPages.hasNext()) {
			
			if( _reporter.isCancelled() ){
				String msg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED);			
				status = WTPCommonPlugin.createCancelStatus(msg);
			}
			
			ErrorPage nextPage = (ErrorPage) errorPages.next();
			String location = nextPage.getLocation();
			if (location == null || location.equals("")) { //$NON-NLS-1$
				String[] parms = new String[1];
				parms[0] = WARValidationResourceHandler.of_Type_Error_Location_47;
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms, nextPage);
			}
			if (location != null && !location.startsWith("/")) { //$NON-NLS-1$
				String[] parms = new String[1];
				parms[0] = WARValidationResourceHandler.of_Type_Error_Location_49;
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_ERROR_PAGE, parms, nextPage);
			}


			// check for valid HTTP error code - must be an Integer, 3 digits, and the starting
			// digit must be a 1,2,3,4, or 5.
			if (nextPage.isErrorCode()) {
				ErrorCodeErrorPage ecep = (ErrorCodeErrorPage) nextPage;
				String errorCode = ecep.getErrorCode();

				boolean valid = false;
				if (errorCode.length() == 3) {
					try {
						Integer tempInt = new Integer(errorCode);
						// ok, it's a valid 3-digit integer
						int code = tempInt.intValue();
						if (code >= 100 && code < 600) {
							// valid HTTP status code - starting digit must be between 1-5
							valid = true;
						}
					} catch (NumberFormatException exc) {
						// Ignore
					}
				}
				if (!valid) {
					String[] parms = new String[1];
					parms[0] = errorCode;
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_ERROR_CODE, parms, ecep);
				}

			}

			// If exception-type... the specified class must be or inherit from java.lang.Throwable
			else if (nextPage.isExceptionType()) {
				ExceptionTypeErrorPage etep = (ExceptionTypeErrorPage) nextPage;
				JavaClass javaType = etep.getExceptionType();
				String exceptionType = "java.lang.Throwable";//$NON-NLS-1$
				String specifiedClassName = etep.getExceptionTypeName();
				if (javaType != null) {
					ResourceSet lookupSet = javaType.eResource().getResourceSet();
					if (lookupSet != null) {
						if (!javaType.inheritsFrom(JavaRefFactory.eINSTANCE.reflectType(exceptionType, lookupSet).getWrapper())) {
							String[] parms = new String[1];
							parms[0] = specifiedClassName;
							addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_EXCEPTION_TYPE, parms, etep);
						}
					}
				} else {
					String[] parms = new String[1];
					parms[0] = "";//$NON-NLS-1$
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_EXCEPTION_TYPE, parms, etep);
				}
				// TBD
			} else { // Error Code
				// TBD
			}

			// TBD remember location/code/exception dups
		}

	}

	/**
	 * Validate the loginConfig section is correct
	 */
	public void validateLoginConfig(LoginConfig loginConfig) {
		// com.ibm.etools.validate.ValidatorManager.setResourceUtilClass(com.ibm.etools.validate.ui.UIResourceUtil.class);

		if (loginConfig != null) {
			String auth = loginConfig.getAuthMethod().getName();

			if (auth == null) {
				String[] parms = new String[0];
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_AUTH_METHOD, parms, loginConfig);
			}
			// Give a warning if form elements are supplied but FORM auth method is not used
			else if (!auth.equals("FORM")) { //$NON-NLS-1$
				FormLoginConfig cfg = loginConfig.getFormLoginConfig();
				if (cfg != null) {
					String[] parms = new String[1];
					parms[0] = auth;
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_IGNORE_FORM_LOGIN, parms, loginConfig);
				}
			}
		}
	}

	/**
	 * Validate the loginConfig section is correct
	 */
	public void validateEnvironmentEntries(EList envEntries) {
		if (envEntries.isEmpty())
			return;

		// boolean isVersion22 = warFile.getDeploymentDescriptor().isVersion2_2Descriptor();
		Iterator entries = envEntries.iterator();
		Hashtable remember = new Hashtable();

		while (entries.hasNext()) {
			EnvEntry entry = (EnvEntry) entries.next();
			if (entry.getType().getName() == null) {
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_ENV_ENTRY, null, entry);
			}

			// check for duplicate env-entry-name's
			String name = entry.getName();
			if (name != null) {
				if (remember.get(name) != null) { // Check for dups
					String[] parms = new String[1];
					parms[0] = WARValidationResourceHandler.of_Type_Env_Entry_Name___88 + ": " + name; //$NON-NLS-1$
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_DUPLICATE_ENTRY, parms, entry);
				} else {
					remember.put(name, "Yea"); //$NON-NLS-1$
				}
			}
		}

	}


	/**
	 * Insert the method's description here. Creation date: (7/5/2001 12:11:23 PM)
	 */
	public void validateMimeMapping() {

		if (webDD.getMimeMappings().isEmpty())
			return;

		Iterator mimes = webDD.getMimeMappings().iterator();
		Hashtable remember = new Hashtable();

		while (mimes.hasNext()) {
			
			if( _reporter.isCancelled()){
				String msg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED);			
				status = WTPCommonPlugin.createCancelStatus(msg);				
			}
			MimeMapping mimeMap = (MimeMapping) mimes.next();

			String ext = mimeMap.getExtension();
			String mtype = mimeMap.getMimeType();
			if (ext != null)
				ext = ext.trim();
			if (mtype != null)
				mtype = mtype.trim();

			if (ext == null || ext.equals("") || mtype == null || mtype.equals("")) { //$NON-NLS-1$ //$NON-NLS-2$
				String[] parms = new String[1];
				if (ext == null || ext.trim().equals("")) //$NON-NLS-1$
					parms[0] = WARValidationResourceHandler.of_Type_Mime_Extension_54;
				else
					parms[0] = WARValidationResourceHandler.of_Type_Mime_Type_55;
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms, mimeMap);
				continue;
			}
			if (remember.get(ext) != null) { // Check for dups

				String[] parms = new String[1];
				parms[0] = WARValidationResourceHandler.of_Type_Mime_Extension___56 + ": " + ext; //$NON-NLS-1$
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_DUPLICATE_ENTRY, parms, mimeMap);
				continue;
			}
			remember.put(ext, "Yea"); //$NON-NLS-1$
		}
	}

	/**
	 * Insert the method's description here. Creation date: (7/5/2001 11:46:58 AM)
	 */
	public void validateOther() {

		SessionConfig sessionCfg = webDD.getSessionConfig();
		if (sessionCfg != null) {
			int timeout = sessionCfg.getSessionTimeout();
			if (timeout == 0) {
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_SESSION_TIMEOUT, null, sessionCfg);
			}
		}



	}

	/**
	 * validateRefs(WebApp) - validate EJB and resource references - details tbd
	 */

	public void validateRefs() {
		EList ejbRefs = webDD.getEjbRefs();

		if (!ejbRefs.isEmpty())
			validateEJBRefs(ejbRefs);


		EList ejblocalRefs = webDD.getEjbLocalRefs();

		if (!ejblocalRefs.isEmpty())
			validateEJBLocalRefs(ejblocalRefs);


		EList resourceRefs = webDD.getResourceRefs();

		if (!resourceRefs.isEmpty()) {
			// validateResourceRefs(resourceRefs); // we want to do additional checks here

			int numRefs = resourceRefs.size();
			Set refSet = new HashSet(numRefs);
			boolean isVersion22 = warFile.getDeploymentDescriptor().getVersionID() <= J2EEVersionConstants.WEB_2_2_ID;

			for (int refNo = 0; refNo < numRefs; refNo++) {
				
				if( _reporter.isCancelled() ){
					String msg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED);			
					status = WTPCommonPlugin.createCancelStatus(msg);
				}
				
				ResourceRefImpl ref = (ResourceRefImpl) (resourceRefs.get(refNo));
				String auth = ref.getAuth().getName();

				// Check: a res-auth element containing Container or Application must be supplied
				if (auth == null || !ref.isSetAuth()) {
					String[] parms = new String[1];
					parms[0] = ref.getName();
					String msgId = isVersion22 ? MESSAGE_WAR_VALIDATION_RES_AUTH_REQUIRED_22 : MESSAGE_WAR_VALIDATION_RES_AUTH_REQUIRED_23;
					addError(WAR_CATEGORY, msgId, parms, ref);
					
				} else if (isVersion22 && auth.equals("Application")) { //$NON-NLS-1$
					String[] parms = new String[1];
					parms[0] = ref.getName();
					addError(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_RES_AUTH_INVALID_22, parms, ref);
				} else if (!isVersion22 && auth.equals("SERVLET")) { //$NON-NLS-1$
					String[] parms = new String[1];
					parms[0] = ref.getName();
					addError(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_RES_AUTH_INVALID_23, parms, ref);
				}

				// validate res-sharing-scope is allowable value
				String sharingScope = ref.getResSharingScope().getName();
				if (!isVersion22) {
					if (sharingScope == null || !ref.isSetResSharingScope()) {
						String[] parms = new String[0];
						addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_RES_SHARING_SCOPE, parms, ref);
					}
				}

				String refName = ref.getName();
				String[] parms = new String[1];
				parms[0] = refName;
				if (!(refSet.add(refName))){
					addError(EREF_CATEGORY, ERROR_EAR_DUPLICATE_RESREF, parms, ref);
				}
			}
		}

	}


	/**
	 * Insert the method's description here. Creation date: (7/6/2001 4:11:09 PM)
	 * 
	 * @return boolean
	 * @param role
	 *            java.lang.String
	 * @param defineRoles
	 *            java.util.Hashtable
	 * 
	 * The auth-constraint only needs to have role-name specified. <auth-constraint> <description></description>
	 * <role-name>guest</role-name> </auth-constraint>
	 * 
	 */
	protected void validateAuthSecRole(String link, String role, Hashtable definedRoles, EObject targetObject) {
		String rName = role;
		String lName = link;
		// boolean validRole = true;
		// boolean validLink = true;

		if (rName != null)
			rName = rName.trim();
		if (lName != null)
			lName = lName.trim();

		if (rName != null) {
			if (!rName.equals("*") && !rName.equals("")) { //$NON-NLS-1$ //$NON-NLS-2$	
				if (definedRoles.get(rName) == null && definedRoles.get(lName) == null) {
					String[] parms = new String[1];
					parms[0] = rName;
					addError(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_SEC_ROLE_NAME, parms, targetObject);
				}
			}
		}
	}



	/**
	 * Insert the method's description here. Creation date: (7/6/2001 4:11:09 PM)
	 * 
	 * @return boolean
	 * @param role
	 *            java.lang.String
	 * @param defineRoles
	 *            java.util.Hashtable
	 * 
	 * 
	 * the security-role-ref must have a non-null role-name and the role-link must contain the name
	 * of a role specified in the security-role section <security-role-ref> <role-name>MyName</role-name>
	 * <role-link>ExistingRole</role-link> </security-role-ref>
	 * 
	 * 
	 */
	protected void validateSecRole(String link, String role, Hashtable definedRoles, EObject targetObject) {
		String rName = role;
		String lName = link;
		// boolean validRole = true;
		// boolean validLink = true;

		if (rName != null)
			rName = rName.trim();
		if (lName != null)
			lName = lName.trim();


		// the security role-name cannot be null
		if ((rName == null || rName.equals(""))) { //$NON-NLS-1$
			String[] parms = new String[1];
			parms[0] = rName;
			addError(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_SEC_ROLE_NAME, parms, targetObject);
		}

		if (rName == null || !rName.equals("*")) { //$NON-NLS-1$		
			// check that security role-link matches a defines security role
			if (lName != null && definedRoles.get(lName) == null) {

				String[] parms = new String[1];
				parms[0] = lName;
				addError(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_SEC_ROLE, parms, targetObject);
			}
		}
	}

	/**
	 * validateSecurity(WebApp) - validate security constraints, roles, and security role refs -
	 * details tbd
	 */

	public void validateSecurityAndServlets() {


		EList webRoles = webDD.getSecurityRoles();

		// Validate security roles
		Hashtable secRoles = getAndValidateSecurityRoles(webRoles);

		// Validate Servlets/JSPs and their role ref.
		validateServlets(webDD.getServlets(), secRoles);

		validateSecurityConstraints(webDD.getConstraints(), secRoles);

		// try {
		if (!(webRoles.isEmpty())) {
			EARFile module = warFile.getEARFile();
			if (module != null) {
				EList earRoleList = module.getDeploymentDescriptor().getSecurityRoles();
				validateWEBRolesWithEARRoles(earRoleList, webRoles);
			}
		}
		// } catch (UncontainedModuleFileException ue) {
		// String[] parms = new String[1];
		// parms[0] = warFile.getName();
		// addError(EREF_CATEGORY, ERROR_EAR_UNCONTAINED_MODULE_FILE_EXCEPTION, parms);
		// }
	}

	/**
	 * The security-constraint element is used to associate security constraints with one or more
	 * web resource collections <!ELEMENT security-constraint (web-resource-collection+,
	 * auth-constraint?, user-data-constraint?)>
	 * 
	 * @param constraints
	 *            org.eclipse.emf.common.util.EList
	 */
	public void validateSecurityConstraints(EList constraints, Hashtable secRoles) {

		if (constraints.isEmpty())
			return;

		Iterator constList = constraints.iterator();
		while (constList.hasNext()) {
			
			if( _reporter.isCancelled() ){
				String msg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED);			
				status = WTPCommonPlugin.createCancelStatus(msg);
			}
			
			SecurityConstraint constraint = (SecurityConstraint) constList.next();

			EList webResourceList = constraint.getWebResourceCollections();
			if (webResourceList == null || webResourceList.isEmpty()) {
				String[] parms = new String[1];
				parms[0] = WARValidationResourceHandler.of_Type_Web_Resource_Collection_64;
				addError(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms, constraint);
				continue;
			}
			validateWebResourceCollections(webResourceList);

			AuthConstraint authConstraint = constraint.getAuthConstraint();
			if (authConstraint != null)
				validateAuthConstraint(authConstraint, secRoles);

			UserDataConstraint dataConstraint = constraint.getUserDataConstraint();
			if (dataConstraint != null && dataConstraint.getTransportGuarantee() != null) {
				// <!ELEMENT user-data-constraint (description?, transport-guarantee)>
				// The transport-guarantee element specifies that the communication
				// between client and server should be NONE, INTEGRAL, or
				// CONFIDENTIAL.

				// EEnumLiteral transport = dataConstraint.getTransportGuarantee();
				TransportGuaranteeType transport = dataConstraint.getTransportGuarantee();
				if (transport == null || !dataConstraint.isSetTransportGuarantee()) {
					addError(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_TRANSPORT, new String[0], dataConstraint);
				}
			}
		}
	}

	public void validateFilters(EList filterList) {
		if (filterList.isEmpty())
			return;

		Iterator filters = filterList.iterator();

		Hashtable remember = new Hashtable();

		while (filters.hasNext()) {
			
			if( _reporter.isCancelled() ){
				String msg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED);			
				status = WTPCommonPlugin.createCancelStatus(msg);
			}
			
			Filter nextFilter = (Filter) filters.next();
			String name = nextFilter.getName();
			if (name != null)
				name = name.trim();

			if (name == null || name.equals("")) { //$NON-NLS-1$
				String[] parms = new String[1];
				parms[0] = WARValidationResourceHandler.of_Type_Filter_Name_66;
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms, nextFilter);
				continue;
			}
			if (remember.get(name) != null) { // check for duplicates
				String[] parms = new String[1];
				parms[0] = name;
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_DUPLICATE_FILTER, parms, nextFilter);
				continue;
			}
			remember.put(name, "Yea"); //$NON-NLS-1$
		}
	}

	/**
	 * validateFilterMappings(Elist(Filters's)) - for each filter mapping, make sure the named
	 * filter exists
	 */
	public void validateFilterMappings(EList filterMappingsList) {

		if (filterMappingsList.isEmpty())
			return;

		Iterator filterMappings = filterMappingsList.iterator();
		while (filterMappings.hasNext()) {
			FilterMapping nextMapping = (FilterMapping) filterMappings.next();

			// Mapping can be either servlet or url
			if (nextMapping.getUrlPattern() != null) {
				String[] parms = new String[1];
				String url = nextMapping.getUrlPattern();
				parms[0] = url;
				if (url == null) {
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_URL, parms, nextMapping);
					continue;
				}
				if (nextMapping.getFilter() == null || nextMapping.getFilter().equals("")) { //$NON-NLS-1$
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_BROKEN_FILTER_MAPPING, parms, nextMapping);
					continue;
				}

				// Is is a valid URI notation ?
				try {
					if (url.equals("")) //$NON-NLS-1$
						throw new Exception(WARValidationResourceHandler.Invalid_URL_70);
					// You can't use com.ibm.webtools.URI here...
					// com.ibm.iwt.webtools.URI uri = new com.ibm.iwt.webtools.URI(url) ;
				} catch (Exception e) {
					parms = new String[1];
					parms[0] = nextMapping.getUrlPattern();
					addError(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_URL, parms, nextMapping);
					continue;
				}
			} else if (nextMapping.getServletName() != null) {
				String[] parms = new String[1];
				String servletName = nextMapping.getServletName();
				parms[0] = servletName;
				if (nextMapping.getServlet() == null) {
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_BROKEN_SERVLET_MAPPING, parms, nextMapping);
					continue;
				}
				if (nextMapping.getFilter() == null || nextMapping.getFilter().equals("")) { //$NON-NLS-1$
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_BROKEN_FILTER_MAPPING, parms, nextMapping);
					continue;
				}
			}
			// else {
			// // otherwise neither servlet-name or url-mapping is defined - this gets flagged by
			// the xml validator
			// // as this does not conform to the DTD
			//		
			// }


		}

	}



	/**
	 * validateServlets(Elist(Servlet's)) - for each servlet mapping, make sure the named servlet
	 * exists
	 */

	public void validateServletMappings(EList servletMappingsList) {

		if (servletMappingsList.isEmpty())
			return;

		Iterator servletMappings = servletMappingsList.iterator();

		Hashtable remember = new Hashtable();
		while (servletMappings.hasNext()) {
			if( _reporter.isCancelled() ){
				String msg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED);			
				status = WTPCommonPlugin.createCancelStatus(msg);
			}
			
			ServletMapping nextMapping = (ServletMapping) servletMappings.next();
			String url = nextMapping.getUrlPattern();

			// Check for null servlet, if the name is right the reflection
			// has already resolved it.

			if (url != null) { // check for duplicate first, no need to repeat earlier error,
				url = url.trim();
				if (remember.get(url) != null) {
					String[] parms = new String[1];
					parms[0] = nextMapping.getUrlPattern();
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_DUPLICATE_MAPPING, parms, nextMapping);
					continue;
				}
				remember.put(nextMapping.getUrlPattern(), "Yea"); //$NON-NLS-1$
			}


			if (url == null || nextMapping.getServlet() == null || nextMapping.getServlet().equals("")) { //$NON-NLS-1$
				String[] parms = new String[1];
				parms[0] = url;
				if (url == null)
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_URL, parms, nextMapping);
				else
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_BROKEN_SERVLET_MAPPING, parms, nextMapping);
				continue;
			}

			// Is is a valid URI notation ?
			try {
				if (url.equals("")) //$NON-NLS-1$
					throw new Exception(WARValidationResourceHandler.Invalid_URL_75);

				//
				// The spec does not prohibit whitespace in the url-patterns
				//	   
				// // check to see if the string is a valid URL- has no white space
				// char[] chars = url.toCharArray();
				// int len = chars.length;
				// for (int cnt = 0; cnt < chars.length; cnt++)
				// {
				// if (Character.isWhitespace(chars[cnt]))
				// throw new Exception("Invalid URL") ;
				// }
				// You can't use com.ibm.webtools.URI here...
				// com.ibm.iwt.webtools.URI uri = new com.ibm.iwt.webtools.URI(url) ;
			} catch (Exception e) {
				String[] parms = new String[1];
				parms[0] = nextMapping.getUrlPattern();
				addError(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_URL, parms, nextMapping);
				continue;
			}
		}

	}

	/**
	 * validateServlets(Elist(Servlet's)) - if it's a JSP, verify the file exists - validate
	 * optional security role refs for existence of the security role
	 */

	public void validateServlets(EList servletList, Hashtable secRoles) {
		if (servletList.isEmpty())
			return;

		Iterator servlets = servletList.iterator();

		Hashtable remember = new Hashtable();

		while (servlets.hasNext()) {
			if( _reporter.isCancelled() ){
				String msg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED);			
				status = WTPCommonPlugin.createCancelStatus(msg);
			}
			
			Servlet nextServlet = (Servlet) servlets.next();
			String name = nextServlet.getServletName();
			if (name != null)
				name = name.trim();

			if (name == null || name.equals("")) { //$NON-NLS-1$
				String[] parms = new String[1];
				parms[0] = WARValidationResourceHandler.of_Type_Servlet_Name_77;
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms, nextServlet);
				continue;
			}
			if (remember.get(name) != null) { // check for duplicates
				String[] parms = new String[1];
				parms[0] = name;
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_DUPLICATE_SERVLET, parms, nextServlet);
				continue;
			}
			remember.put(name, "Yea"); //$NON-NLS-1$

			// Validate servlet roles
			EList rolesList = nextServlet.getSecurityRoleRefs();
			if (!rolesList.isEmpty()) {
				Iterator roles = rolesList.iterator();
				while (roles.hasNext()) {
					SecurityRoleRef role = (SecurityRoleRef) roles.next();
					validateSecRole(role.getLink(), role.getName(), secRoles, role);
				}
			}

			// if it's a JSP, the jsp-file attribute MUST be a full-path, according to the servlet
			// 2.2 spec
			if (nextServlet.getWebType() != null && nextServlet.getWebType().isJspType()) {
				JSPType jspType = (JSPType) (nextServlet.getWebType());

				String jspFileName = jspType.getJspFile();
				if (jspFileName == null || !(jspFileName.length() > 0)) {
					String[] parms = new String[2];
					parms[0] = jspFileName;
					parms[1] = name;
					addError(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_JSPFILE_REF, parms, nextServlet);
				}
			}

			/* No need to check for the existence of JSPs or Servlets. the LinkBuilder will do this */

		}
	}

	public void validateTagLibs() {

		if (webDD.getTagLibs().isEmpty())
			return;

		Iterator tags = webDD.getTagLibs().iterator();
		Hashtable remember = new Hashtable();

		while (tags.hasNext()) {

			if( _reporter.isCancelled() ){
				String msg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED);			
				status = WTPCommonPlugin.createCancelStatus(msg);
			}
			
			TagLibRef taglib = (TagLibRef) tags.next(); // ClassCastException at runtime
			String uri = taglib.getTaglibURI();

			if (uri != null)
				uri = uri.trim();

			if (uri == null || uri.equals("")) { //$NON-NLS-1$
				String[] parms = new String[1];
				parms[0] = WARValidationResourceHandler.of_Type_Taglib_80;
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms, taglib);
				continue;
			}
			if (remember.get(uri) != null) { // Check for dups

				String[] parms = new String[1];
				parms[0] = WARValidationResourceHandler.of_Type_TagLib___81 + ": " + uri; //$NON-NLS-1$
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_DUPLICATE_ENTRY, parms, taglib);
				continue;
			}
			remember.put(uri, "Yea"); //$NON-NLS-1$
		}
	}

	public void validateWebResourceCollections(EList webResourceList) {


		Iterator resourceList = webResourceList.iterator();
		while (resourceList.hasNext()) { // Check the web resource collections
			WebResourceCollection resource = (WebResourceCollection) resourceList.next();

			String name = resource.getWebResourceName();
			if (name != null)
				name = name.trim();
			if (name == null || name.equals("")) { // should have a name //$NON-NLS-1$
				String[] parms = new String[1];
				parms[0] = WARValidationResourceHandler.of_Type_Web_Resource_Name_84;
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms, resource);
			}

			// Check that the http methods, if any is correct
			EList httpList = resource.getHTTPs();
			if (!httpList.isEmpty()) {
				Iterator https = httpList.iterator();
				while (https.hasNext()) {
					HTTPMethodType httpMethod = (HTTPMethodType) https.next();
					String method = httpMethod.getHttpMethod();

					if (method == null || !isHttpMethod(method)) {
						String[] parms = new String[1];
						parms[0] = method;
						addError(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_HTTP_CMD, parms, httpMethod);
					}


				}
			}
		}
	}

	/**
	 * validateWelcomeFileList(WelcomeFileList) - walk through the files and verify they exist
	 */

	public void validateWelcomeFileList(WelcomeFileList fileList) {
		if (fileList == null)
			return;

		Iterator files = fileList.getFile().iterator();

		Hashtable remember = new Hashtable();
		while (files.hasNext()) {
			
			if( _reporter.isCancelled() ){
				String msg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED);			
				status = WTPCommonPlugin.createCancelStatus(msg);
			}
			
			WelcomeFile nextFile = (WelcomeFile) files.next();
			String fileName = nextFile.getWelcomeFile();

			if ((fileName == null) || (fileName.length() == 0)) {
				String[] parms = new String[0];
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_NO_WELCOME_FILE, parms, nextFile);
			} else if ((fileName.startsWith("/")) || (fileName.endsWith("/"))) { //$NON-NLS-1$ //$NON-NLS-2$
				String[] parms = new String[0];
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_INVALID_WELCOME_FILE, parms, nextFile);
			}
			if(fileName != null){
				fileName = fileName.trim();
			}
			if (remember.get(fileName) != null) {
				String[] parms = new String[1];
				parms[0] = WARValidationResourceHandler.of_Type_Welcome_File_Name__87 + ": " + fileName; //$NON-NLS-1$
				addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_DUPLICATE_ENTRY, parms, nextFile);
				continue;
			}
			remember.put(fileName, "Yea"); //$NON-NLS-1$
		}
	}

	public ISchedulingRule getSchedulingRule(IValidationContext helper) {
		_helper = helper;
		return null;
	}
	
	@Override
	public void cleanup(IReporter reporter) {
		warFile = null;
		webDD = null;
		httpMethods = null;
		super.cleanup( reporter );
	}		
}
