franta-hg@11: /**
franta-hg@11: * Alt2XML
franta-hg@11: * Copyright © 2014 František Kučera (frantovo.cz)
franta-hg@11: *
franta-hg@11: * This program is free software: you can redistribute it and/or modify
franta-hg@11: * it under the terms of the GNU General Public License as published by
franta-hg@111: * the Free Software Foundation, version 3 of the License.
franta-hg@11: *
franta-hg@11: * This program is distributed in the hope that it will be useful,
franta-hg@11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
franta-hg@11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
franta-hg@11: * GNU General Public License for more details.
franta-hg@11: *
franta-hg@11: * You should have received a copy of the GNU General Public License
franta-hg@11: * along with this program. If not, see .
franta-hg@11: */
franta-hg@14: package cz.frantovo.alt2xml.in.json;
franta-hg@2:
franta-hg@2: import java.io.IOException;
franta-hg@2: import java.util.Stack;
franta-hg@2: import org.json.simple.parser.ParseException;
franta-hg@2: import org.xml.sax.ContentHandler;
franta-hg@2: import org.xml.sax.SAXException;
franta-hg@2:
franta-hg@2: /**
franta-hg@4: *
franta-hg@19: * @author Ing. František Kučera (frantovo.cz)
franta-hg@2: */
franta-hg@2: public class JsonSimpleContentHandler implements org.json.simple.parser.ContentHandler {
franta-hg@2:
franta-hg@2: /** Sem vypisujeme XML události */
franta-hg@20: private final ContentHandler saxVýstup;
franta-hg@2: /** Musíme si pamatovat polohu v XML stromu, abychom věděli, kterou značku kdy uzavřít */
franta-hg@20: private final Stack poloha = new Stack<>();
franta-hg@3: /**
franta-hg@3: * Po textových uzlech vkládáme konce elementů rovnou,
franta-hg@74: * ale pokud jeden element končí hned po jiném,
franta-hg@3: * vložíme mezi ně ještě konec řádku a odsazení.
franta-hg@3: */
franta-hg@3: private boolean zalomitŘádek = false;
franta-hg@2:
franta-hg@2: public JsonSimpleContentHandler(ContentHandler saxVýstup) {
franta-hg@2: this.saxVýstup = saxVýstup;
franta-hg@2: }
franta-hg@2:
franta-hg@3: private void začniElement(String název) throws IOException {
franta-hg@3: try {
franta-hg@3: vložOdsazení();
franta-hg@3: saxVýstup.startElement(null, null, název, null);
franta-hg@3: poloha.push(název);
franta-hg@3: } catch (SAXException e) {
franta-hg@3: throw new IOException("Chyba při začátku elementu.", e);
franta-hg@3: }
franta-hg@3: }
franta-hg@3:
franta-hg@3: private void ukončiElement() throws IOException {
franta-hg@3: try {
franta-hg@3: String značka = poloha.pop();
franta-hg@3: if (zalomitŘádek) {
franta-hg@3: vložOdsazení();
franta-hg@3: }
franta-hg@3: zalomitŘádek = true;
franta-hg@3: saxVýstup.endElement(null, null, značka);
franta-hg@3: } catch (SAXException e) {
franta-hg@3: throw new IOException("Chyba při ukončování elementu.", e);
franta-hg@3: }
franta-hg@3: }
franta-hg@3:
franta-hg@3: private void vložOdsazení() throws IOException {
franta-hg@3: /**
franta-hg@3: * TODO: ignorableWhitespace() ?
franta-hg@3: */
franta-hg@3: vložText("\n");
franta-hg@3: for (int i = 0; i < poloha.size(); i++) {
franta-hg@3: vložText("\t");
franta-hg@3: }
franta-hg@3: }
franta-hg@3:
franta-hg@3: private void vložText(String text) throws IOException {
franta-hg@3: try {
franta-hg@3: saxVýstup.characters(text.toCharArray(), 0, text.length());
franta-hg@3: } catch (SAXException e) {
franta-hg@3: throw new IOException("Chyba při vkládání textu.", e);
franta-hg@3: }
franta-hg@3: }
franta-hg@3:
franta-hg@2: @Override
franta-hg@2: public void startJSON() throws ParseException, IOException {
franta-hg@2: try {
franta-hg@2: saxVýstup.startDocument();
franta-hg@3: začniElement("objekt");
franta-hg@2: } catch (SAXException e) {
franta-hg@3: throw new IOException("Chyba při začátku dokumentu.", e);
franta-hg@2: }
franta-hg@2: }
franta-hg@2:
franta-hg@2: @Override
franta-hg@2: public void endJSON() throws ParseException, IOException {
franta-hg@2: try {
franta-hg@3: ukončiElement();
franta-hg@3: vložText("\n");
franta-hg@2: saxVýstup.endDocument();
franta-hg@2: } catch (SAXException e) {
franta-hg@2: throw new IOException(e);
franta-hg@2: }
franta-hg@2: }
franta-hg@2:
franta-hg@2: @Override
franta-hg@2: public boolean startObject() throws ParseException, IOException {
franta-hg@74: /**
franta-hg@74: * TODO: zachovat hranice mezi objekty, které jsou prvkem pole
franta-hg@74: * "phoneNumber": [
franta-hg@74: * { "type": "home", "number": "212 555-1234" },
franta-hg@74: * { "type": "fax", "number": "646 555-4567" }
franta-hg@74: * ]
franta-hg@74: *
franta-hg@74: */
franta-hg@74:
franta-hg@2: // System.err.println("startObject");
franta-hg@2: return true;
franta-hg@2: }
franta-hg@2:
franta-hg@2: @Override
franta-hg@2: public boolean endObject() throws ParseException, IOException {
franta-hg@2: // System.err.println("endObject");
franta-hg@2: return true;
franta-hg@2: }
franta-hg@2:
franta-hg@2: @Override
franta-hg@2: public boolean startObjectEntry(String key) throws ParseException, IOException {
franta-hg@3: začniElement(key);
franta-hg@2: return true;
franta-hg@2: }
franta-hg@2:
franta-hg@2: @Override
franta-hg@2: public boolean endObjectEntry() throws ParseException, IOException {
franta-hg@3: ukončiElement();
franta-hg@2: // System.err.println("endObjectEntry");
franta-hg@2: return true;
franta-hg@2: }
franta-hg@2:
franta-hg@2: @Override
franta-hg@2: public boolean startArray() throws ParseException, IOException {
franta-hg@2: // System.err.println("startArray");
franta-hg@2: return true;
franta-hg@2: }
franta-hg@2:
franta-hg@2: @Override
franta-hg@2: public boolean endArray() throws ParseException, IOException {
franta-hg@2: // System.err.println("endArray");
franta-hg@2: return true;
franta-hg@2: }
franta-hg@2:
franta-hg@2: @Override
franta-hg@2: public boolean primitive(Object value) throws ParseException, IOException {
franta-hg@3: vložText(String.valueOf(value));
franta-hg@3: zalomitŘádek = false;
franta-hg@2: return true;
franta-hg@2: }
franta-hg@2: }