/*PURPOSE:This is a servelet which given the the filled in XML form will write the data to an xml document		The servlet then produces a redirect to the Start Form 
BY: 	Charles Pugh
DATE:	30/8/2000
*/
import java.io.*;
import java.util.*;
import org.w3c.dom.*;import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import com.sun.xml.tree.*;

public class saveform extends HttpServlet {
	String xmlFileName;
	String xmlLocation;
	String SchemaFileName;
	String SchemaLocation;
	String[] elementNames = new String[20];
	String[] elementValues = new String[20];
	Document schemaDoc;
	Document document;
	PrintWriter out;
	Writer fileOut;
    String sep = "";
	int noOfElements = 0;
	//String[] elName = new String[20];
	
  public void doGet(HttpServletRequest request,HttpServletResponse response)
																	throws ServletException, IOException {
    response.setContentType("text/html");
    out = response.getWriter();
	
	xmlFileName = request.getParameter("XMLFileName");
	xmlLocation = request.getParameter("FileDIR");
	SchemaFileName = request.getParameter("Schema");
	SchemaLocation = request.getParameter("SchemaDIR");
	
	Enumeration paramNames = request.getParameterNames();
	int i = 0;
	noOfElements = 0;
    while(paramNames.hasMoreElements()) {
      String paramName = (String)paramNames.nextElement();
	  elementNames[i] = paramName;
      String[] paramValues = request.getParameterValues(paramName);
	  
      if (paramValues.length == 1) {
        elementValues[i] = paramValues[0];
      }//end if
	  
	  else {
        for(int j=0; j<paramValues.length; j++) {
			elementValues[i] = elementValues[i] + paramValues[j];
        }//end for
      }//end else
	  
	  i++;
	  noOfElements++;
    }//end while
	
	writeHTML();
  }

  public void doPost(HttpServletRequest request,HttpServletResponse response)
																	throws ServletException, IOException {
    doGet(request, response);
  }//end doPost
  
  public void writeHTML(){
	  
	String title = "Saving XML Document ";
    out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n" +
                "<HTML>\n" +
				"<HEAD><META HTTP-EQUIV=\"REFRESH\"CONTENT = \"5; URL=http://www.uea.ac.uk/~a919538/schema.html\">" +
				"<TITLE>Your XML document is being Saved</TITLE></HEAD>\n" +
                "<BODY BGCOLOR=\"#FDF5E6\">\n" +
                "<H1 ALIGN=CENTER>" + title + "</H1>\n");

	parseXML();
	
