tikhomirov@480: /* tikhomirov@539: * Copyright (c) 2012-2013 TMate Software Ltd tikhomirov@480: * tikhomirov@480: * This program is free software; you can redistribute it and/or modify tikhomirov@480: * it under the terms of the GNU General Public License as published by tikhomirov@480: * the Free Software Foundation; version 2 of the License. tikhomirov@480: * tikhomirov@480: * This program is distributed in the hope that it will be useful, tikhomirov@480: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@480: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@480: * GNU General Public License for more details. tikhomirov@480: * tikhomirov@480: * For information on how to redistribute this software under tikhomirov@480: * the terms of a license other than GNU General Public License tikhomirov@480: * contact TMate Software at support@hg4j.com tikhomirov@480: */ tikhomirov@480: package org.tmatesoft.hg.internal; tikhomirov@480: tikhomirov@480: import java.io.BufferedReader; tikhomirov@480: import java.io.File; tikhomirov@539: import java.io.FileInputStream; tikhomirov@480: import java.io.FileReader; tikhomirov@480: import java.io.IOException; tikhomirov@539: import java.io.InputStreamReader; tikhomirov@539: import java.io.Reader; tikhomirov@539: import java.nio.charset.Charset; tikhomirov@480: import java.util.Collection; tikhomirov@480: tikhomirov@628: import org.tmatesoft.hg.core.HgIOException; tikhomirov@480: import org.tmatesoft.hg.util.LogFacility; tikhomirov@480: tikhomirov@480: /** tikhomirov@480: * Handy class to read line-based configuration files tikhomirov@480: * tikhomirov@480: * @author Artem Tikhomirov tikhomirov@480: * @author TMate Software Ltd. tikhomirov@480: */ tikhomirov@480: public final class LineReader { tikhomirov@480: tikhomirov@480: public interface LineConsumer { tikhomirov@480: // boolean begin(File f, T paramObj) throws IOException; tikhomirov@480: boolean consume(String line, T paramObj) throws IOException; tikhomirov@480: // boolean end(File f, T paramObj) throws IOException; tikhomirov@480: } tikhomirov@480: tikhomirov@480: public static class SimpleLineCollector implements LineReader.LineConsumer> { tikhomirov@480: tikhomirov@480: public boolean consume(String line, Collection result) throws IOException { tikhomirov@480: result.add(line); tikhomirov@480: return true; tikhomirov@480: } tikhomirov@480: } tikhomirov@480: tikhomirov@480: private final File file; tikhomirov@480: private final LogFacility log; tikhomirov@539: private final Charset encoding; tikhomirov@480: private boolean trimLines = true; tikhomirov@480: private boolean skipEmpty = true; tikhomirov@480: private String ignoreThatStarts = null; tikhomirov@480: tikhomirov@480: public LineReader(File f, LogFacility logFacility) { tikhomirov@539: this(f, logFacility, null); tikhomirov@539: } tikhomirov@539: tikhomirov@539: public LineReader(File f, LogFacility logFacility, Charset lineEncoding) { tikhomirov@480: file = f; tikhomirov@480: log = logFacility; tikhomirov@539: encoding = lineEncoding; tikhomirov@480: } tikhomirov@480: tikhomirov@480: /** tikhomirov@480: * default: true tikhomirov@480: * false to return line as is tikhomirov@480: */ tikhomirov@480: public LineReader trimLines(boolean trim) { tikhomirov@480: trimLines = trim; tikhomirov@480: return this; tikhomirov@480: } tikhomirov@480: tikhomirov@480: /** tikhomirov@480: * default: true tikhomirov@480: * false to pass empty lines to consumer tikhomirov@480: */ tikhomirov@480: public LineReader skipEmpty(boolean skip) { tikhomirov@480: skipEmpty = skip; tikhomirov@480: return this; tikhomirov@480: } tikhomirov@480: tikhomirov@480: /** tikhomirov@480: * default: doesn't skip any line. tikhomirov@480: * set e.g. to "#" or "//" to skip lines that start with such prefix tikhomirov@480: */ tikhomirov@480: public LineReader ignoreLineComments(String lineStart) { tikhomirov@480: ignoreThatStarts = lineStart; tikhomirov@480: return this; tikhomirov@480: } tikhomirov@480: tikhomirov@649: /** tikhomirov@649: * tikhomirov@649: * @param consumer where to pipe read lines to tikhomirov@649: * @param paramObj parameterizes consumer tikhomirov@649: * @return paramObj value for convenience tikhomirov@649: * @throws HgIOException if there's {@link IOException} while reading file tikhomirov@649: */ tikhomirov@649: public T read(LineConsumer consumer, T paramObj) throws HgIOException { tikhomirov@480: BufferedReader statusFileReader = null; tikhomirov@480: try { tikhomirov@480: // consumer.begin(file, paramObj); tikhomirov@539: Reader fileReader; tikhomirov@539: if (encoding == null) { tikhomirov@539: fileReader = new FileReader(file); tikhomirov@539: } else { tikhomirov@590: fileReader = new InputStreamReader(new FileInputStream(file), encoding); tikhomirov@539: } tikhomirov@539: statusFileReader = new BufferedReader(fileReader); tikhomirov@480: String line; tikhomirov@480: boolean ok = true; tikhomirov@480: while (ok && (line = statusFileReader.readLine()) != null) { tikhomirov@480: if (trimLines) { tikhomirov@480: line = line.trim(); tikhomirov@480: } tikhomirov@480: if (ignoreThatStarts != null && line.startsWith(ignoreThatStarts)) { tikhomirov@480: continue; tikhomirov@480: } tikhomirov@480: if (!skipEmpty || line.length() > 0) { tikhomirov@480: ok = consumer.consume(line, paramObj); tikhomirov@480: } tikhomirov@480: } tikhomirov@649: return paramObj; tikhomirov@480: } catch (IOException ex) { tikhomirov@628: throw new HgIOException(ex.getMessage(), ex, file); tikhomirov@480: } finally { tikhomirov@624: new FileUtils(log).closeQuietly(statusFileReader); tikhomirov@480: // try { tikhomirov@480: // consumer.end(file, paramObj); tikhomirov@480: // } catch (IOException ex) { tikhomirov@624: // log.warn(getClass(), ex, null); tikhomirov@480: // } tikhomirov@480: } tikhomirov@480: } tikhomirov@480: }