První nástřel – trochu už to funguje, převádí JSON na XML.
1.1 --- a/.hgignore Mon Jan 02 19:23:46 2012 +0100
1.2 +++ b/.hgignore Mon Jan 02 20:15:52 2012 +0100
1.3 @@ -1,3 +1,5 @@
1.4 java/alt2xml/dist/*
1.5 java/alt2xml/build/*
1.6 java/alt2xml/nbproject/private/*
1.7 +
1.8 +temp/*
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/analýza/alt2xml.txt Mon Jan 02 20:15:52 2012 +0100
2.3 @@ -0,0 +1,22 @@
2.4 +Slouží k načítání souborů ve všelijakých syntaxích (json, ini atd.) tak,
2.5 +aby s nimi následně šlo pracovat jako s XML.
2.6 +
2.7 +SAXParserFactory → SAXParser → XMLReader
2.8 +
2.9 +Nejdůležitější je XMLReader, tam se provádí vlastní načítání exotického souboru.
2.10 +
2.11 +Aby se použila správná (naše) továrna, je potřeba udělat něco z následujícího:
2.12 + – nastavit systémovou vlastnost „javax.xml.parsers.SAXParserFactory“
2.13 + – použít Services API… viz JavaDoc k newInstance()
2.14 + – předat název třídy továrny jako parametr newInstance(…, …);
2.15 +
2.16 +Pak načítáme soubory, jako by to bylo XML:
2.17 + SAXParserFactory továrna = SAXParserFactory.newInstance();
2.18 + SAXParser parser = továrna.newSAXParser();
2.19 + parser.parse(new File("data/vstup.json"), h);
2.20 +
2.21 +Nikde sice nejsou žádné ostré závorky (např. JSON používá {} a []),
2.22 +ale používáme stejné API a všechny navazující nástroje jako u opravdového XML.
2.23 +
2.24 +Náš SAXParser používá SuperXMLReader, který rozhoduje, který konkrétní parser se použije.
2.25 +
3.1 --- a/java/alt2xml/nbproject/project.properties Mon Jan 02 19:23:46 2012 +0100
3.2 +++ b/java/alt2xml/nbproject/project.properties Mon Jan 02 20:15:52 2012 +0100
3.3 @@ -1,9 +1,9 @@
3.4 annotation.processing.enabled=true
3.5 annotation.processing.enabled.in.editor=false
3.6 -annotation.processing.processor.options=
3.7 -annotation.processing.processors.list=
3.8 annotation.processing.run.all.processors=true
3.9 annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
3.10 +application.title=alt2xml
3.11 +application.vendor=fiki
3.12 build.classes.dir=${build.dir}/classes
3.13 build.classes.excludes=**/*.java,**/*.form
3.14 # This directory is removed when the project is cleaned:
3.15 @@ -24,17 +24,19 @@
3.16 dist.dir=dist
3.17 dist.jar=${dist.dir}/alt2xml.jar
3.18 dist.javadoc.dir=${dist.dir}/javadoc
3.19 +endorsed.classpath=
3.20 excludes=
3.21 includes=**
3.22 jar.compress=false
3.23 -javac.classpath=
3.24 +javac.classpath=\
3.25 + ${libs.json-simple.classpath}
3.26 # Space-separated list of extra javac options
3.27 javac.compilerargs=
3.28 javac.deprecation=false
3.29 javac.processorpath=\
3.30 ${javac.classpath}
3.31 -javac.source=1.6
3.32 -javac.target=1.6
3.33 +javac.source=1.7
3.34 +javac.target=1.7
3.35 javac.test.classpath=\
3.36 ${javac.classpath}:\
3.37 ${build.classes.dir}
3.38 @@ -51,7 +53,7 @@
3.39 javadoc.use=true
3.40 javadoc.version=false
3.41 javadoc.windowtitle=
3.42 -main.class=
3.43 +main.class=cz.frantovo.alt2xml.CLI
3.44 manifest.file=manifest.mf
3.45 meta.inf.dir=${src.dir}/META-INF
3.46 mkdist.disabled=false
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/java/alt2xml/src/cz/frantovo/alt2xml/AltParser.java Mon Jan 02 20:15:52 2012 +0100
4.3 @@ -0,0 +1,59 @@
4.4 +package cz.frantovo.alt2xml;
4.5 +
4.6 +import java.util.logging.Level;
4.7 +import java.util.logging.Logger;
4.8 +import javax.xml.parsers.SAXParser;
4.9 +import org.xml.sax.Parser;
4.10 +import org.xml.sax.SAXException;
4.11 +import org.xml.sax.SAXNotRecognizedException;
4.12 +import org.xml.sax.SAXNotSupportedException;
4.13 +import org.xml.sax.XMLReader;
4.14 +
4.15 +/**
4.16 + *
4.17 + * @author fiki
4.18 + */
4.19 +public class AltParser extends SAXParser {
4.20 +
4.21 + private static final Logger log = Logger.getLogger(AltParser.class.getName());
4.22 + private XMLReader superReader = new SuperReader();
4.23 +
4.24 + @Override
4.25 + public Parser getParser() throws SAXException {
4.26 + // TODO: dopsat
4.27 + log.log(Level.FINE, "getParser");
4.28 + return null;
4.29 + }
4.30 +
4.31 + @Override
4.32 + public XMLReader getXMLReader() throws SAXException {
4.33 + return superReader;
4.34 + }
4.35 +
4.36 + @Override
4.37 + public boolean isNamespaceAware() {
4.38 + // TODO: dopsat
4.39 + log.log(Level.FINE, "isNamespaceAware");
4.40 + return false;
4.41 + }
4.42 +
4.43 + @Override
4.44 + public boolean isValidating() {
4.45 + // TODO: dopsat
4.46 + log.log(Level.FINE, "isValidating");
4.47 + return false;
4.48 + }
4.49 +
4.50 + @Override
4.51 + public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
4.52 + // TODO: dopsat
4.53 + log.log(Level.FINE, "setProperty: {0} = {1}", new Object[]{name, value});
4.54 + }
4.55 +
4.56 + @Override
4.57 + public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
4.58 + // TODO: dopsat
4.59 + log.log(Level.FINE, "getProperty: {0}", name);
4.60 + return null;
4.61 + }
4.62 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/java/alt2xml/src/cz/frantovo/alt2xml/CLI.java Mon Jan 02 20:15:52 2012 +0100
5.3 @@ -0,0 +1,30 @@
5.4 +package cz.frantovo.alt2xml;
5.5 +
5.6 +import java.io.InputStream;
5.7 +import java.io.OutputStream;
5.8 +import javax.xml.parsers.SAXParser;
5.9 +import javax.xml.parsers.SAXParserFactory;
5.10 +import javax.xml.stream.XMLOutputFactory;
5.11 +import javax.xml.stream.XMLStreamWriter;
5.12 +import org.xml.sax.helpers.DefaultHandler;
5.13 +
5.14 +/**
5.15 + *
5.16 + * @author fiki
5.17 + */
5.18 +public class CLI {
5.19 +
5.20 + public static void main(String[] args) throws Exception {
5.21 + InputStream vstup = System.in;
5.22 + OutputStream výstup = System.out;
5.23 +
5.24 + SAXParserFactory t = SAXParserFactory.newInstance(SAXTovarna.class.getName(), null);
5.25 + SAXParser p = t.newSAXParser();
5.26 +
5.27 + XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newFactory();
5.28 + XMLStreamWriter w = xmlOutputFactory.createXMLStreamWriter(výstup);
5.29 + DefaultHandler h = new EchoContentHandler(w);
5.30 +
5.31 + p.parse(vstup, h);
5.32 + }
5.33 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/java/alt2xml/src/cz/frantovo/alt2xml/EchoContentHandler.java Mon Jan 02 20:15:52 2012 +0100
6.3 @@ -0,0 +1,83 @@
6.4 +package cz.frantovo.alt2xml;
6.5 +
6.6 +import javax.xml.stream.XMLStreamException;
6.7 +import javax.xml.stream.XMLStreamWriter;
6.8 +import org.xml.sax.Attributes;
6.9 +import org.xml.sax.SAXException;
6.10 +import org.xml.sax.helpers.DefaultHandler;
6.11 +
6.12 +/**
6.13 + * Slouží k převodu právě parsovaného XML zpět na XML.
6.14 + * Určen pro testování a ladění a pro použití s neobvyklými „XML“ parsery,
6.15 + * které nečtou XML ale jiný jazyk (např. JSON, INI atd.), ale používají stejné rozhraní (SAX).
6.16 + *
6.17 + * TODO: další typy uzlů a jmenné prostory.
6.18 + * @author fiki
6.19 + */
6.20 +public class EchoContentHandler extends DefaultHandler {
6.21 +
6.22 + private XMLStreamWriter w;
6.23 +
6.24 + /**
6.25 + * @param writer kam se bude vypisovat XML.
6.26 + */
6.27 + public EchoContentHandler(XMLStreamWriter writer) {
6.28 + w = writer;
6.29 + }
6.30 +
6.31 + @Override
6.32 + public void startDocument() throws SAXException {
6.33 + try {
6.34 + w.writeStartDocument();
6.35 + } catch (XMLStreamException e) {
6.36 + throw new SAXException(e);
6.37 + }
6.38 + }
6.39 +
6.40 + @Override
6.41 + public void endDocument() throws SAXException {
6.42 + try {
6.43 + w.writeEndDocument();
6.44 + w.close();
6.45 + } catch (XMLStreamException e) {
6.46 + throw new SAXException(e);
6.47 + }
6.48 + }
6.49 +
6.50 + @Override
6.51 + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
6.52 + try {
6.53 + w.writeStartElement(qName);
6.54 +
6.55 + if (attributes != null) {
6.56 + for (int i = 0; i < attributes.getLength(); i++) {
6.57 + w.writeAttribute(attributes.getQName(i), attributes.getValue(i));
6.58 + }
6.59 + }
6.60 +
6.61 + w.flush();
6.62 + } catch (XMLStreamException e) {
6.63 + throw new SAXException(e);
6.64 + }
6.65 + }
6.66 +
6.67 + @Override
6.68 + public void endElement(String uri, String localName, String qName) throws SAXException {
6.69 + try {
6.70 + w.writeEndElement();
6.71 + w.flush();
6.72 + } catch (XMLStreamException e) {
6.73 + throw new SAXException(e);
6.74 + }
6.75 + }
6.76 +
6.77 + @Override
6.78 + public void characters(char[] ch, int start, int length) throws SAXException {
6.79 + try {
6.80 + w.writeCharacters(ch, start, length);
6.81 + w.flush();
6.82 + } catch (XMLStreamException e) {
6.83 + throw new SAXException(e);
6.84 + }
6.85 + }
6.86 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/java/alt2xml/src/cz/frantovo/alt2xml/JsonSimpleContentHandler.java Mon Jan 02 20:15:52 2012 +0100
7.3 @@ -0,0 +1,103 @@
7.4 +package cz.frantovo.alt2xml;
7.5 +
7.6 +import java.io.IOException;
7.7 +import java.util.Stack;
7.8 +import org.json.simple.parser.ParseException;
7.9 +import org.xml.sax.ContentHandler;
7.10 +import org.xml.sax.SAXException;
7.11 +
7.12 +/**
7.13 +) *
7.14 + * @author fiki
7.15 + */
7.16 +public class JsonSimpleContentHandler implements org.json.simple.parser.ContentHandler {
7.17 +
7.18 + /** Sem vypisujeme XML události */
7.19 + private ContentHandler saxVýstup;
7.20 + /** Musíme si pamatovat polohu v XML stromu, abychom věděli, kterou značku kdy uzavřít */
7.21 + private Stack<String> poloha = new Stack<>();
7.22 +
7.23 + public JsonSimpleContentHandler(ContentHandler saxVýstup) {
7.24 + this.saxVýstup = saxVýstup;
7.25 + }
7.26 +
7.27 + @Override
7.28 + public void startJSON() throws ParseException, IOException {
7.29 + try {
7.30 + saxVýstup.startDocument();
7.31 + saxVýstup.startElement(null, null, "json", null);
7.32 + } catch (SAXException e) {
7.33 + throw new IOException(e);
7.34 + }
7.35 + }
7.36 +
7.37 + @Override
7.38 + public void endJSON() throws ParseException, IOException {
7.39 + try {
7.40 + saxVýstup.endElement(null, null, "json");
7.41 + saxVýstup.endDocument();
7.42 + } catch (SAXException e) {
7.43 + throw new IOException(e);
7.44 + }
7.45 + }
7.46 +
7.47 + @Override
7.48 + public boolean startObject() throws ParseException, IOException {
7.49 + // System.err.println("startObject");
7.50 + return true;
7.51 + }
7.52 +
7.53 + @Override
7.54 + public boolean endObject() throws ParseException, IOException {
7.55 + // System.err.println("endObject");
7.56 + return true;
7.57 + }
7.58 +
7.59 + @Override
7.60 + public boolean startObjectEntry(String key) throws ParseException, IOException {
7.61 + try {
7.62 + saxVýstup.startElement(null, null, key, null);
7.63 + poloha.push(key);
7.64 + } catch (SAXException e) {
7.65 + throw new IOException(e);
7.66 + }
7.67 + // System.err.println("startObjectEntry: " + key);
7.68 + return true;
7.69 + }
7.70 +
7.71 + @Override
7.72 + public boolean endObjectEntry() throws ParseException, IOException {
7.73 + try {
7.74 + String značka = poloha.pop();
7.75 + saxVýstup.endElement(null, null, značka);
7.76 + } catch (SAXException e) {
7.77 + throw new IOException(e);
7.78 + }
7.79 + // System.err.println("endObjectEntry");
7.80 + return true;
7.81 + }
7.82 +
7.83 + @Override
7.84 + public boolean startArray() throws ParseException, IOException {
7.85 + // System.err.println("startArray");
7.86 + return true;
7.87 + }
7.88 +
7.89 + @Override
7.90 + public boolean endArray() throws ParseException, IOException {
7.91 + // System.err.println("endArray");
7.92 + return true;
7.93 + }
7.94 +
7.95 + @Override
7.96 + public boolean primitive(Object value) throws ParseException, IOException {
7.97 + try {
7.98 + String hodnota = String.valueOf(value);
7.99 + saxVýstup.characters(hodnota.toCharArray(), 0, hodnota.length());
7.100 + } catch (SAXException e) {
7.101 + throw new IOException(e);
7.102 + }
7.103 + // System.err.println("primitive: " + value);
7.104 + return true;
7.105 + }
7.106 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/java/alt2xml/src/cz/frantovo/alt2xml/SAXTovarna.java Mon Jan 02 20:15:52 2012 +0100
8.3 @@ -0,0 +1,31 @@
8.4 +package cz.frantovo.alt2xml;
8.5 +
8.6 +import javax.xml.parsers.ParserConfigurationException;
8.7 +import javax.xml.parsers.SAXParser;
8.8 +import javax.xml.parsers.SAXParserFactory;
8.9 +import org.xml.sax.SAXException;
8.10 +import org.xml.sax.SAXNotRecognizedException;
8.11 +import org.xml.sax.SAXNotSupportedException;
8.12 +
8.13 +/**
8.14 + *
8.15 + * @author fiki
8.16 + */
8.17 +public class SAXTovarna extends SAXParserFactory {
8.18 +
8.19 + @Override
8.20 + public SAXParser newSAXParser() throws ParserConfigurationException, SAXException {
8.21 + return new AltParser();
8.22 + }
8.23 +
8.24 + @Override
8.25 + public void setFeature(String name, boolean value) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException {
8.26 + throw new UnsupportedOperationException("Not supported yet.");
8.27 + }
8.28 +
8.29 + @Override
8.30 + public boolean getFeature(String name) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException {
8.31 + throw new UnsupportedOperationException("Not supported yet.");
8.32 + }
8.33 +
8.34 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/java/alt2xml/src/cz/frantovo/alt2xml/SuperReader.java Mon Jan 02 20:15:52 2012 +0100
9.3 @@ -0,0 +1,128 @@
9.4 +package cz.frantovo.alt2xml;
9.5 +
9.6 +import java.io.BufferedReader;
9.7 +import java.io.IOException;
9.8 +import java.io.InputStreamReader;
9.9 +import java.util.logging.Level;
9.10 +import java.util.logging.Logger;
9.11 +import org.json.simple.parser.JSONParser;
9.12 +import org.json.simple.parser.ParseException;
9.13 +import org.xml.sax.ContentHandler;
9.14 +import org.xml.sax.DTDHandler;
9.15 +import org.xml.sax.EntityResolver;
9.16 +import org.xml.sax.ErrorHandler;
9.17 +import org.xml.sax.InputSource;
9.18 +import org.xml.sax.SAXException;
9.19 +import org.xml.sax.SAXNotRecognizedException;
9.20 +import org.xml.sax.SAXNotSupportedException;
9.21 +import org.xml.sax.XMLReader;
9.22 +
9.23 +/**
9.24 + *
9.25 + * @author fiki
9.26 + */
9.27 +public class SuperReader implements XMLReader {
9.28 +
9.29 + private static final Logger log = Logger.getLogger(SuperReader.class.getName());
9.30 + private ContentHandler contentHandler;
9.31 +
9.32 + @Override
9.33 + public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
9.34 + // TODO: dopsat
9.35 + log.log(Level.FINE, "getFeature: {0}", name);
9.36 + return false;
9.37 + }
9.38 +
9.39 + @Override
9.40 + public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException {
9.41 + // TODO: dopsat
9.42 + log.log(Level.FINE, "setFeature: {0} = {1}", new Object[]{name, value});
9.43 + }
9.44 +
9.45 + @Override
9.46 + public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
9.47 + // TODO: dopsat
9.48 + log.log(Level.FINE, "getProperty: {0}", name);
9.49 + return null;
9.50 + }
9.51 +
9.52 + @Override
9.53 + public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
9.54 + // TODO: dopsat
9.55 + log.log(Level.FINE, "setProperty: {0} = {1}", new Object[]{name, value});
9.56 + }
9.57 +
9.58 + @Override
9.59 + public void setEntityResolver(EntityResolver resolver) {
9.60 + // TODO: dopsat
9.61 + log.log(Level.FINE, "setEntityResolver: {0}", resolver);
9.62 + }
9.63 +
9.64 + @Override
9.65 + public EntityResolver getEntityResolver() {
9.66 + // TODO: dopsat
9.67 + log.log(Level.FINE, "getEntityResolver");
9.68 + return null;
9.69 + }
9.70 +
9.71 + @Override
9.72 + public void setDTDHandler(DTDHandler handler) {
9.73 + // TODO: dopsat
9.74 + log.log(Level.FINE, "setDTDHandler: {0}", handler);
9.75 + }
9.76 +
9.77 + @Override
9.78 + public DTDHandler getDTDHandler() {
9.79 + // TODO: dopsat
9.80 + log.log(Level.FINE, "getDTDHandler");
9.81 + return null;
9.82 + }
9.83 +
9.84 + @Override
9.85 + public void setContentHandler(ContentHandler handler) {
9.86 + // TODO: dopsat
9.87 + contentHandler = handler;
9.88 + }
9.89 +
9.90 + @Override
9.91 + public ContentHandler getContentHandler() {
9.92 + // TODO: dopsat
9.93 + return contentHandler;
9.94 + }
9.95 +
9.96 + @Override
9.97 + public void setErrorHandler(ErrorHandler handler) {
9.98 + // TODO: dopsat
9.99 + log.log(Level.FINE, "setErrorHandler: {0}", handler);
9.100 + }
9.101 +
9.102 + @Override
9.103 + public ErrorHandler getErrorHandler() {
9.104 + // TODO: dopsat
9.105 + log.log(Level.FINE, "getErrorHandler");
9.106 + return null;
9.107 + }
9.108 +
9.109 + @Override
9.110 + public void parse(InputSource input) throws IOException, SAXException {
9.111 + /**
9.112 + * TODO: rozpornat formát vstupu a podle toho delegovat
9.113 + */
9.114 +
9.115 + JSONParser p = new JSONParser();
9.116 + InputStreamReader vstup = new InputStreamReader(input.getByteStream());
9.117 + JsonSimpleContentHandler handler = new JsonSimpleContentHandler(contentHandler);
9.118 +
9.119 + try {
9.120 + p.parse(vstup, handler);
9.121 + } catch (ParseException e) {
9.122 + throw new SAXException("Chyba při načítání JSONu", e);
9.123 + }
9.124 + }
9.125 +
9.126 + @Override
9.127 + public void parse(String systemId) throws IOException, SAXException {
9.128 + // TODO: dopsat
9.129 + throw new UnsupportedOperationException("Zatím není podporované.");
9.130 + }
9.131 +}