# HG changeset patch
# User František Kučera <franta-hg@frantovo.cz>
# Date 1325591738 -3600
# Node ID 6c608fd8c0192e0c03018b13730b74735b0b2e27
# Parent  be5bfbe1f0cd952efaf5ed0bbfb658a43e286592
Přehlednější struktura tříd/balíčků.

diff -r be5bfbe1f0cd -r 6c608fd8c019 java/alt2xml/src/cz/frantovo/alt2xml/AltParser.java
--- a/java/alt2xml/src/cz/frantovo/alt2xml/AltParser.java	Mon Jan 02 20:15:52 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-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 be5bfbe1f0cd -r 6c608fd8c019 java/alt2xml/src/cz/frantovo/alt2xml/CLI.java
--- a/java/alt2xml/src/cz/frantovo/alt2xml/CLI.java	Mon Jan 02 20:15:52 2012 +0100
+++ b/java/alt2xml/src/cz/frantovo/alt2xml/CLI.java	Tue Jan 03 12:55:38 2012 +0100
@@ -1,5 +1,6 @@
 package cz.frantovo.alt2xml;
 
+import cz.frantovo.alt2xml.výstup.EchoContentHandler;
 import java.io.InputStream;
 import java.io.OutputStream;
 import javax.xml.parsers.SAXParser;
@@ -15,16 +16,27 @@
 public class CLI {
 
 	public static void main(String[] args) throws Exception {
+		/**
+		 * Použijeme standardní vstup a výstup:
+		 */
 		InputStream vstup = System.in;
 		OutputStream výstup = System.out;
-
-		SAXParserFactory t = SAXParserFactory.newInstance(SAXTovarna.class.getName(), null);
-		SAXParser p = t.newSAXParser();
-
+		
+		/**
+		 * Serializujeme data do XML.
+		 * To normálně vůbec není potřeba – data se do tvaru proudu obsahujícího ostré závorky
+		 * vůbec nedostanou – zpracováváme události (volání javovských metod – začátky a konce elementů atd.)
+		 * a z nich např. deserializujeme nějaké naše objekty, provádíme nějaké akce, nebo třeba stavíme DOM.
+		 */
 		XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newFactory();
 		XMLStreamWriter w = xmlOutputFactory.createXMLStreamWriter(výstup);
 		DefaultHandler h = new EchoContentHandler(w);
-
+		
+		/**
+		 * Parsujeme JSON a děláme z něj XML:
+		 */
+		SAXParserFactory t = SAXParserFactory.newInstance(SAXTovarna.class.getName(), null);
+		SAXParser p = t.newSAXParser();
 		p.parse(vstup, h);
 	}
 }
diff -r be5bfbe1f0cd -r 6c608fd8c019 java/alt2xml/src/cz/frantovo/alt2xml/EchoContentHandler.java
--- a/java/alt2xml/src/cz/frantovo/alt2xml/EchoContentHandler.java	Mon Jan 02 20:15:52 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-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 be5bfbe1f0cd -r 6c608fd8c019 java/alt2xml/src/cz/frantovo/alt2xml/JsonSimpleContentHandler.java
--- a/java/alt2xml/src/cz/frantovo/alt2xml/JsonSimpleContentHandler.java	Mon Jan 02 20:15:52 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-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 be5bfbe1f0cd -r 6c608fd8c019 java/alt2xml/src/cz/frantovo/alt2xml/SAXTovarna.java
--- a/java/alt2xml/src/cz/frantovo/alt2xml/SAXTovarna.java	Mon Jan 02 20:15:52 2012 +0100
+++ b/java/alt2xml/src/cz/frantovo/alt2xml/SAXTovarna.java	Tue Jan 03 12:55:38 2012 +0100
@@ -1,11 +1,16 @@
 package cz.frantovo.alt2xml;
 
