package przyklady.software;
/**Przykład do artykułu "Alternatywne źródła SAX".
 * Parser SAX czytający dane ze strumienia
 * i reagujący na nadchodzące dane zdarzeniami SAX.
 * Uogólnienie pewnej formy zdarzeń czasu rzeczywistego.
 * 
 * Kwiecień 2004.
 * @author Patryk Czarnik
 */

import java.io.IOException;
import java.io.Reader;

import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.AttributesImpl;

/**Parser SAX czytający dane ze strumienia znaków
 * w sposób blokujący i reagujący na każdą porcję danych
 * zdarzeniami SAX reprezentującymi element XML (dane).
 * @author Patryk Czarnik
 */
public class StreamEventsReader implements XMLReader {

  public void parse(String aSystemId) throws IOException, SAXException {
    this.parse(new InputSource(aSystemId));
  }

  /** Czytamy dane ze strumienia Reader podanego (w postaci opakowanej) w aInput. */
  public void parse(InputSource aInput) throws IOException, SAXException {
    if(fHandler != null) {
      Reader src = aInput.getCharacterStream();
      if(src == null)
        throw new SAXException("Nie okreslono zrodla danych");
      char[] buffer = new char[cBufferSize];
      AttributesImpl attrs = new AttributesImpl();

      fHandler.startDocument();
      fHandler.startElement("", "zdarzenia", "zdarzenia", attrs);
      while(true) {
        int len = src.read(buffer);
        if(len == -1)
          break;
        attrs.addAttribute("", "rozmiar", "rozmiar", "CDATA", String.valueOf(len));
        fHandler.startElement("", "dane", "dane", attrs);
        fHandler.characters(buffer, 0, len);
        fHandler.endElement("", "dane", "dane");
        attrs.clear();
      }
      
      fHandler.endElement("", "zdarzenia", "zdarzenia");
      fHandler.endDocument();
    }
  }

  public ContentHandler getContentHandler() {
    return fHandler;
  }
  /**Ustawia obiekt, do którego będą wysyłane zdarzenia SAX
   * podczas parsowania.
   */
  public void setContentHandler(ContentHandler aHandler) {
    fHandler = aHandler;
  }

  // Nie implementowane:
  public DTDHandler getDTDHandler() {
    return null;
  }
  public void setDTDHandler(DTDHandler handler) {
  }
  public EntityResolver getEntityResolver() {
    return null;
  }
  public void setEntityResolver(EntityResolver resolver) {
  }
  public ErrorHandler getErrorHandler() {
    return null;
  }
  public void setErrorHandler(ErrorHandler handler) {
  }
  public boolean getFeature(String name) throws SAXNotRecognizedException,
  SAXNotSupportedException {
    return false;
  }
  public void setFeature(String name, boolean value)
  	throws SAXNotRecognizedException, SAXNotSupportedException {
  }
  public Object getProperty(String name) throws SAXNotRecognizedException,
      SAXNotSupportedException {
    return null;
  }
  public void setProperty(String name, Object value)
      throws SAXNotRecognizedException, SAXNotSupportedException {
  }
  
  private static final int cBufferSize = 4096;
  private Counter fCounter;
  private ContentHandler fHandler;
}
