/* Copyright (C) 2009 Mobile Sorcery AB
This program is free software; you can redistribute it and/or modify it
under the terms of the Eclipse Public License v1.0.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the Eclipse Public License v1.0 for
more details.
You should have received a copy of the Eclipse Public License v1.0 along
with this program. It is also available at http://www.eclipse.org/legal/epl-v10.html
*/
package com.mobilesorcery.sdk.core;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Reader;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.DefaultHandler;
public class LineReader implements Runnable {
public interface ILineHandler {
public void start(Process process);
public void newLine(String line);
/**
* <p>Is called upon when either<p>
* <ul>
* <li>An exception occurs, or
* <li>EOF
* </ul>
* @param e The exception that caused this process to exit (or not start), or <code>null</code> if EOF.
*/
public void stop(IOException e);
}
public static class LineAdapter implements ILineHandler {
@Override
public void start(Process process) {
}
@Override
public void newLine(String line) {
}
@Override
public void stop(IOException e) {
}
}
/**
* Allows for several {@link ILineHandler}s to listen
* to the same source.
*
*/
public static class LineHandlerList implements ILineHandler {
CopyOnWriteArrayList<ILineHandler> delegates = new CopyOnWriteArrayList<ILineHandler>();
public LineHandlerList() {
}
public void addHandler(ILineHandler handler) {
delegates.add(handler);
}
public void removeHandler(ILineHandler handler) {
delegates.remove(handler);
}
@Override
public void start(Process process) {
for (ILineHandler delegate : delegates) {
delegate.start(process);
}
}
@Override
public void newLine(String line) {
for (ILineHandler delegate : delegates) {
delegate.newLine(line);
}
}
@Override
public void stop(IOException e) {
for (ILineHandler delegate : delegates) {
delegate.stop(e);
}
}
}
public static class XMLLineAdapter extends DefaultHandler implements ILineHandler {
StringBuffer buffer = new StringBuffer();
@Override
public void start(Process process) {
}
@Override
public void newLine(String line) {
buffer.append(line);
buffer.append('\n');
}
@Override
public final void stop(IOException ioe) {
Exception ex = ioe;
if (ioe == null) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse(new ByteArrayInputStream(buffer.toString().getBytes()), this);
} catch (Exception e) {
ex = e;
}
}
doStop(ex);
}
protected void doStop(Exception e) {
}
}
private final Reader from;
private final ILineHandler callback;
public LineReader(Reader from, ILineHandler callback) {
this.from = from;
this.callback = callback;
}
public void start() {
Thread thread = new Thread(this);
thread.setDaemon(true);
thread.start();
}
@Override
public void run() {
IOException ex = null;
try {
LineNumberReader reader = new LineNumberReader(from);
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
if (callback != null) {
callback.newLine(line);
}
}
} catch (IOException e) {
ex = e;
e.printStackTrace();
} finally {
if (callback != null) {
callback.stop(ex);
}
}
}
}