package com.thaiopensource.relaxng.util;

import java.util.ResourceBundle;
import java.text.MessageFormat;
import java.io.PrintStream;

import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXParseException;
import org.xml.sax.SAXException;

class ErrorHandlerImpl implements ErrorHandler {
  private PrintStream err;
  
  private String bundleName
    = "com.thaiopensource.relaxng.util.resources.Messages";

  private ResourceBundle bundle = null;

  public ErrorHandlerImpl() {
    this.err = System.err;
  }

  public ErrorHandlerImpl(PrintStream err) {
    this.err = err;
  }

  private String getString(String key) {
    if (bundle == null)
      bundle = ResourceBundle.getBundle(bundleName);
    return bundle.getString(key);
  }

  String format(String key, Object[] args) {
    return MessageFormat.format(getString(key), args);
  }

  public void warning(SAXParseException e) throws SAXParseException {
    print(format("warning",
		 new Object[] { formatMessage(e), formatLocation(e) }));
  }

  public void error(SAXParseException e) {
    print(format("error",
		 new Object[] { formatMessage(e), formatLocation(e) }));
  }

  public void fatalError(SAXParseException e) throws SAXParseException {
    throw e;
  }

  public void printException(Throwable e) {
    String loc;
    if (e instanceof SAXParseException)
      loc = formatLocation((SAXParseException)e);
    else
      loc = "";
    String message;
    if (e instanceof SAXException)
      message = formatMessage((SAXException)e);
    else
      message = formatMessage(e);
    print(format("fatal", new Object[] { message, loc }));
  }

  void print(String message) {
    if (message.length() != 0)
      err.println(message);
  }

  private String formatLocation(SAXParseException e) {
    String systemId = e.getSystemId();
    int n = e.getLineNumber();
    Integer lineNumber = n >= 0 ? new Integer(n) : null;
    n = e.getColumnNumber();
    Integer columnNumber = n >= 0 ? new Integer(n) : null;
    if (systemId != null) {
      if (lineNumber != null) {
	if (columnNumber != null)
	  return format("locator_system_id_line_number_column_number",
			new Object[] { systemId, lineNumber, columnNumber });
	else
	  return format("locator_system_id_line_number",
			new Object[] { systemId, lineNumber });
      }
      else
	return format("locator_system_id",
		      new Object[] { systemId });
    }
    else if (lineNumber != null) {
      if (columnNumber != null)
	return format("locator_line_number_column_number",
		      new Object[] { lineNumber, columnNumber });
      else
	return format("locator_line_number",
		      new Object[] { lineNumber });
    }
    else
      return "";
  }

  private String formatMessage(SAXException se) {
    Exception e = se.getException();
    String detail = se.getMessage();
    if (e != null) {
      String detail2 = e.getMessage();
      if (detail2 == detail)
	return formatMessage(e);
      else if (detail2 == null)
	return format("exception",
		      new Object[]{ e.getClass().getName(), detail });
      else
	return format("tunnel_exception",
		      new Object[] { e.getClass().getName(),
				     detail,
				     detail2 });
    }
    else {
      if (detail == null)
	detail = getString("no_detail");
      return detail;
    }
  }

  private String formatMessage(Throwable e) {
    String detail = e.getMessage();
    if (detail == null)
      detail = getString("no_detail");
    return format("exception",
		  new Object[] { e.getClass().getName(), detail });
  }
}

@@ -116,24 +116,76 @@
 ava.io.Print
+Writer;%0Aimport java.io.Writer;%0Aimport java.io.Output
 Stream;%0A%0Aimp
@@ -346,30 +346,30 @@
 rivate Print
-Stream
+Writer
  err;%0A  %0A  p
@@ -533,23 +533,17 @@
     this
-.err = 
+(
 System.e
@@ -544,16 +544,17 @@
 stem.err
+)
 ;%0A  %7D%0A%0A 
@@ -582,45 +582,185 @@
 mpl(
-PrintStream err) %7B%0A    this.err = err
+OutputStream os) %7B%0A    this.err = new PrintWriter(os);%0A  %7D%0A%0A  public ErrorHandlerImpl(Writer w) %7B%0A    this.err = new PrintWriter(w);%0A  %7D%0A%0A  public void close() %7B%0A    err.close()
 ;%0A  
@@ -1856,16 +1856,18 @@
 () != 0)
+ %7B
 %0A      e
@@ -1887,16 +1887,41 @@
 ssage);%0A
+      err.flush();%0A    %7D%0A
   %7D%0A%0A  p

Use a PrintWriter.