package j3t.wsfolder.doc;

/*v
 * Author: John
 * Created: 01 April 2005 07:32:44
 * Modified: 01 April 2005 07:32:44
 */


/*
To create your own custom template, create a copy of the Custom 
script in Tools/Eventhandlers/Java file/Templates and then modify 
it to create your own template.
*/
import java.io.*;
import java.io.IOException;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.w3c.dom.DocumentFragment;
import org.xml.sax.*;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.dom.DOMSource;

class StringDcMain
{
	
	public static void main (String args[])
	{
		try
		{
			StringEncrypter strEnc = new StringEncrypter("DESede");
			String decElement1= "CipherValue";
			String decElement2= "wsse:password";
			String filename= "encryptedmessage.xml";
			
			//get file to doc
			Document doc= parseXmlFile(filename, false);
			//System.out.println("****DOC*******");
			
			//get password element from encrypted file CipherValue = 0 and decrypt
			String passwordValue = getElementTextNodeValue (doc,"CipherValue",0);
			passwordValue = strEnc.decrypt(passwordValue);			
			//System.out.println("*****PASSWORD******");
			//System.out.println(passwordValue);
			
			//get password element from encrypted file CipherValue = 0 and decrypt
			String arg1 = getElementTextNodeValue (doc,"CipherValue",1);
			//System.out.println(arg1);
			arg1 = strEnc.decrypt(arg1);			
			//System.out.println("*****arg******");
			//System.out.println(arg1);
			
			
			//****************************************************************************************			
			
			
			
			//new doc
			Document cdoc = createDomDocument();
			// Insert the root element node
			Element element = cdoc.createElement("wsse:password");
			// Add a text node to the element
			element.appendChild(cdoc.createTextNode(passwordValue));
			cdoc.appendChild(element);			
			
			
			// get node 
			Node argnode = getNode (doc, "wsse:Password", 0);
			Node parent = argnode.getParentNode();
			parent.normalize();
			//System.out.println("TagName " + parent.getNodeName());
			Element el99 = (Element)parent;
			//System.out.println("TagName " + el99.getTagName());
			
			Node replacednode1 = replaceNode(doc,cdoc,parent);
			
			replacednode1.normalize();
			
			printDocument(doc);
			
			// Output doc
			//doc2file(doc, "UNencryptedmessage.xml");
			
			
			
			//****************************************************************************8
			
			//get file to doc
			Document Nextdoc= parseXmlFile("UNencryptedmessage", false);
			NodeList NL = Nextdoc.getElementsByTagName("arg1");			
			System.out.println(NL.getLength());
			
			
			printDocument(Nextdoc);
			
			// Output Nextdoc
			doc2file(Nextdoc, "newMessage.xml");
			
			
		}catch (Exception e) {}		
	}
	
	
	public static Document createDomDocument() {
		try {
			DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			Document doc = builder.newDocument();
			return doc;
		} catch (ParserConfigurationException e) {
		}
		return null;
	}
	
	
	
	// Get Node from Document.
	public static Node getNode (Document doc, String tagName, int itemPosition)
	{
		NodeList nodelist = doc.getElementsByTagName(tagName);
		// get node value and encrypt
		Node node = nodelist.item(itemPosition).getFirstChild();
		return node;
	}
	
	
	//create a cipher element from a Template (wsse) setting attribute (ID) elements value
	public static Document makeCipherFragment(String filename, String attributeID, String value)
	{
		// Create a Cipher fragment
		Document doc= parseXmlFile(filename, false);
		Element element= doc.getDocumentElement();
		//set ID attribute to Encrypted element tagname
		element.setAttribute(attributeID,value);
		return doc;
	}
	
	
	
	// returns String value of Elements child
	public static String getElementTextNodeValue (Document doc, String tagName, int childPostion)
	{
		// replace wsse:username with encrypted text
		NodeList nodelist = doc.getElementsByTagName(tagName);
		//get the next node TEXT and set value to encrypted node
		Node node = nodelist.item(childPostion).getFirstChild();
		return node.getNodeValue();
	}
	
	
	
