java/alt2xml-in-json/src/cz/frantovo/alt2xml/in/json/JsonSimpleContentHandler.java
author František Kučera <franta-hg@frantovo.cz>
Thu, 24 Oct 2019 21:56:03 +0200
changeset 111 e4900596abdb
parent 74 6d1fc2895273
permissions -rw-r--r--
fix license version: GNU GPLv3
     1 /**
     2  * Alt2XML
     3  * Copyright © 2014 František Kučera (frantovo.cz)
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 3 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
    16  */
    17 package cz.frantovo.alt2xml.in.json;
    18 
    19 import java.io.IOException;
    20 import java.util.Stack;
    21 import org.json.simple.parser.ParseException;
    22 import org.xml.sax.ContentHandler;
    23 import org.xml.sax.SAXException;
    24 
    25 /**
    26  *
    27  * @author Ing. František Kučera (frantovo.cz)
    28  */
    29 public class JsonSimpleContentHandler implements org.json.simple.parser.ContentHandler {
    30 
    31 	/** Sem vypisujeme XML události */
    32 	private final ContentHandler saxVýstup;
    33 	/** Musíme si pamatovat polohu v XML stromu, abychom věděli, kterou značku kdy uzavřít */
    34 	private final Stack<String> poloha = new Stack<>();
    35 	/**
    36 	 * Po textových uzlech vkládáme konce elementů rovnou,
    37 	 * ale pokud jeden element končí hned po jiném,
    38 	 * vložíme mezi ně ještě konec řádku a odsazení.
    39 	 */
    40 	private boolean zalomitŘádek = false;
    41 
    42 	public JsonSimpleContentHandler(ContentHandler saxVýstup) {
    43 		this.saxVýstup = saxVýstup;
    44 	}
    45 
    46 	private void začniElement(String název) throws IOException {
    47 		try {
    48 			vložOdsazení();
    49 			saxVýstup.startElement(null, null, název, null);
    50 			poloha.push(název);
    51 		} catch (SAXException e) {
    52 			throw new IOException("Chyba při začátku elementu.", e);
    53 		}
    54 	}
    55 
    56 	private void ukončiElement() throws IOException {
    57 		try {
    58 			String značka = poloha.pop();
    59 			if (zalomitŘádek) {
    60 				vložOdsazení();
    61 			}
    62 			zalomitŘádek = true;
    63 			saxVýstup.endElement(null, null, značka);
    64 		} catch (SAXException e) {
    65 			throw new IOException("Chyba při ukončování elementu.", e);
    66 		}
    67 	}
    68 
    69 	private void vložOdsazení() throws IOException {
    70 		/**
    71 		 * TODO: ignorableWhitespace() ?
    72 		 */
    73 		vložText("\n");
    74 		for (int i = 0; i < poloha.size(); i++) {
    75 			vložText("\t");
    76 		}
    77 	}
    78 
    79 	private void vložText(String text) throws IOException {
    80 		try {
    81 			saxVýstup.characters(text.toCharArray(), 0, text.length());
    82 		} catch (SAXException e) {
    83 			throw new IOException("Chyba při vkládání textu.", e);
    84 		}
    85 	}
    86 
    87 	@Override
    88 	public void startJSON() throws ParseException, IOException {
    89 		try {
    90 			saxVýstup.startDocument();
    91 			začniElement("objekt");
    92 		} catch (SAXException e) {
    93 			throw new IOException("Chyba při začátku dokumentu.", e);
    94 		}
    95 	}
    96 
    97 	@Override
    98 	public void endJSON() throws ParseException, IOException {
    99 		try {
   100 			ukončiElement();
   101 			vložText("\n");
   102 			saxVýstup.endDocument();
   103 		} catch (SAXException e) {
   104 			throw new IOException(e);
   105 		}
   106 	}
   107 
   108 	@Override
   109 	public boolean startObject() throws ParseException, IOException {
   110 		/**
   111 		 * TODO: zachovat hranice mezi objekty, které jsou prvkem pole
   112 		 * "phoneNumber": [
   113 		 * { "type": "home", "number": "212 555-1234" },
   114 		 * { "type": "fax", "number": "646 555-4567" }
   115 		 * ]
   116 		 *
   117 		 */
   118 
   119 		// System.err.println("startObject");
   120 		return true;
   121 	}
   122 
   123 	@Override
   124 	public boolean endObject() throws ParseException, IOException {
   125 		// System.err.println("endObject");
   126 		return true;
   127 	}
   128 
   129 	@Override
   130 	public boolean startObjectEntry(String key) throws ParseException, IOException {
   131 		začniElement(key);
   132 		return true;
   133 	}
   134 
   135 	@Override
   136 	public boolean endObjectEntry() throws ParseException, IOException {
   137 		ukončiElement();
   138 		// System.err.println("endObjectEntry");
   139 		return true;
   140 	}
   141 
   142 	@Override
   143 	public boolean startArray() throws ParseException, IOException {
   144 		// System.err.println("startArray");
   145 		return true;
   146 	}
   147 
   148 	@Override
   149 	public boolean endArray() throws ParseException, IOException {
   150 		// System.err.println("endArray");
   151 		return true;
   152 	}
   153 
   154 	@Override
   155 	public boolean primitive(Object value) throws ParseException, IOException {
   156 		vložText(String.valueOf(value));
   157 		zalomitŘádek = false;
   158 		return true;
   159 	}
   160 }