in-properties: streaming
authorFrantišek Kučera <franta-hg@frantovo.cz>
Wed, 03 Sep 2014 19:48:14 +0200
changeset 5912b4c1fc57a8
parent 58 c11792ae6489
child 60 61567e326e33
in-properties: streaming
java/alt2xml-in-properties/src/cz/frantovo/alt2xml/in/properties/Reader.java
     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>&lt;aaa&gt;&lt;bbb&gt;&lt;ccc&gt;xxx&lt;/ccc&gt;&lt;/bbb&gt;&lt;/aaa&gt;</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  	}