package net.simpleframework.core;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.net.URL;
import javax.xml.parsers.SAXParserFactory;
import net.simpleframework.util.IConstants;
import net.simpleframework.util.IoUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import com.sun.org.apache.xerces.internal.impl.Constants;
/**
* LGPLv3
*
* @author (cknet@126.com, 13910090885)
* http://code.google.com/p/simpleframework/
* http://www.simpleframework.net
*/
public abstract class AbstractXmlDocument extends ALoggerAware {
protected Document document;
protected AbstractXmlDocument(final URL url) throws IOException {
try {
createDocument(url.openStream());
} catch (final DocumentException e) {
final String xString = stripNonValidXMLCharacters(IoUtils.getStringFromInputStream(
url.openStream(), IConstants.UTF8));
try {
createDocument(new StringReader(xString));
} catch (final Exception e0) {
throw new XMLParseException(e0);
}
} catch (final Throwable e) {
throw new XMLParseException(e);
}
}
protected AbstractXmlDocument(final Reader reader) {
try {
createDocument(reader);
} catch (final Throwable e) {
throw new XMLParseException(e);
}
}
protected AbstractXmlDocument(final InputStream inputStream) {
try {
createDocument(inputStream);
} catch (final Throwable e) {
throw new XMLParseException(e);
}
}
private void createDocument(final Reader reader) throws Exception {
this.document = getSAXReader().read(new InputSource(reader));
init();
}
private void createDocument(final InputStream inputStream) throws Exception {
this.document = getSAXReader().read(new InputSource(inputStream));
init();
}
private SAXReader getSAXReader() throws Exception {
final SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(isValidating());
factory.setNamespaceAware(isNamespaceAware());
final XMLReader xmlReader = factory.newSAXParser().getXMLReader();
final EntityResolver resolver = getEntityResolver();
if (resolver != null) {
xmlReader.setEntityResolver(resolver);
}
return setFeature(new SAXReader(xmlReader));
}
public Document getDocument() {
return document;
}
protected Element getRoot() {
return document.getRootElement();
}
protected Element getElement(final String name) {
return getElement(null, name);
}
protected Element getElement(Element parent, final String name) {
Element element = (parent == null ? (parent = getRoot()) : parent).element(name);
if (element == null) {
element = parent.addElement(name);
}
return element;
}
protected boolean isValidating() {
return false;
}
protected boolean isNamespaceAware() {
return false;
}
protected boolean isLoadExternalDTDFeature() {
return false;
}
protected SAXReader setFeature(final SAXReader reader) throws SAXException {
reader.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE,
isLoadExternalDTDFeature());
return reader;
}
protected EntityResolver getEntityResolver() {
return null;
}
protected void init() throws Exception {
}
public String stripNonValidXMLCharacters(final String in) {
final StringBuilder out = new StringBuilder();
char current;
if (in == null || ("".equals(in)))
return "";
for (int i = 0; i < in.length(); i++) {
current = in.charAt(i);
if ((current == 0x9) || (current == 0xA) || (current == 0xD)
|| ((current >= 0x20) && (current <= 0xD7FF))
|| ((current >= 0xE000) && (current <= 0xFFFD))
|| ((current >= 0x10000) && (current <= 0x10FFFF)))
out.append(current);
}
return out.toString();
}
static class XMLParseException extends SimpleException {
private static final long serialVersionUID = 3959123626087714493L;
public XMLParseException(final String msg) {
super(msg);
}
public XMLParseException(final Throwable cause) {
super(null, cause);
}
public XMLParseException(final String msg, final Throwable cause) {
super(msg, cause);
}
}
}
|