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: }