/**
Copyright (c) 2012 Delcyon, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package com.delcyon.capo.xml.cdom;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Stack;
import org.w3c.dom.Document;
import org.xml.sax.Attributes;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.ext.DefaultHandler2;
import com.delcyon.capo.xml.XPath;
/**
* @author jeremiah
*
*/
public class CDOMHandler extends DefaultHandler2
{
public static final String NAMESPACE_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";
private CDocument document = null;
private Stack<CNode> nodeStack = new Stack<CNode>();
private EntityResolver entityResolver = null;
private ErrorHandler errorHandler = null;
private HashMap<String, String> prefixHashMap = new HashMap<String, String>();
public CDOMHandler(EntityResolver entityResolver, ErrorHandler errorHandler)
{
this.entityResolver = entityResolver;
this.errorHandler = errorHandler;
}
public Document getDocument()
{
this.document.normalizeDocument();
this.document.setSilenceEvents(false);
return this.document;
}
@Override
public void startDocument() throws SAXException
{
document = new CDocument();
document.setSilenceEvents(true);
nodeStack.push(document);
}
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException
{
//System.out.println(prefix+"==>"+uri);
prefixHashMap.put(prefix, uri);
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
//System.out.println(uri+"-->"+localName+"-->"+qName+"-->"+ReflectionUtility.processToString(attributes));
CElement element = new CElement(qName);
element.setOwnerDocument(document);
if(uri.isEmpty() == false)
{
element.setNamespaceURI(uri);
}
nodeStack.peek().appendChild(element);
for(int index = 0; index < attributes.getLength(); index++)
{
//System.out.println("Attr==>"+attributes.getURI(index)+"==>"+attributes.getQName(index)+"==>"+attributes.getValue(index));
CAttr attr = new CAttr(element,attributes.getURI(index),attributes.getQName(index),attributes.getValue(index));
element.setAttributeNode(attr);
}
Set<Entry<String, String>> prefixSet = prefixHashMap.entrySet();
for (Entry<String, String> entry : prefixSet)
{
if(entry.getKey().isEmpty())// && entry.getValue().equals(uri))
{
element.setAttributeNS(NAMESPACE_NAMESPACE_URI,"xmlns", entry.getValue());
document.setDefaultNamespace(entry.getValue());
}
else
{
element.setAttributeNS(NAMESPACE_NAMESPACE_URI,"xmlns:"+entry.getKey(), entry.getValue());
}
}
prefixHashMap.clear();
nodeStack.push(element);
}
@Override
public void processingInstruction(String target, String data) throws SAXException
{
CProcessingInstruction processingInstruction = new CProcessingInstruction(target,data);
nodeStack.peek().appendChild(processingInstruction);
}
@Override
public void comment(char[] ch, int start, int length) throws SAXException
{
CComment text = new CComment();
text.setData(new String(ch,start,length));
nodeStack.peek().appendChild(text);
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException
{
CText text = new CText();
text.setData(new String(ch,start,length));
nodeStack.peek().appendChild(text);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException
{
nodeStack.pop();
}
@Override
public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException
{
if (entityResolver != null)
{
return entityResolver.resolveEntity(publicId, systemId);
}
else
{
return null;
}
}
@Override
public void error(SAXParseException saxParseException) throws SAXException
{
errorHandler.error(saxParseException);
}
@Override
public void fatalError(SAXParseException saxParseException) throws SAXException
{
try
{
XPath.dumpNode(document, System.err);
}
catch (Exception e)
{
e.printStackTrace();
}
errorHandler.fatalError(saxParseException);
}
}