<%@ jet package="org.eclipse.jst.j2ee.web" 
	imports="org.eclipse.jst.j2ee.internal.web.operations.* java.util.* " 
	class="ServletTemplate" 
%><%@ include file="servletHeader.template" %>

<%if (model.isPublic()) {%>public<%}%> <%if (model.isAbstract()) {%>abstract <%}%><%if (model.isFinal()) {%>final <%}
%>class <%=model.getClassName()%><%String superClass = model.getSuperclassName();
 if (! "".equals(superClass)) {%> extends <%=superClass%><%}%><%
 List<String> interfaces = model.getInterfaces(); 
 if (interfaces.size()>0) {%> implements <% }
 for (int i=0; i<interfaces.size(); i++) {
   String INTERFACE = (String) interfaces.get(i);
   if (i>0) { %>, <%}%><%=INTERFACE%><%}%> {
<% if (model.isGenericServletSuperclass()) { %>
	private static final long serialVersionUID = 1L;
<% } %>
<% if (!model.hasEmptySuperclassConstructor()) { %>

    /**
     * Default constructor. 
     */
    public <%=model.getClassName()%>() {
        // TODO Auto-generated constructor stub
    }
<% } %>
<% if (model.shouldGenSuperclassConstructors()) {
     List<Constructor> constructors = model.getConstructors();
     for (Constructor constructor : constructors) {
       if (constructor.isPublic() || constructor.isProtected()) { %>
       
    /**
     * @see <%=model.getSuperclassName()%>#<%=model.getSuperclassName()%>(<%=constructor.getParamsForJavadoc()%>)
     */
    public <%=model.getClassName()%>(<%=constructor.getParamsForDeclaration()%>) {
        super(<%=constructor.getParamsForCall()%>);
        // TODO Auto-generated constructor stub
    }
<% } } } %>
<% if (model.shouldGenInit()) { %>

	/**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		// TODO Auto-generated method stub<% if (model.isGenericServletSuperclass()) { %>
		super.init();<% } %>
	}<% } %><% if (model.shouldGenDestroy()) { %>

	/**
	 * @see Servlet#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub<% if (model.isGenericServletSuperclass()) { %>
		super.destroy();<% } %>
	}<% } %><% if (model.shouldGenGetServletConfig()) { %>

	/**
	 * @see Servlet#getServletConfig()
	 */
	public ServletConfig getServletConfig() {
		// TODO Auto-generated method stub<% if (model.isGenericServletSuperclass()) { %>
		return super.getServletConfig();<% } else { %>
		return null; <% } %>
	}<% } %><% if (model.shouldGenGetServletInfo()) { %>

	/**
	 * @see Servlet#getServletInfo()
	 */
	public String getServletInfo() {
		// TODO Auto-generated method stub<% if (model.isGenericServletSuperclass()) { %>
		return super.getServletInfo();<% } else { %>
		return null; <% } %>
	}<% } %><% if (model.shouldGenService() && !model.isHttpServletSuperclass()) { %>

	/**
	 * @see Servlet#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()) { %>

	/**
	 * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.service(request, response);
	}<% } %><% if (model.shouldGenDoGet()) { %>

	/**
	 * @see 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()) { %>

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doPost(request, response);
	}<% } %><% if (model.shouldGenDoPut()) { %>

	/**
	 * @see HttpServlet#doPut(HttpServletRequest, HttpServletResponse)
	 */
	protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doPut(request, response);
	}<% } %><% if (model.shouldGenDoDelete()) { %>

	/**
	 * @see HttpServlet#doDelete(HttpServletRequest, HttpServletResponse)
	 */
	protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doDelete(request, response);
	}<% } %><% if (model.shouldGenDoHead()) { %>

	/**
	 * @see HttpServlet#doHead(HttpServletRequest, HttpServletResponse)
	 */
	protected void doHead(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doHead(request, response);
	}<% } %><% if (model.shouldGenDoOptions()) { %>

	/**
	 * @see HttpServlet#doOptions(HttpServletRequest, HttpServletResponse)
	 */
	protected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doOptions(request, response);
	}<% } %><% if (model.shouldGenDoTrace()) { %>

	/**
	 * @see HttpServlet#doTrace(HttpServletRequest, HttpServletResponse)
	 */
	protected void doTrace(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doTrace(request, response);
	}<% } %>

}
