franta-hg@11: /**
franta-hg@11: * Alt2XML
franta-hg@11: * Copyright © 2014 František Kučera (frantovo.cz)
franta-hg@11: *
franta-hg@11: * This program is free software: you can redistribute it and/or modify
franta-hg@11: * it under the terms of the GNU General Public License as published by
franta-hg@111: * the Free Software Foundation, version 3 of the License.
franta-hg@11: *
franta-hg@11: * This program is distributed in the hope that it will be useful,
franta-hg@11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
franta-hg@11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
franta-hg@11: * GNU General Public License for more details.
franta-hg@11: *
franta-hg@11: * You should have received a copy of the GNU General Public License
franta-hg@11: * along with this program. If not, see .
franta-hg@11: */
franta-hg@18: package cz.frantovo.alt2xml.in.properties;
franta-hg@2:
franta-hg@17: import cz.frantovo.alt2xml.AbstractAlt2XmlReader;
franta-hg@59: import java.io.BufferedReader;
franta-hg@2: import java.io.IOException;
franta-hg@59: import java.io.InputStreamReader;
franta-hg@59: import java.io.StringReader;
franta-hg@59: import java.nio.charset.StandardCharsets;
franta-hg@21: import java.util.Map.Entry;
franta-hg@21: import java.util.Properties;
franta-hg@59: import java.util.logging.Level;
franta-hg@59: import java.util.logging.Logger;
franta-hg@2: import org.xml.sax.InputSource;
franta-hg@2: import org.xml.sax.SAXException;
franta-hg@21: import org.xml.sax.helpers.AttributesImpl;
franta-hg@2:
franta-hg@2: /**
franta-hg@2: *
franta-hg@17: * @author Ing. František Kučera (frantovo.cz)
franta-hg@2: */
franta-hg@17: public class Reader extends AbstractAlt2XmlReader {
franta-hg@13:
franta-hg@59: public static final String PROPERTY_BATCH_MODE = constructPropertyName("properties", "batch-mode");
franta-hg@59: private static final Logger log = Logger.getLogger(Reader.class.getName());
franta-hg@59:
franta-hg@21: /**
franta-hg@21: *
franta-hg@59: * TODO: same format as Java XML properties
franta-hg@59: *
franta-hg@21: *
franta-hg@21: * TODO: support also nested mode aaa.bbb.ccc=xxx
→
franta-hg@21: * <aaa><bbb><ccc>xxx</ccc></bbb></aaa>
franta-hg@21: */
franta-hg@2: @Override
franta-hg@6: public void parse(InputSource input) throws IOException, SAXException {
franta-hg@59: if (isInBatchMode()) {
franta-hg@59: log.log(Level.FINE, "Reading in batch mode");
franta-hg@59: parseAsBatch(input);
franta-hg@59: } else {
franta-hg@59: log.log(Level.FINE, "Reading in streaming mode");
franta-hg@59: parseAsStream(input);
franta-hg@59: }
franta-hg@59: }
franta-hg@59:
franta-hg@59: private void parseAsBatch(InputSource input) throws IOException, SAXException {
franta-hg@21: Properties loadedData = new Properties();
franta-hg@21: loadedData.load(input.getByteStream());
franta-hg@6:
franta-hg@59: outputStart();
franta-hg@59: outputProperties(loadedData);
franta-hg@59: outputEnd();
franta-hg@59: }
franta-hg@59:
franta-hg@59: private void parseAsStream(InputSource input) throws IOException, SAXException {
franta-hg@59:
franta-hg@59: outputStart();
franta-hg@59:
franta-hg@59: try (BufferedReader br = new BufferedReader(new InputStreamReader(input.getByteStream(), StandardCharsets.ISO_8859_1))) {
franta-hg@59: StringBuilder continuingLine = null;
franta-hg@59: Properties loadedData = new Properties();
franta-hg@59: for (String currentLine = br.readLine(); currentLine != null; currentLine = br.readLine()) {
franta-hg@59: if (currentLine.endsWith("\\")) {
franta-hg@59: if (continuingLine == null) {
franta-hg@59: continuingLine = new StringBuilder();
franta-hg@59: }
franta-hg@59: continuingLine.append(currentLine);
franta-hg@59: } else {
franta-hg@59: String wholeLogicalLine = (continuingLine == null) ? currentLine : continuingLine.append("\n").append(currentLine).toString();
franta-hg@59: continuingLine = null;
franta-hg@59:
franta-hg@59: loadedData.load(new StringReader(wholeLogicalLine));
franta-hg@59: outputProperties(loadedData);
franta-hg@59: loadedData.clear();
franta-hg@59: }
franta-hg@59: }
franta-hg@59: }
franta-hg@59:
franta-hg@59: outputEnd();
franta-hg@59: }
franta-hg@59:
franta-hg@59: /**
franta-hg@59: * Default mode is streaming.
franta-hg@59: *
franta-hg@107: * @return false = do streaming | true = parse whole input as one batch and when all parsed,
franta-hg@59: * flush output
franta-hg@59: */
franta-hg@59: private boolean isInBatchMode() {
franta-hg@59: return Boolean.parseBoolean(String.valueOf(properties.get(PROPERTY_BATCH_MODE)));
franta-hg@59: }
franta-hg@59:
franta-hg@59: private void outputStart() throws SAXException {
franta-hg@21: contentHandler.startDocument();
franta-hg@21: contentHandler.startElement(null, null, "properties", null);
franta-hg@21:
franta-hg@75: contentHandler.lineBreak();
franta-hg@59: }
franta-hg@59:
franta-hg@59: private void outputProperty(String key, String value) throws SAXException {
franta-hg@75: contentHandler.indentation(1);
franta-hg@59:
franta-hg@59: AttributesImpl attributes = new AttributesImpl();
franta-hg@59: attributes.addAttribute(null, "name", "name", "xs:string", key);
franta-hg@59:
franta-hg@59: contentHandler.startElement(null, null, "property", attributes);
franta-hg@59: contentHandler.characters(value.toCharArray(), 0, value.length());
franta-hg@59: contentHandler.endElement(null, null, "property");
franta-hg@59:
franta-hg@75: contentHandler.lineBreak();
franta-hg@59: }
franta-hg@59:
franta-hg@59: private void outputProperties(Properties loadedData) throws SAXException {
franta-hg@21: for (Entry