/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.model.internal.validation;

import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;

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.commonarchivecore.internal.EARFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.WARFile;
import org.eclipse.jst.j2ee.ejb.EnterpriseBean;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.internal.common.impl.EJBLocalRefImpl;
import org.eclipse.jst.j2ee.internal.common.impl.EjbRefImpl;
import org.eclipse.jst.j2ee.internal.common.impl.ResourceRefImpl;
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.validation.core.IFileDelta;
import org.eclipse.wst.validation.core.IValidationContext;
import org.eclipse.wst.validation.core.IMessage;
import org.eclipse.wst.validation.core.IReporter;
import org.eclipse.wst.validation.core.ValidationException;
import org.eclispe.wst.validation.internal.core.Message;

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

public class WarValidator extends org.eclipse.jst.j2ee.model.internal.validation.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();
	}
	
public boolean checkIfValidFileForIncValidation(IFileDelta changedFile) {

	//the getDeltaType helper can be used to do more fine grained
	//validation specific to add, delete or changed resources
	//changedFile.getDeltaType();

	String fileName = changedFile.getFileName();

	if (fileName.endsWith("xml") || fileName.endsWith("jsp") || fileName.endsWith("html")|| fileName.endsWith("java")) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		return true;
	return false;
}
/**
 * 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()) {
	  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.getString("of_Type_Security_Role_Name_6") ; //$NON-NLS-1$
		  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>
 */
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
	 */

	public String getName()
	{
		return WARValidationResourceHandler.getString("Web_Archive_Validator_8"); //$NON-NLS-1$
	}
	// Messaging helpers ...

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

	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", "PUT", "HEAD", "TRACE", "POST", "DELETE", "OPTIONS"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
		
		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.
 */
public void validate(IValidationContext inHelper, IReporter inReporter, IFileDelta[] inChangedFiles) throws ValidationException {

	super.validate(inHelper, inReporter, inChangedFiles);

	// 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

	try {
		warFile = (WARFile) _helper.loadModel(WAR_MODEL_NAME);
		if (warFile != null) {
			webDD = warFile.getDeploymentDescriptor();
			validate();
		} else {
			IMessage errorMsg = new Message(getBaseName(), IMessage.HIGH_SEVERITY, ERROR_INVALID_WAR_FILE);
			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 );
		throw new ValidationException(errorMsg, e);
	}
}


public void validate(IValidationContext inHelper, IReporter inReporter, IFileDelta[] inChangedFiles, WebApp webApp) throws ValidationException {

	super.validate(inHelper, inReporter, inChangedFiles);

	// 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

	try {
		webDD = webApp;
		validate();
		
	} 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 );
		throw new ValidationException(errorMsg, e);
	}
}


/**
 * 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) {
  	e.printStackTrace();
	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.getString("of_Type_Role_Name_19") ; //$NON-NLS-1$
				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()) {
		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.getString("of_Type_Parameter_Name_25"); //$NON-NLS-1$

			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.getString("of_Type_Parameter_Name_25") + ": " + name; //$NON-NLS-1$  //$NON-NLS-2$
			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.getString("of_Type_Parameter_Name_32"); //$NON-NLS-1$
				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.getString("of_Type_Parameter_Name_25") + ": " +  name; //$NON-NLS-1$ //$NON-NLS-2$
				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.getString("of_Type_Parameter_Name_39"); //$NON-NLS-1$
				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.getString("of_Type_Parameter_Name_25") + ": " +  name; //$NON-NLS-1$ //$NON-NLS-2$
				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.getString("of_Type_ejb-ref-name_44"); //$NON-NLS-1$
					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.getString("of_Type_ejb-ref-name_44"); //$NON-NLS-1$
				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.getString("of_Type_ejb-ref-name_44"); //$NON-NLS-1$
					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.getString("of_Type_ejb-ref-name_44"); //$NON-NLS-1$
				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) {
  Iterator errorPages = errorPageList.iterator();

  if (errorPageList == null || errorPageList.isEmpty()) return ;

  while (errorPages.hasNext()) {
	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.getString("of_Type_Error_Location_47") ; //$NON-NLS-1$
		addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms,nextPage);
	}
	if (!location.startsWith("/")){ //$NON-NLS-1$
		String[] parms = new String[1];
		parms[0] = WARValidationResourceHandler.getString("of_Type_Error_Location_49") ; //$NON-NLS-1$
		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.Exception
	else if (nextPage.isExceptionType()) {
		ExceptionTypeErrorPage etep = (ExceptionTypeErrorPage)nextPage;
		JavaClass javaType = etep.getExceptionType();
		String exceptionType = "java.lang.Exception";//$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.getString("of_Type_Env_Entry_Name___88") +  ": " + name; //$NON-NLS-1$  //$NON-NLS-2$
		  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()) {   
	  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.getString("of_Type_Mime_Extension_54") ;    //$NON-NLS-1$
		  else
			 parms[0] = WARValidationResourceHandler.getString("of_Type_Mime_Type_55") ; //$NON-NLS-1$
		  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.getString("of_Type_Mime_Extension___56") + ": " + ext ; //$NON-NLS-1$  //$NON-NLS-2$
		  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++) {
			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()) {
	  SecurityConstraint constraint = (SecurityConstraint) constList.next() ;

	  EList webResourceList = constraint.getWebResourceCollections() ;
	  if (webResourceList == null || webResourceList.isEmpty()) {
		  String[] parms = new String[1];
		  parms[0] = WARValidationResourceHandler.getString("of_Type_Web_Resource_Collection_64") ; //$NON-NLS-1$
		  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()) {
			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.getString("of_Type_Filter_Name_66") ; //$NON-NLS-1$
				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("")) throw new Exception(WARValidationResourceHandler.getString("Invalid_URL_70")) ; //$NON-NLS-1$ //$NON-NLS-2$
		// 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()) {
	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("")) throw new Exception(WARValidationResourceHandler.getString("Invalid_URL_75")) ; //$NON-NLS-1$ //$NON-NLS-2$

//
// 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()) {
			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.getString("of_Type_Servlet_Name_77"); //$NON-NLS-1$
				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().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()) {
		
		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.getString("of_Type_Taglib_80"); //$NON-NLS-1$
			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.getString("of_Type_TagLib___81") + ": " + uri; //$NON-NLS-1$  //$NON-NLS-2$
			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.getString("of_Type_Web_Resource_Name_84") ; //$NON-NLS-1$
			  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()) {
	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 );
	}
	fileName = fileName.trim() ;
	if (remember.get(fileName) != null) {
		String[] parms = new String[1];
		parms[0] = WARValidationResourceHandler.getString("of_Type_Welcome_File_Name__87") + ": " + fileName ; //$NON-NLS-1$  //$NON-NLS-2$
		addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_DUPLICATE_ENTRY, parms,nextFile);
		continue ;      
	}
	remember.put(fileName,"Yea") ; //$NON-NLS-1$
  }
}
}
