import java.io.*;

import org.w3c.dom.*;
import org.xml.sax.*;
import javax.xml.parsers.*;

import org.apache.crimson.tree.*;
import org.apache.crimson.parser.*;


public class TestCrimson
{
    public static void main ( String[] args )
    {
        if ( args.length < 1 )
        {
            System.err.println( "\n\nUSAGE: TestCrimson <xml-file-name>\n\n" );
            
            System.exit( -1 );
        }
        
        try
        {
            String msg = readFile( args[0] );
            
            System.out.println( "Input:\n" + msg );
            
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance( );
            
            // Set configuration options.
            if ( msg.indexOf( "<!DOCTYPE" ) != -1 )
                dbf.setValidating( true );
            
            dbf.setNamespaceAware( true );
            
            dbf.setIgnoringElementContentWhitespace( true );
            
            dbf.setCoalescing( true );
            
            
            DocumentBuilder db = dbf.newDocumentBuilder( );
            
            
            // Set an ErrorHandler before parsing
            OutputStreamWriter errorWriter = new OutputStreamWriter(System.err, "UTF-8");
            
            db.setErrorHandler( new MyErrorHandler(new PrintWriter(errorWriter, true)));
            
            
            System.out.println( "Parsing String to DOM ..." );

            XmlDocument doc = (XmlDocument)db.parse( new File( args[0] ) );
            
            doc.getDocumentElement().normalize( );
            
            
            // Generate using Crimson-specific output method.
            StringWriter sw = new StringWriter( );
            
            System.out.println( "Generating String from DOM ..." );

            doc.write( sw );
            
            String result = sw.toString( );

            System.out.println( "Output:\n" + result );

            FileWriter fw = new FileWriter( "TestCrimson.xml" );

            fw.write( result );

            fw.close( );
        }
        catch ( Exception e )
        {
            System.err.println( e );
            
            e.printStackTrace( );
        }
    }


    private static String readFile ( String fileName ) throws Exception
    {
        BufferedReader br = null;
        
        try
        {
            StringBuffer sb = new StringBuffer( );
            
            char[] inArray = new char [ 1024 ];
            
            br = new BufferedReader( new FileReader( fileName ) );
            
            // While file contents can be read, place what's read in buffer.
            do
            {
                int numRead = br.read( inArray, 0, inArray.length );
                
                // If EOF, we're done.
                if ( numRead == -1 )
                    break;
                
                // Append what we just got to end of buffer.
                sb.append( inArray, 0, numRead );
            }
            while ( true );
            
            // Return buffer as string.
            return( sb.toString() );
        }
        finally   // Make sure we always close the stream.
        {
            if ( br != null )
                br.close( );
        }
    }



    // The following code was taken from DOMEcho.java.

    // Error handler to report errors and warnings
    private static class MyErrorHandler implements ErrorHandler {
        /** Error handler output goes here */
        private PrintWriter out;
        
        MyErrorHandler(PrintWriter out) {
            this.out = out;
        }
        
        /**
         * Returns a string describing parse exception details
         */
        private String getParseExceptionInfo(SAXParseException spe) {
            String systemId = spe.getSystemId();
            if (systemId == null) {
                systemId = "null";
            }
            String info = "URI=" + systemId +
                " Line=" + spe.getLineNumber() +
                ": " + spe.getMessage();
            return info;
        }

        // The following methods are standard SAX ErrorHandler methods.
        // See SAX documentation for more info.

        public void warning(SAXParseException spe) throws SAXException {
            out.println("Warning: " + getParseExceptionInfo(spe));
        }
        
        public void error(SAXParseException spe) throws SAXException {
            String message = "Error: " + getParseExceptionInfo(spe);
            throw new SAXException(message);
        }

        public void fatalError(SAXParseException spe) throws SAXException {
            String message = "Fatal Error: " + getParseExceptionInfo(spe);
            throw new SAXException(message);
        }
    }
}
