
/*
 * @(#)Echo11.java	1.5 99/02/09
 *
 * Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
 * modify and redistribute this software in source and binary code form,
 * provided that i) this copyright notice and license appear on all copies of
 * the software; and ii) Licensee does not utilize the software in a manner
 * which is disparaging to Sun.
 *
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
 * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
 * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
 * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
 * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
 * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
 * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 *
 * This software is not designed or intended for use in on-line control of
 * aircraft, air traffic, aircraft navigation or aircraft communications; or in
 * the design, construction, operation or maintenance of any nuclear
 * facility. Licensee represents and warrants that it will not use or
 * redistribute the Software for such purposes.
 */

import java.io.*;

import org.xml.sax.*;

import javax.xml.parsers.SAXParserFactory;  
import javax.xml.parsers.ParserConfigurationException;  
import javax.xml.parsers.SAXParser;  

import com.sun.xml.parser.LexicalEventListener;

public class Echo11 extends HandlerBase
   implements LexicalEventListener
{
    public static void main (String argv [])
    {
        if (argv.length != 1) {
            System.err.println ("Usage: cmd filename");
            System.exit (1);
        }

        // Use the validating parser
        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setValidating(true);
        try {
            // Set up output stream
            out = new OutputStreamWriter (System.out, "UTF8");

            // Parse the input
            SAXParser saxParser = factory.newSAXParser();
            saxParser.parse( new File(argv [0]), new Echo11() );

        } catch (SAXParseException spe) {
           // Error generated by the parser
           System.out.println ("\n** Parsing error" 
              + ", line " + spe.getLineNumber ()
              + ", uri " + spe.getSystemId ());
           System.out.println("   " + spe.getMessage() );

           // Use the contained exception, if any
           Exception  x = spe;
           if (spe.getException() != null)
               x = spe.getException();
           x.printStackTrace();

        } catch (SAXException sxe) {
           // Error generated by this application
           // (or a parser-initialization error)
           Exception  x = sxe;
           if (sxe.getException() != null)
               x = sxe.getException();
           x.printStackTrace();

        } catch (ParserConfigurationException pce) {
            // Parser with specified options can't be built
            pce.printStackTrace();

        } catch (IOException ioe) {
           // I/O error
           ioe.printStackTrace();
        }

        System.exit (0);
    }

    static private Writer  out;
    private String indentString = "    "; // Amount to indent
    private int indentLevel = 0;

    //===========================================================
    // SAX DocumentHandler methods
    //===========================================================

    public void setDocumentLocator (Locator l)
    {
        // Save this to resolve relative URIs or to give diagnostics.
        try {
          out.write ("LOCATOR");
          out.write ("\n SYS ID: " + l.getSystemId() );
          out.flush ();
        } catch (IOException e) {
            // Ignore errors
        }
    }

    public void startDocument ()
    throws SAXException
    {
        nl();
        nl();
        emit ("START DOCUMENT");
        nl();
        emit ("<?xml version='1.0' encoding='UTF-8'?>");
    }

    public void endDocument ()
    throws SAXException
    {
        nl(); emit ("END DOCUMENT");
        try {
            nl();
            out.flush ();
        } catch (IOException e) {
            throw new SAXException ("I/O error", e);
        }
    }

    public void startElement (String name, AttributeList attrs)
    throws SAXException
    {
        indentLevel++;
        nl(); emit ("ELEMENT: ");
        emit ("<"+name);
        if (attrs != null) {
            for (int i = 0; i < attrs.getLength (); i++) {
                nl();
                emit("   ATTR: ");
                emit (attrs.getName (i));
                emit ("\t\"");
                emit (attrs.getValue (i));
                emit ("\"");
            }
        }
        if (attrs.getLength() > 0) nl();
        emit (">");
    }

    public void endElement (String name)
    throws SAXException
    {
        nl();
        emit ("END_ELM: ");
        emit ("</"+name+">");
        indentLevel--;
    }

    public void characters (char buf [], int offset, int len)
    throws SAXException
    {
        nl(); emit ("CHARS:   ");
        String s = new String(buf, offset, len);
        if (!s.trim().equals("")) emit (s);
    }

    public void ignorableWhitespace (char buf [], int offset, int len)
    throws SAXException
    {
        // Ignore it
    }

    public void processingInstruction (String target, String data)
    throws SAXException
    {
        nl();
        emit ("PROCESS: ");
        emit ("<?"+target+" "+data+"?>");
    }

    //===========================================================
    // SAX ErrorHandler methods
    //===========================================================

    // treat validation errors as fatal
    public void error (SAXParseException e)
    throws SAXParseException
    {
        throw e;
    }

    // dump warnings too
    public void warning (SAXParseException err)
    throws SAXParseException
    {
        System.out.println ("** Warning"
            + ", line " + err.getLineNumber ()
            + ", uri " + err.getSystemId ());
        System.out.println("   " + err.getMessage ());
    }

    //===========================================================
    // LexicalEventListener methods
    //===========================================================

    public void comment(java.lang.String text)
             throws SAXException
    {
       nl(); emit ("COMMENT: "+text);
    }

    public void startCDATA()
              throws SAXException
    {
    }

    public void endCDATA()
              throws SAXException
    {
    }

    public void startParsedEntity(java.lang.String name)
                       throws SAXException
    {
    }

    public void endParsedEntity(java.lang.String name,
                            boolean included)
                     throws SAXException
    {
    }

    //===========================================================
    // Helpers ...
    //===========================================================

    // Wrap I/O exceptions in SAX exceptions, to
    // suit handler signature requirements
    private void emit (String s)
    throws SAXException
    {
        try {
            out.write (s);
            out.flush ();
        } catch (IOException e) {
            throw new SAXException ("I/O error", e);
        }
    }

    // Start a new line
    // and indent the next line appropriately
    private void nl ()
    throws SAXException
    {
        String lineEnd =  System.getProperty("line.separator");
        try {
            out.write (lineEnd);
            for (int i=0; i < indentLevel; i++) out.write(indentString);
        } catch (IOException e) {
            throw new SAXException ("I/O error", e);
        }
    }
}
