package com.alethis.xml;

import org.xml.sax.XMLReader;
import org.xml.sax.SAXException;
import org.xml.sax.InputSource;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.XMLReaderFactory;
import java.io.*;

public class ParseUsingSAX {
    
    public final static void main(String[] args) {
        try {
            File f = new File("c:\\project\\xml\\in.xml");
            FileReader fr = new FileReader(f);
            BufferedReader br = new BufferedReader(fr);
            InputSource is = new InputSource(br);
            
            /*
             *  Possible parsers:
             *   org.apache.xerces.parsers.SAXParser
             *   org.apache.crimson.parser.XMLReaderImpl
             *   gnu.xml.aelfred2.XmlReader
             *   com.bluecast.xml.Piccolo
             *   oracle.xml.parser.v2.SAXParser
             */
            XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
            parser.setContentHandler(new ContentHandlerImpl());
            parser.parse(is);
            
            System.out.println("DONE");
        }
        catch (SAXException se) {
            System.out.println("SAX exception: " + se.getMessage());
        }
        catch (IOException ioe) {
            System.out.println("IO exception: " + ioe.getMessage());
        }
    }
}

class ContentHandlerImpl implements ContentHandler {
    
    private Locator locator;
    
    public void setDocumentLocator(Locator locator) {
        this.locator = locator;
    }
    
    public void startDocument() throws SAXException {
        System.out.println(getLocation() + " startDocument");
    }
    
    public void endDocument() throws SAXException {
        System.out.println(getLocation() + " endDocument");
    }
    
    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
        System.out.println(getLocation() + " startElement /" + namespaceURI + "/" + localName + "/" + qName + "/");
        for (int i = 0; i < atts.getLength(); i++) {
            System.out.println("             attribute: /" + atts.getURI(i) + "/" + atts.getLocalName(i) + "/" + atts.getQName(i) + "/" + atts.getType(i) + "/" + atts.getValue(i) + "/");
        }
    }
    
    public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
        System.out.println(getLocation() + " endElement /" + namespaceURI + "/" + localName + "/" + qName + "/");
    }
    
    public void characters(char[] ch, int start, int length) throws SAXException {
        System.out.print(getLocation() + " characters /");
        for (int i = start; i < start + length; i++) {
            switch (ch[i]) {
                case '\n': System.out.print("\\n"); break;
                case '\r': System.out.print("\\r"); break;
                case '\f': System.out.print("\\f"); break;
                case '\t': System.out.print("\\t"); break;
                default: System.out.print(ch[i]);
            }
        }
        System.out.println("/");
    }
    
    public void startPrefixMapping(String prefix, String uri) throws SAXException {
        System.out.println(getLocation() + " start prefix mapping /" + prefix + "/" + uri + "/");
    }
    
    public void endPrefixMapping(String prefix) throws SAXException {
        System.out.println(getLocation() +  "end prefix mapping /" + prefix + "/");
    }
    
    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
        System.out.println(getLocation() + " ignorable whitespace of length " + length);
    }
    
    public void processingInstruction(String target, String data) throws SAXException {
        System.out.println(getLocation() + " processing instruction /" + target + "/" + data + "/");
    }
    
    public void skippedEntity(String name) throws SAXException {
        System.out.println(getLocation() + " skipped entity /" + name + "/");
    }
    
    public String getLocation() {
        if (locator == null) {
            return "";
        }
        else {
            return  "(" + locator.getLineNumber() + ", " + locator.getColumnNumber() + ")";
        }
    }
}