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

import java.util.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.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.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.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 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();
	}
/**
 * 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.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>
 */
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.Web_Archive_Validator_8; 
	}
	// 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) throws ValidationException {
	super.validate(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

	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);
			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);
	}
}

/**
 * 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.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()) {
		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; 
			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; 
				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; 
				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) {
  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.of_Type_Error_Location_47 ; 
		addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_EMPTY_ENTRY, parms,nextPage);
	}
	if (!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; 
		  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.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 ; 
		  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.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()) {
			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("")) 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()) {
	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.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()) {
			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().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.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; 
			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()) {
	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.of_Type_Welcome_File_Name__87 + ": " + fileName ; 
		addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_DUPLICATE_ENTRY, parms,nextFile);
		continue ;      
	}
	remember.put(fileName,"Yea") ; //$NON-NLS-1$
  }
}
}
