package przyklady.software;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.DOMException;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;

import util.Args;

import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSException;

/** Przyklad do artykulu "XML w Javie 5.0" (Software 2.0, 6/2005).
    Przyklad budowania, modyfikowania i zapisywania do pliku drzewa DOM,
    a takze walidacji, korzystajac z obiektu typu Schema, podczas parsowania
    i niezaleznie od parsowania.
    Marzec 2005
    @author Patryk Czarnik
*/
public class DOMExample {
   public static void main(String args[]) {
		args = Args.argsOrDefault(args, "rooms.xml", "new_DOMExample.xml", "school.xsd", "root.xsd", "utf-8");
      try {
         SchemaFactory sfactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
         Schema schema1 = sfactory.newSchema(new StreamSource(args[2]));
         Schema schema2 = sfactory.newSchema(new StreamSource(args[3]));

         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
         factory.setValidating(false);
         factory.setSchema(schema1);
         DocumentBuilder parser = factory.newDocumentBuilder();
         Document doc = parser.parse(args[0]);
         modifyDocument(doc);
         Validator validator = schema2.newValidator();
         validator.validate(new DOMSource(doc));
         saveDocument(doc, args[1], args[4]);
         System.out.println("Gotowe");

      } catch(Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }
   }

   public static void modifyDocument(Document doc) {
      Element newRoot = doc.createElement("root");
      Element oldRoot = doc.getDocumentElement();
      doc.replaceChild(newRoot, oldRoot);
      newRoot.appendChild(oldRoot);
   }

   public static void saveDocument(Document doc, String fileName, String encoding)
      throws LSException, DOMException, FileNotFoundException {
      DOMImplementation di = doc.getImplementation();
      DOMImplementationLS lsi = (DOMImplementationLS) di.getFeature("LS", "3.0");
      LSSerializer ser = lsi.createLSSerializer();
      LSOutput out = lsi.createLSOutput();
      out.setSystemId(fileName);
      out.setByteStream(new BufferedOutputStream(new FileOutputStream(fileName)));
      out.setEncoding(encoding);
      ser.write(doc, out);
   }
}
