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