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