package przyklady.software;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import org.xml.sax.ext.DefaultHandler2;

import util.Args;

import org.xml.sax.Attributes;
import org.xml.sax.ext.Attributes2;

/** Przyklad do artykulu "XML w Javie 5.0" (Software 2.0, 6/2005).
    Przyklad parsowania dokumentu w trybie SAX z obsluga zdarzen leksykalnych i wsparcia dla XInclude..
    Marzec 2005
    @author Patryk Czarnik
*/
public class SAXExample {
   public static void main(String args[]) {
	  args = Args.argsOrDefault(args, "dok1.xml");
      try {
         SAXParserFactory factory = SAXParserFactory.newInstance();
         if(!factory.getFeature("http://xml.org/sax/features/use-attributes2")) {
            System.out.println("Parser nie obsluguje Attributes2");
            return;
         }
         boolean xInclude = false;
         boolean validating = false;
         for(int i=1; i<args.length; ++i)
           if(args[i].equalsIgnoreCase("X"))
              xInclude = true;
           else if(args[i].equalsIgnoreCase("V"))
              validating = true;
         factory.setXIncludeAware(xInclude);
         factory.setValidating(validating);
         SAXParser parser = factory.newSAXParser();
	 CountingHandler handler = new CountingHandler();
	 parser.setProperty("http://xml.org/sax/properties/lexical-handler", handler);
         parser.parse(args[0], handler);
         handler.printResults();
      } catch(Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }
   }

   private static class CountingHandler extends DefaultHandler2 {
      private int fElemCnt = 0;
      private int fAttrCnt = 0;
      private int fDefAttrCnt = 0;
      private int fTextCnt = 0;
      private int fPICnt = 0;
      private int fCommentCnt = 0;
      private int fWSCnt = 0;
      private int fTextLen = 0;
      private int fWSLen = 0;
      private int fCommentLen = 0;
      
      public void startElement(String uri, String localName, String qName, Attributes atts) {
         ++fElemCnt;
         int length = atts.getLength();
         fAttrCnt += length;
	     Attributes2 atts2 = (Attributes2) atts;
         for(int i=0; i < length; ++i)
            if(!atts2.isSpecified(i))
	       ++fDefAttrCnt;
      }
      
      public void characters(char[] ch, int start, int length) {
         ++fTextCnt;
         fTextLen += length;
      }
      
      public void ignorableWhitespace(char[] ch, int start, int length) {
         ++fWSCnt;
         fWSLen += length;
      }

      public void processingInstruction(String aName, String aData) {
         ++fPICnt;
      }

      public void comment(char[] ch, int start, int length) {
         ++fCommentCnt;
         fCommentLen += length;
      }

      public void printResults() {
         System.out.println("Wyniki zliczania:");
         System.out.println("Elementow: "+fElemCnt);
         System.out.println("Atrybutow: "+fAttrCnt+" w tym domyslnych " + fDefAttrCnt);
         System.out.println("Instrukcji przetwarzania: "+fPICnt);
         System.out.println("Wezlow tekstowych: "+fTextCnt+" dlugosc: "+fTextLen);
         System.out.println("Wezlow IW: "+fWSCnt+" dlugosc: "+fWSLen);
         System.out.println("Komentarzy: "+fCommentCnt+" dlugosc: "+fCommentLen);
      }
   }
}
