# HG changeset patch # User František Kučera # Date 1409766494 -7200 # Node ID 12b4c1fc57a81d91ad6f7e40b0adb8759f240a9b # Parent c11792ae64891a3f5145d2423f84983a3922e042 in-properties: streaming diff -r c11792ae6489 -r 12b4c1fc57a8 java/alt2xml-in-properties/src/cz/frantovo/alt2xml/in/properties/Reader.java --- a/java/alt2xml-in-properties/src/cz/frantovo/alt2xml/in/properties/Reader.java Wed Sep 03 15:50:16 2014 +0200 +++ b/java/alt2xml-in-properties/src/cz/frantovo/alt2xml/in/properties/Reader.java Wed Sep 03 19:48:14 2014 +0200 @@ -18,9 +18,15 @@ package cz.frantovo.alt2xml.in.properties; import cz.frantovo.alt2xml.AbstractAlt2XmlReader; +import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStreamReader; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; import java.util.Map.Entry; import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; @@ -31,36 +37,115 @@ */ public class Reader extends AbstractAlt2XmlReader { + public static final String PROPERTY_BATCH_MODE = constructPropertyName("properties", "batch-mode"); + private static final Logger log = Logger.getLogger(Reader.class.getName()); + /** *

- * TODO: streaming - *

- *

- * TODO: same format as Java XML properties

+ * TODO: same format as Java XML properties + *

*

* TODO: support also nested mode aaa.bbb.ccc=xxx → * <aaa><bbb><ccc>xxx</ccc></bbb></aaa>

*/ @Override public void parse(InputSource input) throws IOException, SAXException { + if (isInBatchMode()) { + log.log(Level.FINE, "Reading in batch mode"); + parseAsBatch(input); + } else { + log.log(Level.FINE, "Reading in streaming mode"); + parseAsStream(input); + } + } + + private void parseAsBatch(InputSource input) throws IOException, SAXException { Properties loadedData = new Properties(); loadedData.load(input.getByteStream()); + outputStart(); + outputProperties(loadedData); + outputEnd(); + } + + private void parseAsStream(InputSource input) throws IOException, SAXException { + + outputStart(); + + try (BufferedReader br = new BufferedReader(new InputStreamReader(input.getByteStream(), StandardCharsets.ISO_8859_1))) { + StringBuilder continuingLine = null; + Properties loadedData = new Properties(); + for (String currentLine = br.readLine(); currentLine != null; currentLine = br.readLine()) { + if (currentLine.endsWith("\\")) { + if (continuingLine == null) { + continuingLine = new StringBuilder(); + } + continuingLine.append(currentLine); + } else { + String wholeLogicalLine = (continuingLine == null) ? currentLine : continuingLine.append("\n").append(currentLine).toString(); + continuingLine = null; + + loadedData.load(new StringReader(wholeLogicalLine)); + outputProperties(loadedData); + loadedData.clear(); + } + } + } + + outputEnd(); + } + + /** + * Default mode is streaming. + * + * @return false = do streaming | false = parse whole input as one batch and when all parsed, + * flush output + */ + private boolean isInBatchMode() { + return Boolean.parseBoolean(String.valueOf(properties.get(PROPERTY_BATCH_MODE))); + } + + private void outputStart() throws SAXException { contentHandler.startDocument(); contentHandler.startElement(null, null, "properties", null); + outputLineBreak(); + } + + private void outputProperty(String key, String value) throws SAXException { + outputIndentation(); + + AttributesImpl attributes = new AttributesImpl(); + attributes.addAttribute(null, "name", "name", "xs:string", key); + + contentHandler.startElement(null, null, "property", attributes); + contentHandler.characters(value.toCharArray(), 0, value.length()); + contentHandler.endElement(null, null, "property"); + + outputLineBreak(); + } + + private void outputProperties(Properties loadedData) throws SAXException { for (Entry e : loadedData.entrySet()) { String key = (String) e.getKey(); String value = (String) e.getValue(); + outputProperty(key, value); + } + } - AttributesImpl attributes = new AttributesImpl(); - attributes.addAttribute(null, "name", "name", "xs:string", key); + private void outputIndentation() throws SAXException { + outputText("\t"); + } - contentHandler.startElement(null, null, "property", attributes); - contentHandler.characters(value.toCharArray(), 0, value.length()); - contentHandler.endElement(null, null, "property"); - } + private void outputLineBreak() throws SAXException { + outputText("\n"); + } + private void outputText(String text) throws SAXException { + contentHandler.characters(text.toCharArray(), 0, text.length()); + } + + private void outputEnd() throws SAXException { contentHandler.endElement(null, null, "properties"); contentHandler.endDocument(); }