[204176] enhancements in stub generation and superclass validation
diff --git a/plugins/org.eclipse.jst.j2ee.web/property_files/web.properties b/plugins/org.eclipse.jst.j2ee.web/property_files/web.properties
index 265d39a..32efa47 100644
--- a/plugins/org.eclipse.jst.j2ee.web/property_files/web.properties
+++ b/plugins/org.eclipse.jst.j2ee.web/property_files/web.properties
@@ -39,6 +39,7 @@
 ERR_SERVLET_ROLE_REF_NAME_EMPTY=The servlet security role reference name cannot be empty.
 ERR_SERVLET_ROLE_REF_NAME_EXIST=The servlet security role reference name already exists.
 ERR_SERVLET_ROLE_LINK_EMPTY=The servlet security role reference link cannot be empty.
+ERR_SERVLET_INTERFACE=The Servlet class or its superclass must implement the javax.servlet.Servlet interface.
 
 ERR_FILTER_DISPLAY_NAME_EXIST=The filter name already exists.
 ERR_FILTER_CLASS_NAME_USED=The class is already associated with other filter.
diff --git a/plugins/org.eclipse.jst.j2ee.web/templates/servletHeader.template b/plugins/org.eclipse.jst.j2ee.web/templates/servletHeader.template
index 6d12384..b610c89 100644
--- a/plugins/org.eclipse.jst.j2ee.web/templates/servletHeader.template
+++ b/plugins/org.eclipse.jst.j2ee.web/templates/servletHeader.template
@@ -3,10 +3,14 @@
 

 import java.io.IOException;

 import javax.servlet.ServletException;

