java/alt2xml-in-properties/src/cz/frantovo/alt2xml/in/properties/Reader.java
author František Kučera <franta-hg@frantovo.cz>
Sun, 02 Oct 2016 11:46:19 +0200
changeset 107 c5a987931ef9
parent 75 ed9ec17aa67f
child 111 e4900596abdb
permissions -rw-r--r--
in-properties: fix typo in comment
franta-hg@11
     1
/**
franta-hg@11
     2
 * Alt2XML
franta-hg@11
     3
 * Copyright © 2014 František Kučera (frantovo.cz)
franta-hg@11
     4
 *
franta-hg@11
     5
 * This program is free software: you can redistribute it and/or modify
franta-hg@11
     6
 * it under the terms of the GNU General Public License as published by
franta-hg@11
     7
 * the Free Software Foundation, either version 3 of the License, or
franta-hg@11
     8
 * (at your option) any later version.
franta-hg@11
     9
 *
franta-hg@11
    10
 * This program is distributed in the hope that it will be useful,
franta-hg@11
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
franta-hg@11
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
franta-hg@11
    13
 * GNU General Public License for more details.
franta-hg@11
    14
 *
franta-hg@11
    15
 * You should have received a copy of the GNU General Public License
franta-hg@11
    16
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
franta-hg@11
    17
 */
franta-hg@18
    18
package cz.frantovo.alt2xml.in.properties;
franta-hg@2
    19
franta-hg@17
    20
import cz.frantovo.alt2xml.AbstractAlt2XmlReader;
franta-hg@59
    21
import java.io.BufferedReader;
franta-hg@2
    22
import java.io.IOException;
franta-hg@59
    23
import java.io.InputStreamReader;
franta-hg@59
    24
import java.io.StringReader;
franta-hg@59
    25
import java.nio.charset.StandardCharsets;
franta-hg@21
    26
import java.util.Map.Entry;
franta-hg@21
    27
import java.util.Properties;
franta-hg@59
    28
import java.util.logging.Level;
franta-hg@59
    29
import java.util.logging.Logger;
franta-hg@2
    30
import org.xml.sax.InputSource;
franta-hg@2
    31
import org.xml.sax.SAXException;
franta-hg@21
    32
import org.xml.sax.helpers.AttributesImpl;
franta-hg@2
    33
franta-hg@2
    34
/**
franta-hg@2
    35
 *
franta-hg@17
    36
 * @author Ing. František Kučera (frantovo.cz)
franta-hg@2
    37
 */
franta-hg@17
    38
