/**
 * A bare-bones implementation of the ServletContext interface 
 * for use in JUnit test cases of the servlet code. Follows the 
 * NullObject pattern for any other methods.
 * 
 * @author Paul Gordon
 */

package org.biomoby.service.test;

import org.biomoby.shared.MobyPrefixResolver;
import org.w3c.dom.*;

import javax.xml.parsers.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.*;

public class TestServletConfig implements ServletConfig{
    private String name = null;
    private String className = null;
    private Hashtable initParams = new Hashtable();
    private ServletContext context = null;

    public TestServletConfig(String n, ServletContext cont){
	name = n;
	context = cont;
    }

    public TestServletConfig(ServletContext cont, java.net.URL u) throws Exception{
	context = cont;

	if(u == null){
	    name = "placeholderName";
	    className = "placeholderClassName";
	    return;
	}

	DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
	dbf.setNamespaceAware(true);	
	DocumentBuilder docBuilder = dbf.newDocumentBuilder();

	Element docRoot = null;
        try{
	    docRoot = docBuilder.parse(u.openStream()).getDocumentElement();
	    if(docRoot == null || !docRoot.getNodeName().equals("web-app")){
		throw new Exception("Invalid web.xml (" + u + "), no root web-app tag");
	    }
	} catch(Exception e){
	    throw new Exception("There appears to be a problem with the \"WEB-INF/web.xml\" file (" + 
				u + ", XML syntax?).\n" +
			       "While parsing it I encountered the error: " + e);
	}

	Element servletNode = MobyPrefixResolver.getChildElement(docRoot, "servlet");
	if(servletNode == null){
	    System.err.println("Could not find /web-app/servlet/ tag in " + 
			       u  + ", aborting!");
	    throw new Exception("Invalid web.xml (" + u +"), no servlet tag");
	}
	Element servletName = MobyPrefixResolver.getChildElement(servletNode, "servlet-name");
	if(servletName == null){
	    System.err.println("Could not find /web-app/servlet/servlet-name tag in " + 
			       u  + ", aborting!");
	    throw new Exception("Invalid web.xml (" + u +"), no servlet-name tag");
	}
	name = servletName.getTextContent();
	if(name.length() == 0){
	    throw new Exception("Invalid web.xml (" + u +"), servlet-name tag is blank (cannot have nameless servlet)");
	}

	Element servletClassName = MobyPrefixResolver.getChildElement(servletNode, "servlet-class");
	if(servletClassName == null){
	    System.err.println("Could not find /web-app/servlet/servlet-class tag in " + 
			       u  + ", aborting!");
	    throw new Exception("Invalid web.xml (" + u + "), no servlet-class tag");
	}
	className = servletClassName.getTextContent();
	if(className.length() == 0){
	    throw new Exception("Invalid web.xml (" + u +"), servlet-class tag is blank (cannot have nameless class)");
	}

	NodeList paramNodes = docRoot.getElementsByTagName("context-param");
	for(int i = 0; i < paramNodes.getLength(); i++){
	    Element paramNameTag = MobyPrefixResolver.getChildElement((Element) paramNodes.item(i), "param-name");
	    Element paramValueTag = MobyPrefixResolver.getChildElement((Element) paramNodes.item(i), "param-value");
	    if(paramNameTag == null || paramValueTag == null){
		System.err.println("Skipping context parameter #" + (i+1) + 
				   " because of undefined param-name or param-value tag");
		continue;
	    }
	    addInitParameter(paramNameTag.getTextContent(), paramValueTag.getTextContent());
	}
    }

    public String getInitParameter(String name){
	return (String) initParams.get(name);
    }

    public void addInitParameter(String name, String value){
	initParams.put(name, value);
    }

    public java.util.Enumeration getInitParameterNames(){
	return initParams.keys();
    }

    public ServletContext getServletContext(){
	return context;
    }

    public String getServletName(){
	return name;
    }

    public String getServletClassName(){
	return className;
    }

}
