1.1 --- a/java/alt2xml-in-properties/src/cz/frantovo/alt2xml/in/properties/Reader.java Wed Sep 03 15:50:16 2014 +0200
1.2 +++ b/java/alt2xml-in-properties/src/cz/frantovo/alt2xml/in/properties/Reader.java Wed Sep 03 19:48:14 2014 +0200
1.3 @@ -18,9 +18,15 @@
1.4 package cz.frantovo.alt2xml.in.properties;
1.5
1.6 import cz.frantovo.alt2xml.AbstractAlt2XmlReader;
1.7 +import java.io.BufferedReader;
1.8 import java.io.IOException;
1.9 +import java.io.InputStreamReader;
1.10 +import java.io.StringReader;
1.11 +import java.nio.charset.StandardCharsets;
1.12 import java.util.Map.Entry;
1.13 import java.util.Properties;
1.14 +import java.util.logging.Level;
1.15 +import java.util.logging.Logger;
1.16 import org.xml.sax.InputSource;
1.17 import org.xml.sax.SAXException;
1.18 import org.xml.sax.helpers.AttributesImpl;
1.19 @@ -31,36 +37,115 @@
1.20 */
1.21 public class Reader extends AbstractAlt2XmlReader {
1.22
1.23 + public static final String PROPERTY_BATCH_MODE = constructPropertyName("properties", "batch-mode");
1.24 + private static final Logger log = Logger.getLogger(Reader.class.getName());
1.25 +
1.26 /**
1.27 * <p>
1.28 - * TODO: streaming
1.29 - * <p>
1.30 - * <p>
1.31 - * TODO: same format as Java XML properties</p>
1.32 + * TODO: same format as Java XML properties
1.33 + * </p>
1.34 * <p>
1.35 * TODO: support also nested mode <code>aaa.bbb.ccc=xxx</code> →
1.36 * <code><aaa><bbb><ccc>xxx</ccc></bbb></aaa></code></p>
1.37 */
1.38 @Override
1.39 public void parse(InputSource input) throws IOException, SAXException {
1.40 + if (isInBatchMode()) {
1.41 + log.log(Level.FINE, "Reading in batch mode");
1.42 + parseAsBatch(input);
1.43 + } else {
1.44 + log.log(Level.FINE, "Reading in streaming mode");
1.45 + parseAsStream(input);
1.46 + }
1.47 + }
1.48 +
1.49 + private void parseAsBatch(InputSource input) throws IOException, SAXException {
1.50 Properties loadedData = new Properties();
1.51 loadedData.load(input.getByteStream());
1.52
1.53 + outputStart();
1.54 + outputProperties(loadedData);
1.55 + outputEnd();
1.56 + }
1.57 +
1.58 + private void parseAsStream(InputSource input) throws IOException, SAXException {
1.59 +
1.60 + outputStart();
1.61 +
1.62 + try (BufferedReader br = new BufferedReader(new InputStreamReader(input.getByteStream(), StandardCharsets.ISO_8859_1))) {
1.63 + StringBuilder continuingLine = null;
1.64 + Properties loadedData = new Properties();
1.65 + for (String currentLine = br.readLine(); currentLine != null; currentLine = br.readLine()) {
1.66 + if (currentLine.endsWith("\\")) {
1.67 + if (continuingLine == null) {
1.68 + continuingLine = new StringBuilder();
1.69 + }
1.70 + continuingLine.append(currentLine);
1.71 + } else {
1.72 + String wholeLogicalLine = (continuingLine == null) ? currentLine : continuingLine.append("\n").append(currentLine).toString();
1.73 + continuingLine = null;
1.74 +
1.75 + loadedData.load(new StringReader(wholeLogicalLine));
1.76 + outputProperties(loadedData);
1.77 + loadedData.clear();
1.78 + }
1.79 + }
1.80 + }
1.81 +
1.82 + outputEnd();
1.83 + }
1.84 +
1.85 + /**
1.86 + * Default mode is streaming.
1.87 + *
1.88 + * @return false = do streaming | false = parse whole input as one batch and when all parsed,
1.89 + * flush output
1.90 + */
1.91 + private boolean isInBatchMode() {
1.92 + return Boolean.parseBoolean(String.valueOf(properties.get(PROPERTY_BATCH_MODE)));
1.93 + }
1.94 +
1.95 + private void outputStart() throws SAXException {
1.96 contentHandler.startDocument();
1.97 contentHandler.startElement(null, null, "properties", null);
1.98
1.99 + outputLineBreak();
1.100 + }
1.101 +
1.102 + private void outputProperty(String key, String value) throws SAXException {
1.103 + outputIndentation();
1.104 +
1.105 + AttributesImpl attributes = new AttributesImpl();
1.106 + attributes.addAttribute(null, "name", "name", "xs:string", key);
1.107 +
1.108 + contentHandler.startElement(null, null, "property", attributes);
1.109 + contentHandler.characters(value.toCharArray(), 0, value.length());
1.110 + contentHandler.endElement(null, null, "property");
1.111 +
1.112 + outputLineBreak();
1.113 + }
1.114 +
1.115 + private void outputProperties(Properties loadedData) throws SAXException {
1.116 for (Entry<Object, Object> e : loadedData.entrySet()) {
1.117 String key = (String) e.getKey();
1.118 String value = (String) e.getValue();
1.119 + outputProperty(key, value);
1.120 + }
1.121 + }
1.122
1.123 - AttributesImpl attributes = new AttributesImpl();
1.124 - attributes.addAttribute(null, "name", "name", "xs:string", key);
1.125 + private void outputIndentation() throws SAXException {
1.126 + outputText("\t");
1.127 + }
1.128
1.129 - contentHandler.startElement(null, null, "property", attributes);
1.130 - contentHandler.characters(value.toCharArray(), 0, value.length());
1.131 - contentHandler.endElement(null, null, "property");
1.132 - }
1.133 + private void outputLineBreak() throws SAXException {
1.134 + outputText("\n");
1.135 + }
1.136
1.137 + private void outputText(String text) throws SAXException {
1.138 + contentHandler.characters(text.toCharArray(), 0, text.length());
1.139 + }
1.140 +
1.141 + private void outputEnd() throws SAXException {
1.142 contentHandler.endElement(null, null, "properties");
1.143 contentHandler.endDocument();
1.144 }