-<% if (model.shouldGenGetServletConfig()) { %>

+<% if (model.shouldGenGetServletConfig() || model.shouldGenInit()) { %>

 import javax.servlet.ServletConfig; <% } %>

+<% if (model.shouldGenService() && !model.isHttpServletSuperclass()) { %>

+import javax.servlet.ServletRequest;

+import javax.servlet.ServletResponse; <% } %>

+<% if (model.isHttpServletSuperclass()) { %>

 import javax.servlet.http.HttpServletRequest;

-import javax.servlet.http.HttpServletResponse;

+import javax.servlet.http.HttpServletResponse;<% } %>

 

 /**

  * Servlet implementation class for Servlet: <%=model.getServletClassName()%>

diff --git a/plugins/org.eclipse.jst.j2ee.web/templates/servletHeaderNonAnnotated.template b/plugins/org.eclipse.jst.j2ee.web/templates/servletHeaderNonAnnotated.template
index 2eeaa0d..c667538 100644
--- a/plugins/org.eclipse.jst.j2ee.web/templates/servletHeaderNonAnnotated.template
+++ b/plugins/org.eclipse.jst.j2ee.web/templates/servletHeaderNonAnnotated.template
@@ -3,10 +3,14 @@
 

 import java.io.IOException;

 import javax.servlet.ServletException;

-<% if (model.shouldGenGetServletConfig()) { %>

+<% if (model.shouldGenGetServletConfig() || model.shouldGenInit()) { %>

 import javax.servlet.ServletConfig; <% } %>

+<% if (model.shouldGenService() && !model.isHttpServletSuperclass()) { %>

+import javax.servlet.ServletRequest;

+import javax.servlet.ServletResponse; <% } %>

+<% if (model.isHttpServletSuperclass()) { %>

 import javax.servlet.http.HttpServletRequest;

-import javax.servlet.http.HttpServletResponse;

+import javax.servlet.http.HttpServletResponse;<% } %>

 

 /**

  * Servlet implementation class for Servlet: <%=model.getServletClassName()%>

diff --git a/plugins/org.eclipse.jst.j2ee.web/templates/servletXDoclet.javajet b/plugins/org.eclipse.jst.j2ee.web/templates/servletXDoclet.javajet
index 6b3a539..f275128 100644
--- a/plugins/org.eclipse.jst.j2ee.web/templates/servletXDoclet.javajet
+++ b/plugins/org.eclipse.jst.j2ee.web/templates/servletXDoclet.javajet
@@ -4,8 +4,9 @@
 %><%@ include file="servletHeader.template" %>

 

 <%if (model.isPublic()) {%>public<%}%> <%if (model.isAbstract()) {%>abstract <%}%><%if (model.isFinal()) {%>final <%}

-%>class <%=model.getServletClassName()%> extends <%=model.getSuperclassName()%><%

- List interfaces = model.getInterfaces(); 

+%>class <%=model.getServletClassName()%><%String superClass = model.getSuperclassName();

+ if (! "".equals(superClass)) {%> extends <%=superClass%><%}%>

+ <%List interfaces = model.getInterfaces(); 

  if (interfaces.size()>0) {%> implements <% }

  for (int i=0; i<interfaces.size(); i++) {

    String INTERFACE = (String) interfaces.get(i);

@@ -22,34 +23,43 @@
 	/* (non-Javadoc)

 	 * @see javax.servlet.GenericServlet#init()

 	 */

-	public void init() throws ServletException {

-		// TODO Auto-generated method stub

-		super.init();

+	public void init(ServletConfig config) throws ServletException {

+		// TODO Auto-generated method stub <% if (model.isGenericServletSuperclass()) { %>

+		super.init(); <% } %>

 	} <% } %>  <% if (model.shouldGenDestroy()) { %>

 	

 	/* (non-Javadoc)

 	 * @see javax.servlet.Servlet#destroy()

 	 */

 	public void destroy() {

-		// TODO Auto-generated method stub

-		super.destroy();

+		// TODO Auto-generated method stub <% if (model.isGenericServletSuperclass()) { %>

+		super.destroy(); <% } %>

 	} <% } %>  <% if (model.shouldGenGetServletConfig()) { %>

 	

 	/* (non-Javadoc)

 	 * @see javax.servlet.Servlet#getServletConfig()

 	 */

 	public ServletConfig getServletConfig() {

-		// TODO Auto-generated method stub

-		return super.getServletConfig();

+		// TODO Auto-generated method stub <% if (model.isGenericServletSuperclass()) { %>

+		return super.getServletConfig(); <% } else { %>

+		return null; <% } %>

 	} <% } %>  <% if (model.shouldGenGetServletInfo()) { %>

 	

 	/* (non-Javadoc)

 	 * @see javax.servlet.Servlet#getServletInfo()

 	 */

 	public String getServletInfo() {

+		// TODO Auto-generated method stub <% if (model.isGenericServletSuperclass()) { %>

+		return super.getServletInfo(); <% } else { %>

+		return null; <% } %>

+	} <% } %> 	<% if (model.shouldGenService() && !model.isHttpServletSuperclass()) { %>

+	

+	/* (non-Java-doc)

+	 * @see javax.servlet.GenericServlet#service(ServletRequest request, ServletResponse response)

+	 */

+	public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {

 		// TODO Auto-generated method stub

-		return super.getServletInfo();

-	} <% } %>  <% if (model.shouldGenService()) { %>

+	} <% } %> 	<% if (model.shouldGenService() && model.isHttpServletSuperclass()) { %>

 	

 	/* (non-Java-doc)

 	 * @see javax.servlet.http.HttpServlet#service(HttpServletRequest request, HttpServletResponse response)

@@ -57,13 +67,14 @@
 	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

 		// TODO Auto-generated method stub

 		super.service(request, response);

-	} <% } %> 	<% if (model.shouldGenDoGet()) { %>

+	} <% } %>	<% if (model.shouldGenDoGet()) { %>

 	

 	/* (non-Java-doc)

 	 * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

 	 */

 	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

 		// TODO Auto-generated method stub

+		super.doGet(request, response);

 	} <% } %> 	<% if (model.shouldGenDoPost()) { %>

 	

 	/* (non-Java-doc)

@@ -71,6 +82,7 @@
 	 */

 	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

 		// TODO Auto-generated method stub

+		super.doPost(request, response);

 	} <% } %>  	<% if (model.shouldGenDoPut()) { %>

 	

 	/* (non-Javadoc)

diff --git a/plugins/org.eclipse.jst.j2ee.web/templates/servletXDocletNonAnnotated.javajet b/plugins/org.eclipse.jst.j2ee.web/templates/servletXDocletNonAnnotated.javajet
index 23d6541..d31c39e 100644
--- a/plugins/org.eclipse.jst.j2ee.web/templates/servletXDocletNonAnnotated.javajet
+++ b/plugins/org.eclipse.jst.j2ee.web/templates/servletXDocletNonAnnotated.javajet
@@ -4,7 +4,8 @@
 %><%@ include file="servletHeaderNonAnnotated.template" %>

 

 <%if (model.isPublic()) {%>public<%}%> <%if (model.isAbstract()) {%>abstract <%}%><%if (model.isFinal()) {%>final <%}

-%>class <%=model.getServletClassName()%> extends <%=model.getSuperclassName()%><%

+%>class <%=model.getServletClassName()%><%String superClass = model.getSuperclassName();

+ if (! "".equals(superClass)) {%> extends <%=superClass%><%}%><%

  List interfaces = model.getInterfaces(); 

  if (interfaces.size()>0) {%> implements <% }

  for (int i=0; i<interfaces.size(); i++) {

@@ -22,34 +23,43 @@
 	/* (non-Javadoc)

 	 * @see javax.servlet.GenericServlet#init()

 	 */

-	public void init() throws ServletException {

-		// TODO Auto-generated method stub

-		super.init();

+	public void init(ServletConfig config) throws ServletException {

+		// TODO Auto-generated method stub <% if (model.isGenericServletSuperclass()) { %>

+		super.init(); <% } %>

 	} <% } %>  <% if (model.shouldGenDestroy()) { %>

 	

 	/* (non-Javadoc)

 	 * @see javax.servlet.Servlet#destroy()

 	 */

 	public void destroy() {

-		// TODO Auto-generated method stub

-		super.destroy();

+		// TODO Auto-generated method stub <% if (model.isGenericServletSuperclass()) { %>

+		super.destroy(); <% } %>

 	} <% } %>  <% if (model.shouldGenGetServletConfig()) { %>

 	

 	/* (non-Javadoc)

 	 * @see javax.servlet.Servlet#getServletConfig()

 	 */

 	public ServletConfig getServletConfig() {

-		// TODO Auto-generated method stub

-		return super.getServletConfig();

+		// TODO Auto-generated method stub <% if (model.isGenericServletSuperclass()) { %>

+		return super.getServletConfig(); <% } else { %>

+		return null; <% } %>

 	} <% } %>  <% if (model.shouldGenGetServletInfo()) { %>

 	

 	/* (non-Javadoc)

 	 * @see javax.servlet.Servlet#getServletInfo()

 	 */

 	public String getServletInfo() {

-		// TODO Auto-generated method stub

-		return super.getServletInfo();

-	} <% } %>  <% if (model.shouldGenService()) { %>

+		// TODO Auto-generated method stub <% if (model.isGenericServletSuperclass()) { %>

+		return super.getServletInfo(); <% } else { %>

+		return null; <% } %>

