/*
* $Id: SAXHandler.java,v 1.21 2002/09/16 08:05:03 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.core.xml;
import anvil.ErrorListener;
import anvil.ErrorListenerImpl;
import anvil.core.Any;
import anvil.core.AnyTuple;
import anvil.core.Array;
import anvil.core.runtime.AnyFunction;
import anvil.doc.Doc;
import anvil.script.Context;
import anvil.script.Type;
import anvil.script.Scope;
import anvil.script.Function;
import java.io.IOException;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
/**
* class SAXHandler
*
* @author: Jani Lehtim�ki
*/
public class SAXHandler implements ErrorHandler, DTDHandler, ContentHandler, EntityResolver, Function
{
private Context _context;
private ErrorListener _listener = null;
private Any _userdata;
private Locator _locator = null;
private Any _error = null;
private Any _fatalError = null;
private Any _warning = null;
private Any _resolveEntity = null;
private Any _notationDecl = null;
private Any _unparsedEntityDecl = null;
private Any _startDocument = null;
private Any _endDocument = null;
private Any _startElement = null;
private Any _endElement = null;
private Any _startPrefixMapping = null;
private Any _endPrefixMapping = null;
private Any _characters = null;
private Any _ignorableWhitespace = null;
private Any _processingInstruction = null;
private Any _skippedEntity = null;
private Any _setDocumentLocator = null;
private Any[] _p5 = new Any[5];
public SAXHandler(Context context, Any callbacks, Any userdata)
{
_context = context;
_userdata = (userdata != null) ? userdata : Any.NULL;
_error = getFunction(context, callbacks, "error");
_fatalError = getFunction(context, callbacks, "fatalError");
_warning = getFunction(context, callbacks, "warning");
_resolveEntity = getFunction(context, callbacks, "resolveEntity");
_notationDecl = getFunction(context, callbacks, "notationDecl");
_unparsedEntityDecl = getFunction(context, callbacks, "unparsedEntityDecl");
_startDocument = getFunction(context, callbacks, "startDocument");
_endDocument = getFunction(context, callbacks, "endDocument");
_startElement = getFunction(context, callbacks, "startElement");
_endElement = getFunction(context, callbacks, "endElement");
_startPrefixMapping = getFunction(context, callbacks, "startPrefixMapping");
_endPrefixMapping = getFunction(context, callbacks, "endPrefixMapping");
_characters = getFunction(context, callbacks, "characters");
_ignorableWhitespace = getFunction(context, callbacks, "ignorableWhitespace");
_processingInstruction = getFunction(context, callbacks, "processingInstruction");
_skippedEntity = getFunction(context, callbacks, "skippedEntity");
_setDocumentLocator = getFunction(context, callbacks, "setDocumentLocator");
}
private Any getFunction(Context context, Any struct, String name)
{
Any value = struct.checkAttribute(context, name);
if (!value.isNull()) {
return value;
}
return null;
}
private String buildErrorString(String type, SAXParseException exception)
{
StringBuffer buffer = new StringBuffer(100);
String s;
buffer.append(type);
buffer.append(':');
buffer.append(' ');
s = exception.getPublicId();
if (s != null) {
buffer.append(s);
buffer.append(' ');
}
s = exception.getSystemId();
if (s != null) {
buffer.append(s);
buffer.append(' ');
}
buffer.append('[');
buffer.append(exception.getLineNumber());
buffer.append(':');
buffer.append(exception.getColumnNumber());
buffer.append(']');
buffer.append(' ');
buffer.append(exception.getMessage());
return buffer.toString();
}
/* ErrorHandler */
private AnyTuple buildLocation(SAXParseException exception)
{
Any[] list = new Any[4];
list[0] = Any.create(exception.getPublicId());
list[1] = Any.create(exception.getSystemId());
list[2] = Any.create(exception.getLineNumber());
list[3] = Any.create(exception.getColumnNumber());
return new AnyTuple(list);
}
public ErrorListener getListener()
{
return _listener;
}
public void error(SAXParseException exception)
{
if (_error != null) {
_error.execute(_context, buildLocation(exception),
Any.create(exception.getMessage()), _userdata);
} else {
if (_listener == null) {
_listener = new ErrorListenerImpl();
}
_listener.error(_context.getCurrentLocation(), buildErrorString("Error", exception));
}
}
public void fatalError(SAXParseException exception)
{
if (_fatalError != null) {
_fatalError.execute(_context, buildLocation(exception),
Any.create(exception.getMessage()), _userdata);
} else {
if (_listener == null) {
_listener = new ErrorListenerImpl();
}
_listener.error(_context.getCurrentLocation(), buildErrorString("Fatal error", exception));
}
}
public void warning(SAXParseException exception)
{
if (_warning != null) {
_warning.execute(_context, buildLocation(exception),
Any.create(exception.getMessage()), _userdata);
} else {
if (_listener == null) {
_listener = new ErrorListenerImpl();
}
_listener.error(_context.getCurrentLocation(), buildErrorString("Warning", exception));
}
}
/* DTDHandler */
public void notationDecl(String name, String publicId, String systemId)
{
if (_notationDecl != null) {
_notationDecl.execute(_context,
Any.create(name),
Any.create(publicId),
Any.create(systemId),
_userdata);
}
}
public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName)
{
if (_unparsedEntityDecl != null) {
_unparsedEntityDecl.execute(_context,
Any.create(name),
Any.create(publicId),
Any.create(systemId),
_userdata);
}
}
/* EntityResolver */
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException
{
if (_resolveEntity != null) {
return XMLModule.createInputSource(_context,
_resolveEntity.execute(_context,
Any.create(publicId), Any.create(systemId), _userdata));
}
return null;
}
/* ContentHandler */
public void setDocumentLocator(Locator locator)
{
_locator = locator;
if (_setDocumentLocator != null) {
_setDocumentLocator.execute(_context, new AnyFunction(this), _userdata);
}
}
public void skippedEntity(String name)
{
if (_skippedEntity != null) {
_skippedEntity.execute(_context, Any.create(name), _userdata);
}
}
public void startDocument()
{
if (_startDocument != null) {
_startDocument.execute(_context, _userdata);
}
}
public void endDocument()
{
if (_endDocument != null) {
_endDocument.execute(_context, _userdata);
}
}
public void startElement(String namespaceURI, String localName, String qName, Attributes attributes)
{
if (_startElement != null) {
_p5[0] = Any.create(namespaceURI);
_p5[1] = Any.create(localName);
_p5[2] = Any.create(qName);
int n = (attributes != null) ? attributes.getLength() : 0;
Array list = new Array(n);
for(int i=0; i<n; i++) {
String qname = attributes.getQName(i);
String value = attributes.getValue(i);
list.append(qname, Any.create(value));
}
_p5[3] = list;
_p5[4] = _userdata;
_startElement.execute(_context, _p5);
}
}
public void endElement(String namespaceURI, String localName, String qName)
{
if (_endElement != null) {
_endElement.execute(_context,
Any.create(namespaceURI),
Any.create(localName),
Any.create(qName),
_userdata);
}
}
public void characters(char[] ch, int start, int length)
{
if (_characters != null) {
_characters.execute(_context, Any.create(new String(ch, start, length)), _userdata);
}
}
public void ignorableWhitespace(char[] ch, int start, int length)
{
if (_ignorableWhitespace != null) {
_ignorableWhitespace.execute(_context, Any.create(new String(ch, start, length)), _userdata);
}
}
public void startPrefixMapping(String prefix, String uri)
{
if (_startPrefixMapping != null) {
_startPrefixMapping.execute(_context, Any.create(prefix), Any.create(uri), _userdata);
}
}
public void endPrefixMapping(String prefix)
{
if (_endPrefixMapping != null) {
_endPrefixMapping.execute(_context, Any.create(prefix), _userdata);
}
}
public void processingInstruction(String target, String data)
{
if (_processingInstruction != null) {
_processingInstruction.execute(_context, Any.create(target), Any.create(data), _userdata);
}
}
public String getName()
{
return "locator";
}
public String getQualifiedName()
{
return getName();
}
public int getType()
{
return FUNCTION;
}
public Scope getParent()
{
return null;
}
public Doc getDocument()
{
return null;
}
public Any execute(Context context, Any[] parameters)
{
Any[] list = new Any[4];
list[0] = Any.create(_locator.getPublicId());
list[1] = Any.create(_locator.getSystemId());
list[2] = Any.create(_locator.getLineNumber());
list[3] = Any.create(_locator.getColumnNumber());
return new AnyTuple(list);
}
public Any execute(Context context, Any self, Any[] parameters)
{
return execute(context, parameters);
}
public Any execute(Context context, Any self)
{
return execute(context, (Any[]) null);
}
public Any execute(Context context, Any self, Any param1)
{
return execute(context, (Any[]) null);
}
public Any execute(Context context, Any self, Any param1, Any param2)
{
return execute(context, (Any[]) null);
}
public Any execute(Context context, Any self, Any param1, Any param2, Any param3)
{
return execute(context, (Any[]) null);
}
public Any execute(Context context, Any self, Any param1, Any param2, Any param3, Any param4)
{
return execute(context, (Any[]) null);
}
public int getTypeRef(anvil.codec.ConstantPool pool)
{
return 0;
}
}