    out.println("</BODY></HTML>");
  }//end writeHTML
  
  public void parseXML(){

	try {		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
		schemaDoc = docBuilder.parse (new File (SchemaLocation,  SchemaFileName));
		document = docBuilder.newDocument ();
		changeXMLDoc();
		
		XMLOut(document, xmlFileName);
	}//end Try
	
	catch (SAXParseException err) {System.out.println ("** Parsing error" 
														+ ", line " + err.getLineNumber ()
														+ ", uri " + err.getSystemId ());
        parseError("   " + err.getMessage ());
        // print stack trace as below
    } 	catch (SAXException e) {} 
	catch (Throwable t) {}
  }//end parseXML
  
  public void parseError (String error){
	out.println("" + error);
  }//end parse error
  
  public void changeXMLDoc(){	Node elem1 = schemaDoc.getDocumentElement().getChildNodes().item(1);
	
	String SchemaName = elem1.getAttributes().item(0).getNodeValue();
	
	String type = findType(elem1);
	Element root;
	
	if (type == "simple")
		dealWithSimple(elem1);
	if (type == "complex"){
		root = dealWithComplex(elem1);			document.appendChild(root);
	}  }//end changeXMLDoc    public String findType(Node el){
	String type = "simple";
	if (el.getChildNodes().getLength() > 0){
		for(int i=1; i < el.getChildNodes().getLength(); i=i+2){
			if(el.getChildNodes().item(i).getNodeName() == "xsd:complexType")
				type = "complex";
		 }//end for
	 }//end if
	 else
		  type = "simple";
	 return type;	
  }//end findType    public Element dealWithSimple (Node el){
    String value = "No match"; 
	String tagName = el.getAttributes().getNamedItem("name").getNodeValue();
	
	Element e = (document.createElement(tagName));
	
	//maches parameter value with tag 
	for(int i=0; i<noOfElements; i++){
		if (elementNames[i].equals(tagName)){	
			value = elementValues[i];
		}
	} 
	Text t = (document.createTextNode(value));
	e.appendChild(t);
	return e;
  }//end DealWithSimple
    public Element dealWithComplex(Node el){	
	DocumentFragment docFrag = document.createDocumentFragment();
	
	String value = el.getAttributes().getNamedItem("name").getNodeValue();
	
	Element dElement = document.createElement(value);
	
	Node elem2 =  el.getChildNodes().item(1);

	for (int i=1; i < elem2.getChildNodes().getLength(); i=i+2){
		String type = findType(elem2.getChildNodes().item(i));
		if (type == "simple")
			docFrag.appendChild(dealWithSimple(elem2.getChildNodes().item(i)));
		else if (type == "complex"){
			docFrag.appendChild(dealWithComplex(elem2.getChildNodes().item(i)));
		}
	}//end for	
		dElement.appendChild(docFrag);		
	return dElement;
  }//end dealWithComplex
  
  private void XMLOut (Document outDoc, String fil)throws SAXException{	  
        try{    
            if (fil.length() > 0) {
                fileOut = new FileWriter (new File (fil));
            } 			else {
                fileOut = new OutputStreamWriter (System.out, "UTF8");
            }
            emit ("<?xml version='1.0' encoding='UTF-8'?>\n");
            XMLOutElement (outDoc.getDocumentElement(), "");						out.println("<BR>");
			out.println("<BR>");			out.println("<BR>");
			out.println("<P><h2><CENTER> Your XML File  : <P><I>" + xmlFileName + "</I></CENTER>");
			out.println("<BR>");			out.println("<BR>");
			out.println("<BR>");			out.println("<P><CENTER> Has been successfully saved to : <P><I>" + xmlLocation + "</I></CENTER><h2>");			out.println("<BR>");
			out.println("<BR>");
			out.println("<BR>");			out.println("<P><h3><CENTER>Please Wait.....</CENTER><h3>");			
        } catch (IOException e) {throw new SAXException("File Error", e);}
  }//end XMLout

  private void XMLOutElement (Element el, String pre)throws SAXException
  {
    // Processing for opening tag
    emit (pre + "<" + el.getTagName());
    // Processing for attributes NEEDED
    emit (">\n");
    // Output contents - Could elide for null contents
    XMLOutNodeList (el.getFirstChild (), pre);
    // Processing for closing tag
    emit (pre + "</" + el.getTagName() + ">\n");
  }//end XMLOutElement

  private void XMLOutNodeList (Node nd, String pre)throws SAXException {
    while (nd != null) {
       switch (nd.getNodeType()) {				
          case nd.TEXT_NODE:
             // Note: may need to extract data in chunks
             if (hasText ((Text) nd)) {
             emit (pre + nd.getNodeValue() + "\n");
             }
             break;

             case nd.ELEMENT_NODE:
             XMLOutElement ((Element) nd, pre + sep);
             break;
        }//end switch
        nd = nd.getNextSibling ();
     }//end while
   }//end XMLOutNodeList
  
  private boolean hasText (Text tx){
    return (tx.getData().trim().length() > 0);
  }//end hasText

  private void emit (String s)throws SAXException {
	try {
        fileOut.write (s);
        fileOut.flush ();
	} 	catch (IOException e) {throw new SAXException ("I/O error", e);}
  }//end emit
}//endSaveForm