+import cz.frantovo.alt2xml.vstup.SuperReader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
+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;
 
 /**
  *
@@ -15,7 +20,7 @@
 
 	@Override
 	public SAXParser newSAXParser() throws ParserConfigurationException, SAXException {
-		return new AltParser();
+		return new MůjParser(new SuperReader());
 	}
 
 	@Override
@@ -27,5 +32,53 @@
 	public boolean getFeature(String name) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException {
 		throw new UnsupportedOperationException("Not supported yet.");
 	}
-	
-}
+
+	private static class MůjParser extends SAXParser {
+
+		private static final Logger log = Logger.getLogger(MůjParser.class.getName());
+		private XMLReader xmlReader;
+
+		public MůjParser(XMLReader xmlReader) {
+			this.xmlReader = xmlReader;
+		}
+
+		@Override
+		public Parser getParser() throws SAXException {
+			// TODO: dopsat
+			log.log(Level.FINE, "getParser");
+			return null;
+		}
+
+		@Override
+		public XMLReader getXMLReader() throws SAXException {
+			return xmlReader;
+		}
+
+		@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;
+		}
+	}
+}
\ No newline at end of file
diff -r be5bfbe1f0cd -r 6c608fd8c019 java/alt2xml/src/cz/frantovo/alt2xml/SuperReader.java
--- a/java/alt2xml/src/cz/frantovo/alt2xml/SuperReader.java	Mon Jan 02 20:15:52 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-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é.");
-	}
-}
diff -r be5bfbe1f0cd -r 6c608fd8c019 java/alt2xml/src/cz/frantovo/alt2xml/vstup/JsonSimpleContentHandler.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml/src/cz/frantovo/alt2xml/vstup/JsonSimpleContentHandler.java	Tue Jan 03 12:55:38 2012 +0100
@@ -0,0 +1,135 @@
+package cz.frantovo.alt2xml.vstup;
+
+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<>();
+	/**
+	 * Po textových uzlech vkládáme konce elementů rovnou,
+	 * ale pokud jeden element končí hned po jiném, 
+	 * vložíme mezi ně ještě konec řádku a odsazení.
+	 */
+	private boolean zalomitŘádek = false;
+
+	public JsonSimpleContentHandler(ContentHandler saxVýstup) {
+		this.saxVýstup = saxVýstup;
+	}
+
+	private void začniElement(String název) throws IOException {
+		try {
+			vložOdsazení();
+			saxVýstup.startElement(null, null, název, null);
+			poloha.push(název);
+		} catch (SAXException e) {
+			throw new IOException("Chyba při začátku elementu.", e);
+		}
+	}
+
+	private void ukončiElement() throws IOException {
+		try {
+			String značka = poloha.pop();
+			if (zalomitŘádek) {
+				vložOdsazení();
+			}
+			zalomitŘádek = true;
+			saxVýstup.endElement(null, null, značka);
+		} catch (SAXException e) {
+			throw new IOException("Chyba při ukončování elementu.", e);
+		}
+	}
+
+	private void vložOdsazení() throws IOException {
+		/**
+		 * TODO: ignorableWhitespace() ?
+		 */
+		vložText("\n");
+		for (int i = 0; i < poloha.size(); i++) {
+			vložText("\t");
+		}
+	}
+
+	private void vložText(String text) throws IOException {
+		try {
+			saxVýstup.characters(text.toCharArray(), 0, text.length());
+		} catch (SAXException e) {
+			throw new IOException("Chyba při vkládání textu.", e);
+		}
+	}
+
+	@Override
+	public void startJSON() throws ParseException, IOException {
+		try {
+			saxVýstup.startDocument();
+			začniElement("objekt");
+		} catch (SAXException e) {
+			throw new IOException("Chyba při začátku dokumentu.", e);
+		}
+	}
+
+	@Override
+	public void endJSON() throws ParseException, IOException {
+		try {
+			ukončiElement();
+			vložText("\n");
+			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 {
+		začniElement(key);
+		return true;
+	}
+
+	@Override
+	public boolean endObjectEntry() throws ParseException, IOException {
+		ukončiElement();
+		// 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 {
+		vložText(String.valueOf(value));
+		zalomitŘádek = false;
+		return true;
+	}
+}
diff -r be5bfbe1f0cd -r 6c608fd8c019 java/alt2xml/src/cz/frantovo/alt2xml/vstup/SuperReader.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml/src/cz/frantovo/alt2xml/vstup/SuperReader.java	Tue Jan 03 12:55:38 2012 +0100
@@ -0,0 +1,127 @@
+package cz.frantovo.alt2xml.vstup;
+
+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é.");
+	}
+}
diff -r be5bfbe1f0cd -r 6c608fd8c019 java/alt2xml/src/cz/frantovo/alt2xml/výstup/EchoContentHandler.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml/src/cz/frantovo/alt2xml/výstup/EchoContentHandler.java	Tue Jan 03 12:55:38 2012 +0100
@@ -0,0 +1,83 @@
+package cz.frantovo.alt2xml.výstup;
+
+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);
+		}
+	}
+}