	// replace Elements child text node with a value
	public static void replaceElementsTextNodevalue(Document doc,String tagname, String value, int childposition)
	{
		// replace CipherValue with encrypted text
		NodeList nodelist= doc.getElementsByTagName(tagname);
		//get the next node TEXT and set value to encrypted node
		Node node = nodelist.item(childposition).getFirstChild();
		node.setNodeValue(value);
	}
	
	
	// Dump it! to file
	//http://forum.java.sun.com/thread.jspa?threadID=599716&messageID=3244438
	static void doc2file(Document doc, String filename) throws Exception {
		try {
			TransformerFactory tFactory = TransformerFactory.newInstance();
			Transformer transformer = tFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StringWriter sw=new StringWriter();
			StreamResult result = new StreamResult(sw);
			transformer.transform(source, result);
			String xmlString=sw.toString();
			PrintWriter pw = new PrintWriter(
				new FileWriter(filename));
			pw.write(xmlString.toString());
			pw.close();
		} 
		catch (Exception e) {
			System.err.println(e.toString());
		}//catch
	}
	
	
	public static Node replaceNode(Document replacedDocument, Document replacingDocument, Node replacedNode){
		
		//Create a documentFragment of the replacingDocument
		DocumentFragment docFrag = replacingDocument.createDocumentFragment();
		Element rootElement = replacingDocument.getDocumentElement();
		docFrag.appendChild(rootElement);    
		
		
		//Import docFrag under the ownership of replacedDocument
		Node replacingNode = ((replacedDocument).importNode(docFrag, true)); 
		
		
		//In order to replace the node need to retrieve replacedNode's parent
		Node replaceNodeParent = replacedNode.getParentNode();
		replaceNodeParent.replaceChild(replacingNode, replacedNode);
		return replacedDocument;
	}
	
	// Prints Dom to Screen
	// throws IOException
	public static void printDocument(Document doc) throws IOException {
		OutputFormat of = new OutputFormat(doc);
		of.setPreserveSpace(true);
		XMLSerializer xs = new XMLSerializer(System.out, of);
		xs.serialize(doc);
		System.out.println();
	}//printDocument
	
	
	
	// Parses an XML file and returns a DOM document.
	// If validating is true, the contents is validated against the DTD
	// specified in the file.
	public static Document parseXmlFile(String filename, boolean validating) {
		try {
			// Create a builder factory
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			factory.setValidating(validating);
			
			// Create the builder and parse the file
			Document doc = factory.newDocumentBuilder().parse(new File(filename));
			return doc;
		} catch (SAXException e) {
			// A parsing error occurred; the xml input is not valid
		} catch (ParserConfigurationException e) {
		} catch (IOException e) {
		}
		return null;
	}//end
	
	
	// Parses a string containing XML and returns a DocumentFragment
	// containing the nodes of the parsed XML.
	public static DocumentFragment parseXml(Document doc, String fragment) {
		// Wrap the fragment in an arbitrary element
		fragment = "<fragment>"+fragment+"</fragment>";
		try {
			// Create a DOM builder and parse the fragment
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			Document d = factory.newDocumentBuilder().parse(new InputSource(new StringReader(fragment)));
			
			// Import the nodes of the new document into doc so that they
			// will be compatible with doc
			Node node = doc.importNode(d.getDocumentElement(), true);
			
			// Create the document fragment node to hold the new nodes
			DocumentFragment docfrag = doc.createDocumentFragment();
			
			// Move the nodes into the fragment
			while (node.hasChildNodes()) {
				docfrag.appendChild(node.removeChild(node.getFirstChild()));
			}
			
			// Return the fragment
			return docfrag;
		} catch (SAXException e) {
			// A parsing error occurred; the xml input is not valid
		} catch (ParserConfigurationException e) {
		} catch (IOException e) {
		}
		return null;
	}//end
	
}