All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.brutusin.commons.io.LineReader Maven / Gradle / Ivy

There is a newer version: 1.6.5
Show newest version
/*
 * Copyright 2014 brutusin.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.brutusin.commons.io;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import org.brutusin.commons.org.apache.commons.io.input.CountingInputStream;

/**
 * Template utility class to process text input streams, line by line.
 *
 * @author Ignacio del Valle Alles [email protected]
 */
public abstract class LineReader {

    public static final String DEFAULT_CHARSET = "UTF-8";
    private CountingInputStream is;
    private boolean exit = false;
    private long lineNumber;
    private String nextLine;
    private String line;
    private final Charset charset;

    /**
     * Creates an instance using {@value #DEFAULT_CHARSET} as the text charset
     * of the input stream
     *
     * @param is Inputstream to process
     */
    public LineReader(InputStream is) {
        this(is, DEFAULT_CHARSET);
    }

    /**
     * Creates an instance using the specified charset
     *
     * @param is Inputstream to process
     * @param charset charset of the input stream
     * @throws UnsupportedCharsetException
     */
    public LineReader(InputStream is, String charset) throws UnsupportedCharsetException {
        this.is = new CountingInputStream(is);
        this.charset = Charset.forName(charset);
    }
    
    /**
     * Synchronously processes the input stream
     * @throws IOException
     * @throws InterruptedException 
     */
    public final void run() throws IOException, InterruptedException {
        InputStreamReader isr = new InputStreamReader(this.is, this.charset);
        BufferedReader br = new BufferedReader(isr);
        this.line = null;
        this.lineNumber = 0;
        try {
            do {
                if (this.exit) {
                    return;
                }
                if(Thread.currentThread().isInterrupted()){
                throw new InterruptedException();
            }
                this.nextLine = br.readLine();
                try {
                    if (this.line != null) {
                        processLine(this.line);
                        if (this.exit) {
                            return;
                        }
                    }
                } catch (Exception e) {
                    onExceptionFound(e);
                } finally {
                    this.lineNumber++;
                    this.line = this.nextLine;
                }
            } while (this.line != null);
        } finally {
            onFinish();
        }
    }

    /**
     * Stops the processing. To be called by subclasses or clients
     */
    public final void exit() {
        this.exit = true;
    }

    /**
     * Callback method. Guaranteed to be called after processing. Default
     * implementation does nothing
     */
    protected void onFinish() {
    }

    /**
     * Returns the number of the current processing line. 1-based
     * @return the line number
     */
    protected final long getLineNumber() {
        return this.lineNumber;
    }

    /**
     * @return {@code true} if is last line. {@code false} otherwise
     */
    protected final boolean isLastLine() {
        return this.nextLine == null;
    }

   /**
    * Returns the byte counter after the last buffer fill. Useful to estimate advance 
    * @return number of bytes read until now
    */
    protected final long getBytesBuffered() {
        return this.is.getByteCount();
    }

    /**
     * Returns current line content
     * @return 
     */
    public final String getLine() {
        return line;
    }

    /**
     * The actual processing to perform.
     * @param line current line
     * @throws Exception 
     */
    protected abstract void processLine(String line) throws Exception;

    /**
     * Exception handling. Processing continues unless this method throws
     * an uncatched throwable or {@link exit()} is called
     * @param ex current exception
     */
    protected abstract void onExceptionFound(Exception ex);
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy