import java.io.*;
import java.net.*;
import org.xml.sax.*;
import oracle.xml.parser.v2.*;

/** Diese Klasse <code>XMLParser</code> ist von <code>HandlerBase</code> 
	abgeleitet. <code>HandlerBase</code> implementiert die Interfaces 
	<code>EntityResolver, DTDHandler, DocumentHandler, ErrorHandler</code>.
	Es muessen hier nur die benötigten Methoden ueberschrieben werden.

	@author Rene Steiner, Akadia AG
*/
public class XMLParser extends HandlerBase
{
	// Locator speichern
	Locator locator;

	/** Hauptprogramm

		@param arguments Parameter die beim Programmstart uebergeben wurden
	*/
	static public void main(String[] arguments) {

		try {
			
			// XML Dateiname muss beim Programmstart uebergeben werden
			if (arguments.length != 1) {

				System.err.println("Verwendung: XMLParser <Dateiname>");
				System.exit(1);
			}

			// Parser Handler erzeugen
			XMLParser handler = new XMLParser();

			// SAX Parser erzeugen
			Parser parser = new SAXParser();

			// Den Handler dem Parser zuordnen
			parser.setDocumentHandler(handler);
			parser.setEntityResolver(handler);
			parser.setDTDHandler(handler);
			parser.setErrorHandler(handler);

			// Dateiname in URL konvertieren und Parsing ausfuehren
			try {
				parser.parse(toURL(new File(arguments[0])).toString());
			}
			catch (SAXParseException ex) {
				System.err.println("XMLParser.main(): " + ex.getMessage());
			}
			catch (SAXException ex) {
				System.err.println("XMLParser.main(): " + ex.getMessage());
			}

		}
		catch (Exception ex) {
			System.err.println("XMLParser.main(): " + ex.getMessage());
		}

	} // End of main()

	/** Diese Methode ist seit Java 2 in <code>java.io.File</code> vorhanden
		und muss hier nicht mehr implementiert werden. Wer Java 1 verwendet kann
		jedoch diese hier brauchen.

		@see java.io.File#toURL

		@param file Datei Objekt mit dem zu konvertierenden Dateinamen und Pfad

		@return URL

		@throws java.net.MalformedURLException
	*/
  static URL toURL(File file) throws MalformedURLException {

		String path			 = file.getAbsolutePath();
		String separator = System.getProperty("file.separator");

		if (separator != null && separator.length() == 1)
			path = path.replace(separator.charAt(0), '/');

		if (!path.startsWith("/"))
		    path = "/" + path;

		if (!path.endsWith("/") && file.isDirectory())
		    path = path + "/";

		return new URL("file", "", path);
	}


	/** Interface DocumentHandler
	*/
	public void setDocumentLocator(Locator locator) {

		System.out.println("setDocumentLocator");
		this.locator = locator;
	}

	/** Interface DocumentHandler
	*/
	public void startDocument() {

		System.out.println("startDocument");
	}

	/** Interface DocumentHandler
	*/
	public void endDocument() throws SAXException {

		System.out.println("endDocument");
	}

	/** Interface DocumentHandler
	*/
	public void startElement(String name, AttributeList attributes) 
				throws SAXException {
	
		System.out.println("startElement: " + name);

		for(int i = 0; i < attributes.getLength(); i++)
			System.out.println("->" + attributes.getName(i) + " " 
				+ attributes.getType(i) + "=" + attributes.getValue(i));
	}

	/** Interface DocumentHandler
	*/
	public void endElement(String name) throws SAXException {
	
		System.out.println("endElement: " + name);
	}

	/** Interface DocumentHandler
	*/
	public void characters(char[] cbuf, int start, int len) {

		System.out.print("characters: ");
		System.out.println(new String(cbuf, start, len));
	}

	/** Interface DocumentHandler
	*/
	public void ignorableWhitespace(char[] cbuf, int start, int len) {

		System.out.println("ignorableWhiteSpace");
	}

	/** Interface DocumentHandler
	*/
	public void processingInstruction(String target, String data) 
				throws SAXException {

		System.out.println("processingInstruction: " + target + " " + data);
	}


	/** Interface EntityResolver
	*/
	public InputSource resolveEntity(String publicId, String systemId)
				throws SAXException {

		System.out.println("resolveEntity: " 
			+ (publicId != null ? publicId : "(no public id)")
			+ " " + systemId);
		System.out.println("locator: " 
			+ (locator.getPublicId() != null ? locator.getPublicId() : "(no public id)")
			+ " " + locator.getSystemId() + " " + locator.getLineNumber() 
			+ " " + locator.getColumnNumber());

		return null;
	}


	/** Interface DTDHandler
	*/
	public void notationDecl(String name, String publicId, String systemId) {

		System.out.println("notationDecl: " + name + " " + publicId + " " + systemId);
	}

	/** Interface DTDHandler
	*/
	public void unparsedEntityDecl(String name, String publicId, String systemId, 
				String notationName)
	{
		System.out.println("unparsedEntityDecl: " + name + " " + publicId + " " +
			systemId + " " + notationName);
	}


	/** Interface ErrorHandler
	*/
	public void warning (SAXParseException ex) throws SAXException {

		System.err.println("WARNING: " + ex.getMessage());
		throw new SAXException(ex);
	}

	/** Interface ErrorHandler
	*/
	public void error(SAXParseException ex) throws SAXException {

		System.err.println("ERROR: " + ex.getMessage());
		throw new SAXException(ex);
	}

	/** Interface ErrorHandler
	*/
	public void fatalError(SAXParseException ex) throws SAXException {

		System.err.println("FATALERROR: " + ex.getMessage());
		throw new SAXException(ex);
	}

} // End of class XMLParser


