package com.cloudhopper.commons.xml;
/*
* #%L
* ch-commons-xbean
* %%
* Copyright (C) 2012 Cloudhopper by Twitter
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
/**
*
* @author joelauer
*/
public class SimpleHandlerAdapter extends DefaultHandler {
private static final Logger logger = LoggerFactory.getLogger(SimpleHandlerAdapter.class);
private SimpleHandler handler;
private SAXParseException error;
private int currentDepth;
private Attributes currentAttrs;
private StringBuilder charBuffer;
public SimpleHandlerAdapter(SimpleHandler handler) {
this(handler, 200);
}
public SimpleHandlerAdapter(SimpleHandler handler, int charBufferSize) {
this.handler = handler;
this.currentDepth = -1;
this.charBuffer = new StringBuilder(charBufferSize);
}
public SAXParseException getError() {
return this.error;
}
@Override
public void processingInstruction(String target, String value) {
logger.trace("processingInstruction target=[" + target + "], value=[" + value + "]");
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
//
// get the tag stripped of any namespace
//
String tag = (uri == null || uri.length() == 0) ? qName : localName;
//
// always increment the current depth
//
this.currentDepth++;
//
// reset character buffer at start of new element
//
charBuffer.setLength(0);
//
// reference to current attributes -- will be used during an endElement
//
this.currentAttrs = attrs;
logger.trace("startElement depth=[" + currentDepth + "], tag=[" + tag + "], uri=[" + uri + "], attrs.length=[" + currentAttrs.getLength() + "]");
handler.startElement(currentDepth, uri, tag, currentAttrs);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
//
// get the tag stripped of any namespace
//
String tag = (uri == null || uri.length() == 0) ? qName : localName;
logger.trace("endElement depth=[" + currentDepth + "], tag=[" + tag + "], uri=[" + uri + "], attrs.length=[" + currentAttrs.getLength() + "], charBuffer.length=[" + charBuffer.length() + "]");
handler.endElement(currentDepth, uri, tag, currentAttrs, charBuffer);
//
// always decrement the current depth
//
this.currentDepth--;
}
@Override
public void ignorableWhitespace(char buf[], int offset, int len) throws SAXException {
logger.trace("ignorableWhitespace buf.offset=[" + offset + "], buf.len=[" + len + "]");
}
@Override
public void characters(char buf[], int offset, int len) throws SAXException {
if (buf == null || buf.length <= 0) {
// do nothing
return;
}
charBuffer.append(buf, offset, len);
}
@Override
public void warning(SAXParseException ex) {
logger.warn("WARNING @ " + getLocationString(ex) + " : " + ex.toString(), ex);
}
@Override
public void error(SAXParseException ex) throws SAXException {
// Save error and continue to report other errors
if (error == null)
error = ex;
logger.error("ERROR @ " + getLocationString(ex) + " : " + ex.toString(), ex);
}
@Override
public void fatalError(SAXParseException ex) throws SAXException {
error = ex;
logger.error("FATAL @ " + getLocationString(ex) + " : " + ex.toString(), ex);
throw ex;
}
private String getLocationString(SAXParseException ex) {
return ex.getSystemId() + " line:" + ex.getLineNumber() + " col:" + ex.getColumnNumber();
}
@Override
public InputSource resolveEntity(String pid, String sid) {
logger.trace("resolveEntity pid=[" + pid + "], sid=[" + sid + "]");
return null;
}
}