/* * This file is part of INDI for Java. * * INDI for Java is free software: you can redistribute it * and/or modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * INDI for Java 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 * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with INDI for Java. If not, see * <http://www.gnu.org/licenses/>. */ package laazotea.indi; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.StringReader; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; /** * A class that reads from a input stream and sends the read messages to a parser. * * @author S. Alonso (Zerjillo) [zerjioi at ugr.es] * @version 1.2, April 1, 2012 */ public class INDIProtocolReader extends Thread { /** * The parser to which the messages will be sent. */ private INDIProtocolParser parser; /** * Used to friendly stop the reader. */ private boolean stop; /** * Creates the reader. * @param parser The parser to which the readed messages will be sent. */ public INDIProtocolReader(INDIProtocolParser parser) { this.parser = parser; } /** * The main body of the reader. */ @Override public void run() { DocumentBuilderFactory docBuilderFactory; DocumentBuilder docBuilder; try { docBuilderFactory = DocumentBuilderFactory.newInstance(); docBuilder = docBuilderFactory.newDocumentBuilder(); docBuilder.setErrorHandler(new ErrorHandler() { @Override public void warning(SAXParseException e) throws SAXException { } @Override public void fatalError(SAXParseException e) throws SAXException { } @Override public void error(SAXParseException e) throws SAXException { } }); } catch (Exception e) { e.printStackTrace(); return; } int BUFFER_SIZE = 1000000; StringBuffer bufferedInput = new StringBuffer(); char[] buffer = new char[BUFFER_SIZE]; stop = false; BufferedReader in = new BufferedReader(new InputStreamReader(parser.getInputStream())); try { while (!stop) { int nReaded = in.read(buffer, 0, BUFFER_SIZE); if (nReaded != -1) { bufferedInput.append(buffer, 0, nReaded); // Appending to the buffer boolean errorParsing = false; try { String d = "<INDI>" + bufferedInput + "</INDI>"; //System.err.println(d); d = d.replaceAll("\\<\\?xml version='...'\\?\\>", ""); d = d.replaceAll("\\<\\?xml version=\"...\"\\?\\>", ""); // System.err.println(d); Document doc = docBuilder.parse(new InputSource(new StringReader(d))); parser.parseXML(doc); } catch (SAXException e) { errorParsing = true; } if (!errorParsing) { bufferedInput.setLength(0); // Empty the buffer because it has been already parsed } } else { // If -1 readed, end stop = true; } } } catch (IOException e) { // e.printStackTrace(); } parser.finishReader(); } /** * Sets the stop parameter. If set to <code>true</code> the reader will gracefully stop after the next read. * @param stop */ public void setStop(boolean stop) { this.stop = stop; } }