+	} <% } %> 	<% if (model.shouldGenService() && !model.isHttpServletSuperclass()) { %>

+	

+	/* (non-Java-doc)

+	 * @see javax.servlet.GenericServlet#service(ServletRequest request, ServletResponse response)

+	 */

+	public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {

+		// TODO Auto-generated method stub 

+	} <% } %> 	<% if (model.shouldGenService() && model.isHttpServletSuperclass()) { %>

 	

 	/* (non-Java-doc)

 	 * @see javax.servlet.http.HttpServlet#service(HttpServletRequest request, HttpServletResponse response)

@@ -57,13 +67,14 @@
 	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

 		// TODO Auto-generated method stub

 		super.service(request, response);

-	} <% } %> 	<% if (model.shouldGenDoGet()) { %>

+	} <% } %>	<% if (model.shouldGenDoGet()) { %>

 	

 	/* (non-Java-doc)

 	 * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

 	 */

 	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

 		// TODO Auto-generated method stub

+		super.doGet(request, response);

 	} <% } %> 	<% if (model.shouldGenDoPost()) { %>

 	

 	/* (non-Java-doc)

@@ -71,6 +82,7 @@
 	 */

 	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

 		// TODO Auto-generated method stub

+		super.doPost(request, response);

 	} <% } %>  	<% if (model.shouldGenDoPut()) { %>

 	

 	/* (non-Javadoc)

diff --git a/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/AbstractSupertypesValidator.java b/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/AbstractSupertypesValidator.java
new file mode 100644
index 0000000..a9f9749
--- /dev/null
+++ b/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/AbstractSupertypesValidator.java
@@ -0,0 +1,84 @@
+package org.eclipse.jst.j2ee.internal.web.operations;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeHierarchy;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jem.util.logger.proxy.Logger;
+import org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+
+public class AbstractSupertypesValidator {
+	
+	private IDataModel dataModel;
+	
+	private String superclass;
+	private List interfaces;
+	private IJavaProject javaProject;
+	
+	public AbstractSupertypesValidator(IDataModel dataModel) {
+		this.dataModel = dataModel;
+	}
+	
+	protected String getSuperclass() {
+		if (superclass == null) {
+			superclass = dataModel.getStringProperty(INewServletClassDataModelProperties.SUPERCLASS);
+		}
+		return superclass;
+	}
+	
+	protected List getInterfaces() {
+		if (interfaces == null) {
+			interfaces = (List) dataModel.getProperty(INewServletClassDataModelProperties.INTERFACES);
+		}
+		return interfaces;
+	}
+	
+	protected IJavaProject getJavaProject() {
+		if (javaProject == null) {
+			javaProject = JavaCore.create((IProject) dataModel.getProperty(
+					INewJavaClassDataModelProperties.PROJECT));
+		}
+		return javaProject;
+	}
+	
+	protected boolean hasSuperclass(String typeName, String superTypeName) {
+		try {
+			IType type = getJavaProject().findType(typeName);
+			if (type != null) {
+				ITypeHierarchy typeHierarchy = type.newTypeHierarchy(new NullProgressMonitor());
+				for (IType superType : typeHierarchy.getAllSuperclasses(type)) {
+					if (superTypeName.equals(superType.getFullyQualifiedName()))
+						return true;
+				}
+			}
+		} catch (JavaModelException e) {
+			Logger.getLogger().log(e);
+		}
+		
+		return false;
+	}
+	
+	protected boolean hasSuperInterface(String typeName, String superTypeName) {
+		try {
+			IType type = getJavaProject().findType(typeName);
+			if (type != null) {
+				ITypeHierarchy typeHierarchy = type.newTypeHierarchy(new NullProgressMonitor());
+				for (IType superType : typeHierarchy.getAllSuperInterfaces(type)) {
+					if (superTypeName.equals(superType.getFullyQualifiedName()))
+						return true;
+				}
+			}
+		} catch (JavaModelException e) {
+			Logger.getLogger().log(e);
+		}
+		
+		return false;
+	}
+
+}
diff --git a/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/CreateServletTemplateModel.java b/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/CreateServletTemplateModel.java
index e4d2aca..c933afb 100644
--- a/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/CreateServletTemplateModel.java
+++ b/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/CreateServletTemplateModel.java
@@ -50,11 +50,11 @@
 	}
 
 	public String getServletClassName() {
-		return getProperty(INewJavaClassDataModelProperties.CLASS_NAME);
+		return getProperty(INewJavaClassDataModelProperties.CLASS_NAME).trim();
 	}
 
 	public String getJavaPackageName() {
-		return getProperty(INewJavaClassDataModelProperties.JAVA_PACKAGE);
+		return getProperty(INewJavaClassDataModelProperties.JAVA_PACKAGE).trim();
 	}
 
 	public String getQualifiedJavaClassName() {
@@ -62,11 +62,11 @@
 	}
 
 	public String getSuperclassName() {
-		return getProperty(INewJavaClassDataModelProperties.SUPERCLASS);
+		return getProperty(INewJavaClassDataModelProperties.SUPERCLASS).trim();
 	}
 
 	public String getServletName() {
-		return getProperty(INewServletClassDataModelProperties.DISPLAY_NAME);
+		return getProperty(INewServletClassDataModelProperties.DISPLAY_NAME).trim();
 	}
 
 	public boolean isPublic() {
@@ -133,6 +133,16 @@
 		return implementImplementedMethod(DO_TRACE);
 	}
 
+	public boolean isGenericServletSuperclass() {
+		ServletSupertypesValidator validator = new ServletSupertypesValidator(dataModel);
+		return validator.isGenericServletSuperclass();
+	}
+	
+	public boolean isHttpServletSuperclass() {
+		ServletSupertypesValidator validator = new ServletSupertypesValidator(dataModel);
+		return validator.isHttpServletSuperclass();
+	}
+	
 	public List getInitParams() {
 		return (List) dataModel.getProperty(INewServletClassDataModelProperties.INIT_PARAM);
 	}
diff --git a/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/NewServletClassDataModelProvider.java b/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/NewServletClassDataModelProvider.java
index 8cfddb9..482514f 100644
--- a/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/NewServletClassDataModelProvider.java
+++ b/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/NewServletClassDataModelProvider.java
@@ -168,14 +168,29 @@
 	 * @return Object default value of property
 	 */
 	public Object getDefaultProperty(String propertyName) {
-		// Generate a doPost method by default
-		if (propertyName.equals(DO_POST))
-			return Boolean.TRUE;
-		// Generate a doGet method by default
-		else if (propertyName.equals(DO_GET))
-			return Boolean.TRUE;
-		else if (propertyName.equals(SERVICE))
-			return Boolean.FALSE;
+		// Generate a doPost and doGet methods by default only if a class 
+		// extending HttpServlet is selected
+		if (propertyName.equals(DO_POST) || propertyName.equals(DO_GET)) {
+			ServletSupertypesValidator validator = new ServletSupertypesValidator(getDataModel());
+			if (validator.isHttpServletSuperclass())
+				return Boolean.TRUE;
+		}
+		
+		// Generate a service method by default only if a class 
+		// not extending HttpServlet is selected
+		if (propertyName.equals(SERVICE)) {
+			ServletSupertypesValidator validator = new ServletSupertypesValidator(getDataModel());
+			if (!validator.isHttpServletSuperclass())
+				return Boolean.TRUE;
+		}
+		
+		if (propertyName.equals(INIT) || propertyName.equals(DESTROY) || 
+			propertyName.equals(GET_SERVLET_CONFIG) || propertyName.equals(GET_SERVLET_INFO)) {
+			ServletSupertypesValidator validator = new ServletSupertypesValidator(getDataModel());
+			if (!validator.isGenericServletSuperclass()) 
+				return Boolean.TRUE;
+		}
+		
 		// Use servlet by default
 		else if (propertyName.equals(IS_SERVLET_TYPE))
 			return Boolean.TRUE;
@@ -346,9 +361,9 @@
 	 */
 	public IStatus validate(String propertyName) {
 		IStatus result = Status.OK_STATUS;
-		// If our default is the superclass, we know it is ok
-		if (propertyName.equals(SUPERCLASS) && getStringProperty(propertyName).equals(SERVLET_SUPERCLASS))
-			return WTPCommonPlugin.OK_STATUS;
+		// Validate super class
+		if (propertyName.equals(SUPERCLASS)) 
+			return validateSuperClassName(getStringProperty(propertyName));
 		// Validate init params
 		if (propertyName.equals(INIT_PARAM))
 			return validateInitParamList((List) getProperty(propertyName));
@@ -372,6 +387,38 @@
 		// Otherwise defer to super to validate the property
 		return super.validate(propertyName);
 	}
+	
+	/**
+	 * Subclasses may extend this method to provide their own validation of the specified java
+	 * classname. This implementation will ensure the class name is not set to Servlet and then will
+	 * forward on to the NewJavaClassDataModel to validate the class name as valid java. This method
+	 * does not accept null as a parameter. It will not return null. 
+	 * It will check if the super class extends the javax.servlet.Servlet interface also.
+	 * 
+	 * @see NewServletClassDataModelProvider#validateExistingClass(boolean)
+	 * @see NewJavaClassDataModelProvider#validateJavaClassName(String)
+	 * 
+	 * @param className
+	 * @return IStatus is java classname valid?
+	 */
+	protected IStatus validateSuperClassName(String superclassName) {
+		//If the servlet implements javax.servlet.Servlet, we do not need a super class
+		ServletSupertypesValidator validator = new ServletSupertypesValidator(getDataModel());
+		if (validator.isGenericServletSuperclass())
+			return WTPCommonPlugin.OK_STATUS;
+		
+		// Check the super class as a java class
+		if (superclassName.trim().length() > 0) {
+			IStatus status = super.validate(SUPERCLASS);
+			if (status.getSeverity() == IStatus.ERROR)
+				return status;
+		}
+		
+		if (!validator.isServletSuperclass())
+			return WTPCommonPlugin.createErrorStatus(WebMessages.ERR_SERVLET_INTERFACE);
+		
+		return WTPCommonPlugin.OK_STATUS;
+	}
 
 	/**
 	 * This method is intended for internal use only. It will be used to validate the init params
@@ -616,4 +663,8 @@
 			return Boolean.TRUE;
 		return Boolean.FALSE;
 	}
+	
+	private boolean hasServletInterfaceToImplement(List newInterfacesList) {
+		return newInterfacesList != null && newInterfacesList.contains(SERVLET_INTERFACES[0]);		
+	}
 }
diff --git a/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/ServletSupertypesValidator.java b/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/ServletSupertypesValidator.java
new file mode 100644
index 0000000..4edca8e
--- /dev/null
+++ b/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/ServletSupertypesValidator.java
@@ -0,0 +1,59 @@
+package org.eclipse.jst.j2ee.internal.web.operations;
+
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+
+public class ServletSupertypesValidator extends AbstractSupertypesValidator {
+
+	public static final String HTTP_SERVLET_CLASS_NAME = "javax.servlet.http.HttpServlet";
+	public static final String GENERIC_SERVLET_CLASS_NAME = "javax.servlet.GenericServlet";
+	public static final String SERVLET_INTERFACE_NAME = "javax.servlet.Servlet";
+	
+	public ServletSupertypesValidator(IDataModel dataModel) {
+		super(dataModel);
+	}
+	
+	public boolean isHttpServletSuperclass() {
+		if (HTTP_SERVLET_CLASS_NAME.equals(getSuperclass()))
+			return true;
+		
+		if (hasSuperclass(getSuperclass(), HTTP_SERVLET_CLASS_NAME))
+			return true;
+		
+		return false;
+	}
+
+	public boolean isGenericServletSuperclass() {
+		if (HTTP_SERVLET_CLASS_NAME.equals(getSuperclass()))
+			return true;
+		
+		if (GENERIC_SERVLET_CLASS_NAME.equals(getSuperclass()))
+			return true;
+		
+		if (hasSuperclass(getSuperclass(), GENERIC_SERVLET_CLASS_NAME))
+			return true;
+		
+		return false;
+	}
+	
+	public boolean isServletSuperclass() {
+		if (HTTP_SERVLET_CLASS_NAME.equals(getSuperclass()))
+			return true;
+		
+		if (GENERIC_SERVLET_CLASS_NAME.equals(getSuperclass()))
+			return true;
+		
+		if (getInterfaces().contains(SERVLET_INTERFACE_NAME))
+			return true;
+		
+		if (hasSuperInterface(getSuperclass(), SERVLET_INTERFACE_NAME))
+			return true;
+		
+		for (Object iface : getInterfaces()) {
+			if (hasSuperInterface((String) iface, SERVLET_INTERFACE_NAME)) 
+				return true;
+		}
+		
+		return false;
+	}
+
+}
diff --git a/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/WebMessages.java b/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/WebMessages.java
index c0f408d..6a18bdb 100644
--- a/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/WebMessages.java
+++ b/plugins/org.eclipse.jst.j2ee.web/web/org/eclipse/jst/j2ee/internal/web/operations/WebMessages.java
@@ -61,6 +61,7 @@
 	public static String ERR_SERVLET_ROLE_REF_NAME_EMPTY;
 	public static String ERR_SERVLET_ROLE_REF_NAME_EXIST;
 	public static String ERR_SERVLET_ROLE_LINK_EMPTY;
+	public static String ERR_SERVLET_INTERFACE;
 
 	public static String ERR_FILTER_DISPLAY_NAME_EXIST;
 	public static String ERR_FILTER_CLASS_NAME_USED;
diff --git a/plugins/org.eclipse.jst.servlet.ui/servlet_ui/org/eclipse/jst/servlet/ui/internal/wizard/NewServletClassOptionsWizardPage.java b/plugins/org.eclipse.jst.servlet.ui/servlet_ui/org/eclipse/jst/servlet/ui/internal/wizard/NewServletClassOptionsWizardPage.java
index fad633b..8dbddc4 100644
--- a/plugins/org.eclipse.jst.servlet.ui/servlet_ui/org/eclipse/jst/servlet/ui/internal/wizard/NewServletClassOptionsWizardPage.java
+++ b/plugins/org.eclipse.jst.servlet.ui/servlet_ui/org/eclipse/jst/servlet/ui/internal/wizard/NewServletClassOptionsWizardPage.java
@@ -13,9 +13,15 @@
 package org.eclipse.jst.servlet.ui.internal.wizard;
 
 
+import java.util.Iterator;
+
 import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties;
 import org.eclipse.jst.j2ee.internal.web.operations.INewServletClassDataModelProperties;
+import org.eclipse.jst.j2ee.internal.web.operations.ServletSupertypesValidator;
 import org.eclipse.jst.j2ee.internal.wizard.NewJavaClassOptionsWizardPage;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionEvent;
@@ -24,13 +30,14 @@
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
 
 /**
  * 
  */
-public class NewServletClassOptionsWizardPage extends NewJavaClassOptionsWizardPage {
+public class NewServletClassOptionsWizardPage extends NewJavaClassOptionsWizardPage implements ISelectionChangedListener {
 	
 	protected Button initButton;
 	protected Button destroyButton;
@@ -49,6 +56,34 @@
 		super(model, pageName, pageDesc, pageTitle);
 	}
 	
+	protected void enter() {
+		super.enter();
+		
+		interfaceViewer.getList().deselectAll();
+		removeButton.setEnabled(false);
+		
+		ServletSupertypesValidator validator = new ServletSupertypesValidator(getDataModel());
+		
+		boolean genericServlet = validator.isGenericServletSuperclass();
+		inheritButton.setEnabled(genericServlet);
+		
+		boolean inherit = getDataModel().getBooleanProperty(INewServletClassDataModelProperties.ABSTRACT_METHODS);
+		initButton.setEnabled(genericServlet && inherit);
+		destroyButton.setEnabled(genericServlet && inherit);
+		getConfigButton.setEnabled(genericServlet && inherit);
+		getInfoButton.setEnabled(genericServlet && inherit);
+		serviceButton.setEnabled(genericServlet && inherit);
+		
+		boolean httpServlet = validator.isHttpServletSuperclass();
+		doGetButton.setVisible(httpServlet);
+		doPostButton.setVisible(httpServlet);
+		doPutButton.setVisible(httpServlet);
+		doDeleteButton.setVisible(httpServlet);
+		doHeadButton.setVisible(httpServlet);
+		doOptionsButton.setVisible(httpServlet);
+		doTraceButton.setVisible(httpServlet);
+	}
+	
 	protected void createModifierControls(Composite parent) {
 		super.createModifierControls(parent);
 		
@@ -84,13 +119,29 @@
 		inheritButton.setText(IWebWizardConstants.JAVA_CLASS_INHERIT_CHECKBOX_LABEL);
 		synchHelper.synchCheckbox(inheritButton, INewJavaClassDataModelProperties.ABSTRACT_METHODS, null);
 		inheritButton.addSelectionListener(new SelectionListener() {
+			private ServletSupertypesValidator validator = new ServletSupertypesValidator(getDataModel());
+			
 			public void widgetSelected(SelectionEvent e) {
 				boolean enable = inheritButton.getSelection();
-				initButton.setEnabled(enable);
-				destroyButton.setEnabled(enable);
-				getConfigButton.setEnabled(enable);
-				getInfoButton.setEnabled(enable);
-				serviceButton.setEnabled(enable);
+				enableGenericServletButtons(enable);
+				enableHttpServletButtons(enable);
+			}
+			
+			public void widgetDefaultSelected(SelectionEvent e) {
+				//Do nothing
+			}
+			
+			private void enableGenericServletButtons(boolean enable) {
+				if (validator.isGenericServletSuperclass()) {
+					initButton.setEnabled(enable);
+					destroyButton.setEnabled(enable);
+					getConfigButton.setEnabled(enable);
+					getInfoButton.setEnabled(enable);
+					serviceButton.setEnabled(enable);
+				}
+			}
+			
+			private void enableHttpServletButtons(boolean enable) {
 				doGetButton.setEnabled(enable);
 				doPostButton.setEnabled(enable);
 				doPutButton.setEnabled(enable);
@@ -99,11 +150,8 @@
 				doOptionsButton.setEnabled(enable);
 				doTraceButton.setEnabled(enable);
 			}
-			public void widgetDefaultSelected(SelectionEvent e) {
-				//Do nothing
-			}
 		});
-
+		
 		Composite comp = new Composite(buttonCompo, SWT.NULL);
 		GridLayout layout = new GridLayout(3, false);
 		layout.marginWidth = 0;
@@ -111,55 +159,91 @@
 		comp.setLayout(layout);
 		data = new GridData(GridData.FILL_BOTH);
 		comp.setLayoutData(data);
-
+		
 		initButton = new Button(comp, SWT.CHECK);
-		initButton.setText("init"); //$NON-NLS-1$
+		initButton.setText("&init"); //$NON-NLS-1$
 		synchHelper.synchCheckbox(initButton, INewServletClassDataModelProperties.INIT, null);
 
 		destroyButton = new Button(comp, SWT.CHECK);
-		destroyButton.setText("destroy"); //$NON-NLS-1$
+		destroyButton.setText("destro&y"); //$NON-NLS-1$
 		synchHelper.synchCheckbox(destroyButton, INewServletClassDataModelProperties.DESTROY, null);
 
 		getConfigButton = new Button(comp, SWT.CHECK);
-		getConfigButton.setText("getServletConfig"); //$NON-NLS-1$
+		getConfigButton.setText("getServlet&Config"); //$NON-NLS-1$
 		synchHelper.synchCheckbox(getConfigButton, INewServletClassDataModelProperties.GET_SERVLET_CONFIG, null);
 
 		getInfoButton = new Button(comp, SWT.CHECK);
-		getInfoButton.setText("getServletInfo"); //$NON-NLS-1$
+		getInfoButton.setText("getServletI&nfo"); //$NON-NLS-1$
 		synchHelper.synchCheckbox(getInfoButton, INewServletClassDataModelProperties.GET_SERVLET_INFO, null);
 		
 		serviceButton = new Button(comp, SWT.CHECK);
-		serviceButton.setText("service"); //$NON-NLS-1$
+		serviceButton.setText("&service"); //$NON-NLS-1$
 		synchHelper.synchCheckbox(serviceButton, INewServletClassDataModelProperties.SERVICE, null);
-
+		
 		doGetButton = new Button(comp, SWT.CHECK);
-		doGetButton.setText("doGet"); //$NON-NLS-1$
+		doGetButton.setText("do&Get"); //$NON-NLS-1$
 		synchHelper.synchCheckbox(doGetButton, INewServletClassDataModelProperties.DO_GET, null);
 
 		doPostButton = new Button(comp, SWT.CHECK);
-		doPostButton.setText("doPost"); //$NON-NLS-1$
+		doPostButton.setText("do&Post"); //$NON-NLS-1$
 		synchHelper.synchCheckbox(doPostButton, INewServletClassDataModelProperties.DO_POST, null);
 
 		doPutButton = new Button(comp, SWT.CHECK);
-		doPutButton.setText("doPut"); //$NON-NLS-1$
+		doPutButton.setText("doP&ut"); //$NON-NLS-1$
 		synchHelper.synchCheckbox(doPutButton, INewServletClassDataModelProperties.DO_PUT, null);
 
 		doDeleteButton = new Button(comp, SWT.CHECK);
-		doDeleteButton.setText("doDelete"); //$NON-NLS-1$
+		doDeleteButton.setText("do&Delete"); //$NON-NLS-1$
 		synchHelper.synchCheckbox(doDeleteButton, INewServletClassDataModelProperties.DO_DELETE, null);
 
 		doHeadButton = new Button(comp, SWT.CHECK);
-		doHeadButton.setText("doHead"); //$NON-NLS-1$
+		doHeadButton.setText("do&Head"); //$NON-NLS-1$
 		synchHelper.synchCheckbox(doHeadButton, INewServletClassDataModelProperties.DO_HEAD, null);
 
 		doOptionsButton = new Button(comp, SWT.CHECK);
-		doOptionsButton.setText("doOptions"); //$NON-NLS-1$
+		doOptionsButton.setText("do&Options"); //$NON-NLS-1$
 		synchHelper.synchCheckbox(doOptionsButton, INewServletClassDataModelProperties.DO_OPTIONS, null);
 
 		doTraceButton = new Button(comp, SWT.CHECK);
-		doTraceButton.setText("doTrace"); //$NON-NLS-1$
+		doTraceButton.setText("do&Trace"); //$NON-NLS-1$
 		synchHelper.synchCheckbox(doTraceButton, INewServletClassDataModelProperties.DO_TRACE, null);
 		
+		interfaceViewer.addSelectionChangedListener(this);
+		
 	    Dialog.applyDialogFont(parent);
 	}
+
+	protected String[] getValidationPropertyNames() {
+		return new String[] { INewJavaClassDataModelProperties.INTERFACES };
+	}
+	
+	public void selectionChanged(SelectionChangedEvent event) {
+		StructuredSelection selection = (StructuredSelection) event.getSelection();
+		
+		// if the selection is empty, then the remove button is disabled
+		if (selection.isEmpty()) {
+			removeButton.setEnabled(false);
+			return;
+		}
+		
+		// if the selection is non-empty and the servlet extends GenericServlet, then
+		// the remove button is enabled
+		ServletSupertypesValidator validator = new ServletSupertypesValidator(getDataModel());
+		if (validator.isGenericServletSuperclass()) {
+			removeButton.setEnabled(true);
+			return;
+		} 
+		
+		// if the selection is non-empty and the servlet does not extend GenericServlet, 
+		// then the remove button is disabled only if the Servlet interface is in the selection
+		Iterator iter = selection.iterator();
+		while (iter.hasNext()) {
+			if (ServletSupertypesValidator.SERVLET_INTERFACE_NAME.equals(iter.next()))
+			removeButton.setEnabled(false);
+			return;
+		}
+
+		// in all other cases the remove button is enabled
+		removeButton.setEnabled(true);
+	}
 }