public class Reader extends AbstractAlt2XmlReader {
franta-hg@13
    39
franta-hg@59
    40
	public static final String PROPERTY_BATCH_MODE = constructPropertyName("properties", "batch-mode");
franta-hg@59
    41
	private static final Logger log = Logger.getLogger(Reader.class.getName());
franta-hg@59
    42
franta-hg@21
    43
	/**
franta-hg@21
    44
	 * <p>
franta-hg@59
    45
	 * TODO: same format as Java XML properties
franta-hg@59
    46
	 * </p>
franta-hg@21
    47
	 * <p>
franta-hg@21
    48
	 * TODO: support also nested mode <code>aaa.bbb.ccc=xxx</code> →
franta-hg@21
    49
	 * <code>&lt;aaa&gt;&lt;bbb&gt;&lt;ccc&gt;xxx&lt;/ccc&gt;&lt;/bbb&gt;&lt;/aaa&gt;</code></p>
franta-hg@21
    50
	 */
franta-hg@2
    51
	@Override
franta-hg@6
    52
	public void parse(InputSource input) throws IOException, SAXException {
franta-hg@59
    53
		if (isInBatchMode()) {
franta-hg@59
    54
			log.log(Level.FINE, "Reading in batch mode");
franta-hg@59
    55
			parseAsBatch(input);
franta-hg@59
    56
		} else {
franta-hg@59
    57
			log.log(Level.FINE, "Reading in streaming mode");
franta-hg@59
    58
			parseAsStream(input);
franta-hg@59
    59
		}
franta-hg@59
    60
	}
franta-hg@59
    61
franta-hg@59
    62
	private void parseAsBatch(InputSource input) throws IOException, SAXException {
franta-hg@21
    63
		Properties loadedData = new Properties();
franta-hg@21
    64
		loadedData.load(input.getByteStream());
franta-hg@6
    65
franta-hg@59
    66
		outputStart();
franta-hg@59
    67
		outputProperties(loadedData);
franta-hg@59
    68
		outputEnd();
franta-hg@59
    69
	}
franta-hg@59
    70
franta-hg@59
    71
	private void parseAsStream(InputSource input) throws IOException, SAXException {
franta-hg@59
    72
franta-hg@59
    73
		outputStart();
franta-hg@59
    74
franta-hg@59
    75
		try (BufferedReader br = new BufferedReader(new InputStreamReader(input.getByteStream(), StandardCharsets.ISO_8859_1))) {
franta-hg@59
    76
			StringBuilder continuingLine = null;
franta-hg@59
    77
			Properties loadedData = new Properties();
franta-hg@59
    78
			for (String currentLine = br.readLine(); currentLine != null; currentLine = br.readLine()) {
franta-hg@59
    79
				if (currentLine.endsWith("\\")) {
franta-hg@59
    80
					if (continuingLine == null) {
franta-hg@59
    81
						continuingLine = new StringBuilder();
franta-hg@59
    82
					}
franta-hg@59
    83
					continuingLine.append(currentLine);
franta-hg@59
    84
				} else {
franta-hg@59
    85
					String wholeLogicalLine = (continuingLine == null) ? currentLine : continuingLine.append("\n").append(currentLine).toString();
franta-hg@59
    86
					continuingLine = null;
franta-hg@59
    87
franta-hg@59
    88
					loadedData.load(new StringReader(wholeLogicalLine));
franta-hg@59
    89
					outputProperties(loadedData);
franta-hg@59
    90
					loadedData.clear();
franta-hg@59
    91
				}
franta-hg@59
    92
			}
franta-hg@59
    93
		}
franta-hg@59
    94
franta-hg@59
    95
		outputEnd();
franta-hg@59
    96
	}
franta-hg@59
    97
franta-hg@59
    98
	/**
franta-hg@59
    99
	 * Default mode is streaming.
franta-hg@59
   100
	 *
franta-hg@107
   101
	 * @return false = do streaming | true = parse whole input as one batch and when all parsed,
franta-hg@59
   102
	 * flush output
franta-hg@59
   103
	 */
franta-hg@59
   104
	private boolean isInBatchMode() {
franta-hg@59
   105
		return Boolean.parseBoolean(String.valueOf(properties.get(PROPERTY_BATCH_MODE)));
franta-hg@59
   106
	}
franta-hg@59
   107
franta-hg@59
   108
	private void outputStart() throws SAXException {
franta-hg@21
   109
		contentHandler.startDocument();
franta-hg@21
   110
		contentHandler.startElement(null, null, "properties", null);
franta-hg@21
   111
franta-hg@75
   112
		contentHandler.lineBreak();
franta-hg@59
   113
	}
franta-hg@59
   114
franta-hg@59
   115
	private void outputProperty(String key, String value) throws SAXException {
franta-hg@75
   116
		contentHandler.indentation(1);
franta-hg@59
   117
franta-hg@59
   118
		AttributesImpl attributes = new AttributesImpl();
franta-hg@59
   119
		attributes.addAttribute(null, "name", "name", "xs:string", key);
franta-hg@59
   120
franta-hg@59
   121
		contentHandler.startElement(null, null, "property", attributes);
franta-hg@59
   122
		contentHandler.characters(value.toCharArray(), 0, value.length());
franta-hg@59
   123
		contentHandler.endElement(null, null, "property");
franta-hg@59
   124
franta-hg@75
   125
		contentHandler.lineBreak();
franta-hg@59
   126
	}
franta-hg@59
   127
franta-hg@59
   128
	private void outputProperties(Properties loadedData) throws SAXException {
franta-hg@21
   129
		for (Entry<Object, Object> e : loadedData.entrySet()) {
franta-hg@21
   130
			String key = (String) e.getKey();
franta-hg@21
   131
			String value = (String) e.getValue();
franta-hg@59
   132
			outputProperty(key, value);
franta-hg@59
   133
		}
franta-hg@59
   134
	}
franta-hg@21
   135
franta-hg@59
   136
	private void outputEnd() throws SAXException {
franta-hg@21
   137
		contentHandler.endElement(null, null, "properties");
franta-hg@75
   138
		contentHandler.lineBreak();
franta-hg@21
   139
		contentHandler.endDocument();
franta-hg@6
   140
	}
franta-hg@2
   141
}