package przyklady.software;
/**Przykład do artykułu "Alternatywne źródła SAX".
 * Filtr SAX liczący referencje i tworzący dokument wynikowy.
 * 
 * Kwiecień 2004.
 * @author Patryk Czarnik
 */
import java.io.IOException;
import java.util.Iterator;
import java.util.Map.Entry;

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.XMLFilter;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.AttributesImpl;

/**Filtr na podstawie dokumentu zgodnego z encyklopedia.dtd
 * tworzy dokument zgodny z wyniki.dtd zawierający liczbę
 * referencji do poszczególnych haseł w dokumencie źródłowym.
 * @author Patryk Czarnik
 *
 */
public class CountingFilter extends CountingHandler implements XMLFilter {
  public CountingFilter() {
    super();  // Konstruktor z CountingHandler
  }

  /**Metoda wywoływana na końcu dokumentu.
   * Dopiero wtedy wysyłamy dalej zdarzenia SAX reprezentujące
   * cały dokument z obliczonymi wynikami.
   */
  public void endDocument()
  throws SAXException {
    if(fHandler != null) {
      Iterator val_iter = getCounter().getValues().entrySet().iterator();
      AttributesImpl attrs = new AttributesImpl();
      
      fHandler.startDocument();
      fHandler.startElement("", "wyniki", "wyniki", attrs);
      
      while(val_iter.hasNext()) {
        Entry entry = (Entry)val_iter.next();
        String word = (String)entry.getKey();
        Integer count = (Integer)entry.getValue();
        
        attrs.addAttribute("", "haslo", "haslo", "CDATA", word);
        attrs.addAttribute("", "liczba", "liczba", "CDATA", count.toString());
        fHandler.startElement("", "wynik", "wynik", attrs);
        fHandler.endElement("", "wynik", "wynik");
        attrs.clear();
      }
      
      fHandler.endElement("", "wyniki", "wyniki");
      fHandler.endDocument();
    }
  }

  public XMLReader getParent() {
    return fParent;
  }

  /** Ustawia obiekt, z którego mają przychodzić zdarzenia SAX. */
  public void setParent(XMLReader aParent) {
    fParent = aParent;
    fParent.setContentHandler(this);
  }

  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;
  }

  public void parse(String aUrl) throws IOException, SAXException {
    if(fParent != null)
      fParent.parse(aUrl);
  }

  public void parse(InputSource aSrc) throws IOException, SAXException {
    if(fParent != null) {
      fParent.parse(aSrc);
    }
  }

  public boolean getFeature(String aName)
  throws SAXNotRecognizedException, SAXNotSupportedException {
    if(fParent != null)
      return fParent.getFeature(aName);
    else
      return false;
  }

  public void setFeature(String aName, boolean aValue)
  throws SAXNotRecognizedException, SAXNotSupportedException {
    if(fParent != null)
      fParent.setFeature(aName, aValue);
  }

  public DTDHandler getDTDHandler() {
    return null;
  }

  public void setDTDHandler(DTDHandler arg0) {
  }

  public EntityResolver getEntityResolver() {
    return null;
  }

  public void setEntityResolver(EntityResolver arg0) {
  }

  public ErrorHandler getErrorHandler() {
    return null;
  }

  public void setErrorHandler(ErrorHandler arg0) {
  }

  public Object getProperty(String aName)
  throws SAXNotRecognizedException, SAXNotSupportedException {
    if(fParent != null)
      return fParent.getProperty(aName);
    else
      throw new SAXNotSupportedException(aName);
  }

  public void setProperty(String aName, Object aValue)
  throws SAXNotRecognizedException, SAXNotSupportedException {
    if(fParent != null)
      fParent.setProperty(aName, aValue);
    else
      throw new SAXNotSupportedException(aName);
  }

  private XMLReader fParent;
  private ContentHandler fHandler;
}
