blob: fbe4a2e55f373a73d0028f4d3b95112aa6de6d45 [file] [log] [blame]
/*******************************************************************************
* 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.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.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) 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.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.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.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$
}
}
}