# HG changeset patch
# User František Kučera <franta-hg@frantovo.cz>
# Date 1325531752 -3600
# Node ID be5bfbe1f0cd952efaf5ed0bbfb658a43e286592
# Parent  c7e077699574ae6fe39f0e0d0c542ce2678c8d68
První nástřel – trochu už to funguje, převádí JSON na XML.

diff -r c7e077699574 -r be5bfbe1f0cd .hgignore
--- a/.hgignore	Mon Jan 02 19:23:46 2012 +0100
+++ b/.hgignore	Mon Jan 02 20:15:52 2012 +0100
@@ -1,3 +1,5 @@
 java/alt2xml/dist/*
 java/alt2xml/build/*
 java/alt2xml/nbproject/private/*
+
+temp/*
diff -r c7e077699574 -r be5bfbe1f0cd analýza/alt2xml.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analýza/alt2xml.txt	Mon Jan 02 20:15:52 2012 +0100
@@ -0,0 +1,22 @@
+Slouží k načítání souborů ve všelijakých syntaxích (json, ini atd.) tak, 
+aby s nimi následně šlo pracovat jako s XML.
+
+SAXParserFactory → SAXParser → XMLReader
+
+Nejdůležitější je XMLReader, tam se provádí vlastní načítání exotického souboru.
+
+Aby se použila správná (naše) továrna, je potřeba udělat něco z následujícího:
+	– nastavit systémovou vlastnost „javax.xml.parsers.SAXParserFactory“
+	– použít Services API… viz JavaDoc k newInstance()
+	– předat název třídy továrny jako parametr newInstance(…, …);
+
+Pak načítáme soubory, jako by to bylo XML:
+	SAXParserFactory továrna = SAXParserFactory.newInstance();
+	SAXParser parser = továrna.newSAXParser();
+	parser.parse(new File("data/vstup.json"), h);
+	
+Nikde sice nejsou žádné ostré závorky (např. JSON používá {} a []), 
+ale používáme stejné API a všechny navazující nástroje jako u opravdového XML.
+
+Náš SAXParser používá SuperXMLReader, který rozhoduje, který konkrétní parser se použije.
+
diff -r c7e077699574 -r be5bfbe1f0cd java/alt2xml/nbproject/project.properties
--- a/java/alt2xml/nbproject/project.properties	Mon Jan 02 19:23:46 2012 +0100
+++ b/java/alt2xml/nbproject/project.properties	Mon Jan 02 20:15:52 2012 +0100
@@ -1,9 +1,9 @@
 annotation.processing.enabled=true
 annotation.processing.enabled.in.editor=false
-annotation.processing.processor.options=
-annotation.processing.processors.list=
 annotation.processing.run.all.processors=true
 annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+application.title=alt2xml
+application.vendor=fiki
 build.classes.dir=${build.dir}/classes
 build.classes.excludes=**/*.java,**/*.form
 # This directory is removed when the project is cleaned:
@@ -24,17 +24,19 @@
 dist.dir=dist
 dist.jar=${dist.dir}/alt2xml.jar
 dist.javadoc.dir=${dist.dir}/javadoc
+endorsed.classpath=
 excludes=
 includes=**
 jar.compress=false
-javac.classpath=
+javac.classpath=\
+    ${libs.json-simple.classpath}
 # Space-separated list of extra javac options
 javac.compilerargs=
 javac.deprecation=false
 javac.processorpath=\
     ${javac.classpath}
-javac.source=1.6
-javac.target=1.6
+javac.source=1.7
+javac.target=1.7
 javac.test.classpath=\
     ${javac.classpath}:\
     ${build.classes.dir}
@@ -51,7 +53,7 @@
 javadoc.use=true
 javadoc.version=false
 javadoc.windowtitle=
-main.class=
+main.class=cz.frantovo.alt2xml.CLI
 manifest.file=manifest.mf
 meta.inf.dir=${src.dir}/META-INF
 mkdist.disabled=false
diff -r c7e077699574 -r be5bfbe1f0cd java/alt2xml/src/cz/frantovo/alt2xml/AltParser.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml/src/cz/frantovo/alt2xml/AltParser.java	Mon Jan 02 20:15:52 2012 +0100
@@ -0,0 +1,59 @@
+package cz.frantovo.alt2xml;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.xml.parsers.SAXParser;
+import org.xml.sax.Parser;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+
+/**
+ *
+ * @author fiki
+ */
+public class AltParser extends SAXParser {
+
+	private static final Logger log = Logger.getLogger(AltParser.class.getName());
+	private XMLReader superReader = new SuperReader();
+
+	@Override
+	public Parser getParser() throws SAXException {
+		// TODO: dopsat
+		log.log(Level.FINE, "getParser");
+		return null;
+	}
+
+	@Override
+	public XMLReader getXMLReader() throws SAXException {
+		return superReader;
+	}
+
+	@Override
+	public boolean isNamespaceAware() {
+		// TODO: dopsat
+		log.log(Level.FINE, "isNamespaceAware");
+		return false;
+	}
+
+	@Override
+	public boolean isValidating() {
+		// TODO: dopsat
+		log.log(Level.FINE, "isValidating");
+		return false;
+	}
+
+	@Override
+	public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
+		// TODO: dopsat
+		log.log(Level.FINE, "setProperty: {0} = {1}", new Object[]{name, value});
+	}
+
+	@Override
+	public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
+		// TODO: dopsat
+		log.log(Level.FINE, "getProperty: {0}", name);
+		return null;
+	}
+}
diff -r c7e077699574 -r be5bfbe1f0cd java/alt2xml/src/cz/frantovo/alt2xml/CLI.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml/src/cz/frantovo/alt2xml/CLI.java	Mon Jan 02 20:15:52 2012 +0100
@@ -0,0 +1,30 @@
+package cz.frantovo.alt2xml;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamWriter;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ *
+ * @author fiki
+ */
+public class CLI {
+
+	public static void main(String[] args) throws Exception {
+		InputStream vstup = System.in;
+		OutputStream výstup = System.out;
+
+		SAXParserFactory t = SAXParserFactory.newInstance(SAXTovarna.class.getName(), null);
+		SAXParser p = t.newSAXParser();
+
+		XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newFactory();
+		XMLStreamWriter w = xmlOutputFactory.createXMLStreamWriter(výstup);
+		DefaultHandler h = new EchoContentHandler(w);
+
+		p.parse(vstup, h);
+	}
+}
diff -r c7e077699574 -r be5bfbe1f0cd java/alt2xml/src/cz/frantovo/alt2xml/EchoContentHandler.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml/src/cz/frantovo/alt2xml/EchoContentHandler.java	Mon Jan 02 20:15:52 2012 +0100
@@ -0,0 +1,83 @@
+package cz.frantovo.alt2xml;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Slouží k převodu právě parsovaného XML zpět na XML.
+ * Určen pro testování a ladění a pro použití s neobvyklými „XML“ parsery,
+ * které nečtou XML ale jiný jazyk (např. JSON, INI atd.), ale používají stejné rozhraní (SAX).
+ * 
+ * TODO: další typy uzlů a jmenné prostory.
+ * @author fiki
+ */
+public class EchoContentHandler extends DefaultHandler {
+
+	private XMLStreamWriter w;
+
+	/**
+	 * @param writer kam se bude vypisovat XML.
+	 */
+	public EchoContentHandler(XMLStreamWriter writer) {
+		w = writer;
+	}
+
+	@Override
+	public void startDocument() throws SAXException {
+		try {
+			w.writeStartDocument();
+		} catch (XMLStreamException e) {
+			throw new SAXException(e);
+		}
+	}
+
+	@Override
+	public void endDocument() throws SAXException {
+		try {
+			w.writeEndDocument();
+			w.close();
+		} catch (XMLStreamException e) {
+			throw new SAXException(e);
+		}
+	}
+
+	@Override
+	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+		try {
+			w.writeStartElement(qName);
+
+			if (attributes != null) {
+				for (int i = 0; i < attributes.getLength(); i++) {
+					w.writeAttribute(attributes.getQName(i), attributes.getValue(i));
+				}
+			}
+
+			w.flush();
+		} catch (XMLStreamException e) {
+			throw new SAXException(e);
+		}
+	}
+
+	@Override
+	public void endElement(String uri, String localName, String qName) throws SAXException {
+		try {
+			w.writeEndElement();
+			w.flush();
+		} catch (XMLStreamException e) {
+			throw new SAXException(e);
+		}
+	}
+
+	@Override
+	public void characters(char[] ch, int start, int length) throws SAXException {
+		try {
+			w.writeCharacters(ch, start, length);
+			w.flush();
+		} catch (XMLStreamException e) {
+			throw new SAXException(e);
+		}
+	}
+}
diff -r c7e077699574 -r be5bfbe1f0cd java/alt2xml/src/cz/frantovo/alt2xml/JsonSimpleContentHandler.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml/src/cz/frantovo/alt2xml/JsonSimpleContentHandler.java	Mon Jan 02 20:15:52 2012 +0100
@@ -0,0 +1,103 @@
+package cz.frantovo.alt2xml;
+
+import java.io.IOException;
+import java.util.Stack;
+import org.json.simple.parser.ParseException;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+) *
+ * @author fiki
+ */
+public class JsonSimpleContentHandler implements org.json.simple.parser.ContentHandler {
+
+	/** Sem vypisujeme XML události */
+	private ContentHandler saxVýstup;
+	/** Musíme si pamatovat polohu v XML stromu, abychom věděli, kterou značku kdy uzavřít */
+	private Stack<String> poloha = new Stack<>();
+
+	public JsonSimpleContentHandler(ContentHandler saxVýstup) {
+		this.saxVýstup = saxVýstup;
+	}
+
+	@Override
+	public void startJSON() throws ParseException, IOException {
+		try {
+			saxVýstup.startDocument();
+			saxVýstup.startElement(null, null, "json", null);
+		} catch (SAXException e) {
+			throw new IOException(e);
+		}
+	}
+
+	@Override
+	public void endJSON() throws ParseException, IOException {
+		try {
+			saxVýstup.endElement(null, null, "json");
+			saxVýstup.endDocument();
+		} catch (SAXException e) {
+			throw new IOException(e);
+		}
+	}
+
+	@Override
+	public boolean startObject() throws ParseException, IOException {
+		// System.err.println("startObject");
+		return true;
+	}
+
+	@Override
+	public boolean endObject() throws ParseException, IOException {
+		// System.err.println("endObject");
+		return true;
+	}
+
+	@Override
+	public boolean startObjectEntry(String key) throws ParseException, IOException {
+		try {
+			saxVýstup.startElement(null, null, key, null);
+			poloha.push(key);
+		} catch (SAXException e) {
+			throw new IOException(e);
+		}
+		// System.err.println("startObjectEntry: " + key);
+		return true;
+	}
+
+	@Override
+	public boolean endObjectEntry() throws ParseException, IOException {
+		try {
+			String značka = poloha.pop();
+			saxVýstup.endElement(null, null, značka);
+		} catch (SAXException e) {
+			throw new IOException(e);
+		}
+		// System.err.println("endObjectEntry");
+		return true;
+	}
+
+	@Override
+	public boolean startArray() throws ParseException, IOException {
+		// System.err.println("startArray");
+		return true;
+	}
+
+	@Override
+	public boolean endArray() throws ParseException, IOException {
+		// System.err.println("endArray");
+		return true;
+	}
+
+	@Override
+	public boolean primitive(Object value) throws ParseException, IOException {
+		try {
+			String hodnota = String.valueOf(value);
+			saxVýstup.characters(hodnota.toCharArray(), 0, hodnota.length());
+		} catch (SAXException e) {
+			throw new IOException(e);
+		}
+		// System.err.println("primitive: " + value);
+		return true;
+	}
+}
diff -r c7e077699574 -r be5bfbe1f0cd java/alt2xml/src/cz/frantovo/alt2xml/SAXTovarna.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml/src/cz/frantovo/alt2xml/SAXTovarna.java	Mon Jan 02 20:15:52 2012 +0100
@@ -0,0 +1,31 @@
+package cz.frantovo.alt2xml;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+
+/**
+ *
+ * @author fiki
+ */
+public class SAXTovarna extends SAXParserFactory {
+
+	@Override
+	public SAXParser newSAXParser() throws ParserConfigurationException, SAXException {
+		return new AltParser();
+	}
+
+	@Override
+	public void setFeature(String name, boolean value) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException {
+		throw new UnsupportedOperationException("Not supported yet.");
+	}
+
+	@Override
+	public boolean getFeature(String name) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException {
+		throw new UnsupportedOperationException("Not supported yet.");
+	}
+	
+}
diff -r c7e077699574 -r be5bfbe1f0cd java/alt2xml/src/cz/frantovo/alt2xml/SuperReader.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml/src/cz/frantovo/alt2xml/SuperReader.java	Mon Jan 02 20:15:52 2012 +0100
@@ -0,0 +1,128 @@
+package cz.frantovo.alt2xml;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+
+/**
+ *
+ * @author fiki
+ */
+public class SuperReader implements XMLReader {
+
+	private static final Logger log = Logger.getLogger(SuperReader.class.getName());
+	private ContentHandler contentHandler;
+
+	@Override
+	public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
+		// TODO: dopsat
+		log.log(Level.FINE, "getFeature: {0}", name);
+		return false;
+	}
+
+	@Override
+	public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException {
+		// TODO: dopsat
+		log.log(Level.FINE, "setFeature: {0} = {1}", new Object[]{name, value});
+	}
+
+	@Override
+	public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
+		// TODO: dopsat
+		log.log(Level.FINE, "getProperty: {0}", name);
+		return null;
+	}
+
+	@Override
+	public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
+		// TODO: dopsat
+		log.log(Level.FINE, "setProperty: {0} = {1}", new Object[]{name, value});
+	}
+
+	@Override
+	public void setEntityResolver(EntityResolver resolver) {
+		// TODO: dopsat
+		log.log(Level.FINE, "setEntityResolver: {0}", resolver);
+	}
+
+	@Override
+	public EntityResolver getEntityResolver() {
+		// TODO: dopsat
+		log.log(Level.FINE, "getEntityResolver");
+		return null;
+	}
+
+	@Override
+	public void setDTDHandler(DTDHandler handler) {
+		// TODO: dopsat
+		log.log(Level.FINE, "setDTDHandler: {0}", handler);
+	}
+
+	@Override
+	public DTDHandler getDTDHandler() {
+		// TODO: dopsat
+		log.log(Level.FINE, "getDTDHandler");
+		return null;
+	}
+
+	@Override
+	public void setContentHandler(ContentHandler handler) {
+		// TODO: dopsat
+		contentHandler = handler;
+	}
+
+	@Override
+	public ContentHandler getContentHandler() {
+		// TODO: dopsat
+		return contentHandler;
+	}
+
+	@Override
+	public void setErrorHandler(ErrorHandler handler) {
+		// TODO: dopsat
+		log.log(Level.FINE, "setErrorHandler: {0}", handler);
+	}
+
+	@Override
+	public ErrorHandler getErrorHandler() {
+		// TODO: dopsat
+		log.log(Level.FINE, "getErrorHandler");
+		return null;
+	}
+
+	@Override
+	public void parse(InputSource input) throws IOException, SAXException {
+		/**
+		 * TODO: rozpornat formát vstupu a podle toho delegovat
+		 */
+		
+		JSONParser p = new JSONParser();
+		InputStreamReader vstup = new InputStreamReader(input.getByteStream());
+		JsonSimpleContentHandler handler = new JsonSimpleContentHandler(contentHandler);
+
+		try {
+			p.parse(vstup, handler);
+		} catch (ParseException e) {
+			throw new SAXException("Chyba při načítání JSONu", e);
+		}
+	}
+
+	@Override
+	public void parse(String systemId) throws IOException, SAXException {
+		// TODO: dopsat
+		throw new UnsupportedOperationException("Zatím není podporované.");
+	}
+}