java/alt2xml-in-ini/src/cz/frantovo/alt2xml/in/ini/Reader.java
author František Kučera <franta-hg@frantovo.cz>
Sat, 06 Sep 2014 18:29:44 +0200
changeset 78 afcb4ccc6594
parent 77 36ee0aefea27
child 80 c5816dd82cbb
permissions -rw-r--r--
in-ini: first working version
     1 /**
     2  * Alt2XML
     3  * Copyright © 2014 František Kučera (frantovo.cz)
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, either version 3 of the License, or
     8  * (at your option) any later version.
     9  *
    10  * This program is distributed in the hope that it will be useful,
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  * GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License
    16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
    17  */
    18 package cz.frantovo.alt2xml.in.ini;
    19 
    20 import cz.frantovo.alt2xml.AbstractAlt2XmlReader;
    21 import cz.frantovo.alt2xml.in.Alt2ContentHandler;
    22 import java.io.BufferedReader;
    23 import java.io.IOException;
    24 import java.io.InputStreamReader;
    25 import java.util.logging.Level;
    26 import java.util.logging.Logger;
    27 import java.util.regex.Matcher;
    28 import java.util.regex.Pattern;
    29 import org.xml.sax.InputSource;
    30 import org.xml.sax.SAXException;
    31 
    32 /**
    33  *
    34  * @author Ing. František Kučera (frantovo.cz)
    35  */
    36 public class Reader extends AbstractAlt2XmlReader {
    37 
    38 	public static final String ROOT_ELEMENT = "ini";
    39 	private static final Logger log = Logger.getLogger(Reader.class.getName());
    40 
    41 	@Override
    42 	public void parse(InputSource input) throws IOException, SAXException {
    43 		outputStart();
    44 
    45 		try (BufferedReader br = new BufferedReader(new InputStreamReader(input.getByteStream()))) {
    46 			FileContext fc = new FileContext(contentHandler);
    47 			for (String currentLine = br.readLine(); currentLine != null; currentLine = br.readLine()) {
    48 				for (LINE_TYPE lineType : LINE_TYPE.values()) {
    49 					boolean lineProcessed = lineType.processLine(currentLine, fc);
    50 					if (lineProcessed) {
    51 						break;
    52 					}
    53 				}
    54 			}
    55 			fc.outputEndSection(fc.lastSection);
    56 
    57 		}
    58 
    59 		outputEnd();
    60 	}
    61 
    62 	private void outputStart() throws SAXException {
    63 		contentHandler.startDocument();
    64 		contentHandler.lineBreak();
    65 		contentHandler.startElement(null, null, ROOT_ELEMENT, null);
    66 		contentHandler.lineBreak();
    67 	}
    68 
    69 	private void outputEnd() throws SAXException {
    70 		contentHandler.endElement(null, null, "ini");
    71 		contentHandler.lineBreak();
    72 		contentHandler.endDocument();
    73 	}
    74 
    75 	private static class FileContext {
    76 
    77 		private final Alt2ContentHandler contentHandler;
    78 		private String lastSection;
    79 
    80 		public FileContext(Alt2ContentHandler contentHandler) {
    81 			this.contentHandler = contentHandler;
    82 		}
    83 
    84 		protected void outputStartSection(String name) throws SAXException {
    85 			contentHandler.indentation(1);
    86 			contentHandler.startElement(null, null, name, null);
    87 			contentHandler.lineBreak();
    88 		}
    89 
    90 		protected void outputEndSection(String name) throws SAXException {
    91 			if (name != null) {
    92 				contentHandler.indentation(1);
    93 				contentHandler.endElement(null, null, name);
    94 				contentHandler.lineBreak();
    95 			}
    96 		}
    97 	}
    98 
    99 	private static class LineContext {
   100 
   101 		private final String line;
   102 		private final Matcher matcher;
   103 
   104 		public LineContext(String line, Matcher matcher) {
   105 			this.line = line;
   106 			this.matcher = matcher;
   107 		}
   108 	}
   109 
   110 	private enum LINE_TYPE {
   111 
   112 		COMMENT("(;|#)\\s*(.*)") {
   113 
   114 					@Override
   115 					public void processLine(LineContext lc, FileContext fc) throws SAXException {
   116 						log.log(Level.FINER, "Comment: {0}", lc.matcher.group(2));
   117 					}
   118 
   119 				},
   120 		SECTION("\\[(.+)\\]") {
   121 
   122 					@Override
   123 					public void processLine(LineContext lc, FileContext fc) throws SAXException {
   124 						String name = lc.matcher.group(1);
   125 						fc.outputEndSection(fc.lastSection);
   126 						fc.outputStartSection(name);
   127 						fc.lastSection = name;
   128 					}
   129 
   130 				},
   131 		ENTRY("\\s*([^=]+)\\s*=\\s*(.+)") {
   132 
   133 					@Override
   134 					public void processLine(LineContext lc, FileContext fc) throws SAXException {
   135 						String key = lc.matcher.group(1);
   136 						String value = lc.matcher.group(2);
   137 
   138 						fc.contentHandler.indentation(2);
   139 						fc.contentHandler.textElement(value, null, null, key, null);
   140 						fc.contentHandler.lineBreak();
   141 
   142 					}
   143 
   144 				},;
   145 
   146 		private LINE_TYPE(String pattern) {
   147 			this.pattern = Pattern.compile(pattern);
   148 		}
   149 
   150 		private final Pattern pattern;
   151 
   152 		protected boolean processLine(String currentLine, FileContext fileContext) throws SAXException {
   153 			Matcher m = pattern.matcher(currentLine);
   154 			if (m.matches()) {
   155 				processLine(new LineContext(currentLine, m), fileContext);
   156 				return true;
   157 			} else {
   158 				return false;
   159 			}
   160 		}
   161 
   162 		public abstract void processLine(LineContext lc, FileContext fc) throws SAXException;
   163 	}
   164 
   165 }