[jOOQ/jOOQ#11341] intoXML() throws NPE exception
This includes: - [jOOQ/jOOQ#11634] XMLFormat.quoteNested() is not being considered in Result.intoXML()
This commit is contained in:
parent
aa0bbc2641
commit
50b7ba5e76
@ -219,6 +219,8 @@ abstract class AbstractFormattable implements Formattable, Serializable {
|
||||
formatCSV(writer, new CSVFormat().header(header).delimiter(delimiter).nullString(nullString));
|
||||
}
|
||||
|
||||
abstract JSONFormat defaultJSONFormat();
|
||||
|
||||
@Override
|
||||
public final String formatJSON() {
|
||||
StringWriter writer = new StringWriter();
|
||||
@ -245,12 +247,14 @@ abstract class AbstractFormattable implements Formattable, Serializable {
|
||||
|
||||
@Override
|
||||
public final void formatJSON(Writer writer) {
|
||||
formatJSON(writer, null);
|
||||
formatJSON(writer, defaultJSONFormat());
|
||||
}
|
||||
|
||||
abstract XMLFormat defaultXMLFormat();
|
||||
|
||||
@Override
|
||||
public final String formatXML() {
|
||||
return formatXML((XMLFormat) null);
|
||||
return formatXML(defaultXMLFormat());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -262,7 +266,7 @@ abstract class AbstractFormattable implements Formattable, Serializable {
|
||||
|
||||
@Override
|
||||
public final void formatXML(OutputStream stream) {
|
||||
formatXML(stream, null);
|
||||
formatXML(stream, defaultXMLFormat());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -272,7 +276,7 @@ abstract class AbstractFormattable implements Formattable, Serializable {
|
||||
|
||||
@Override
|
||||
public final void formatXML(Writer writer) {
|
||||
formatXML(writer, null);
|
||||
formatXML(writer, defaultXMLFormat());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -342,11 +346,11 @@ abstract class AbstractFormattable implements Formattable, Serializable {
|
||||
|
||||
@Override
|
||||
public final Document intoXML() {
|
||||
return intoXML((XMLFormat) null);
|
||||
return intoXML(defaultXMLFormat());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <H extends ContentHandler> H intoXML(H handler) throws SAXException {
|
||||
return intoXML(handler, null);
|
||||
return intoXML(handler, defaultXMLFormat());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1050,10 +1050,12 @@ abstract class AbstractRecord extends AbstractStore implements Record {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void formatJSON(Writer writer, JSONFormat format) {
|
||||
if (format == null)
|
||||
format = JSONFormat.DEFAULT_FOR_RECORDS;
|
||||
final JSONFormat defaultJSONFormat() {
|
||||
return JSONFormat.DEFAULT_FOR_RECORDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void formatJSON(Writer writer, JSONFormat format) {
|
||||
if (format.header())
|
||||
log.debug("JSONFormat.header currently not supported for Record.formatJSON()");
|
||||
|
||||
@ -1075,10 +1077,12 @@ abstract class AbstractRecord extends AbstractStore implements Record {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void formatXML(Writer writer, XMLFormat format) {
|
||||
if (format == null)
|
||||
format = XMLFormat.DEFAULT_FOR_RECORDS;
|
||||
final XMLFormat defaultXMLFormat() {
|
||||
return XMLFormat.DEFAULT_FOR_RECORDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void formatXML(Writer writer, XMLFormat format) {
|
||||
if (format.header())
|
||||
log.debug("XMLFormat.header currently not supported for Record.formatXML()");
|
||||
|
||||
|
||||
@ -49,6 +49,7 @@ import static org.jooq.tools.StringUtils.abbreviate;
|
||||
import static org.jooq.tools.StringUtils.leftPad;
|
||||
import static org.jooq.tools.StringUtils.rightPad;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.io.Writer;
|
||||
import java.sql.Date;
|
||||
import java.sql.Timestamp;
|
||||
@ -99,11 +100,15 @@ import org.jooq.tools.StringUtils;
|
||||
import org.jooq.tools.json.JSONValue;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.DocumentFragment;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.AttributesImpl;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
@ -611,10 +616,12 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void formatJSON(Writer writer, JSONFormat format) {
|
||||
if (format == null)
|
||||
format = JSONFormat.DEFAULT_FOR_RESULTS;
|
||||
final JSONFormat defaultJSONFormat() {
|
||||
return JSONFormat.DEFAULT_FOR_RESULTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void formatJSON(Writer writer, JSONFormat format) {
|
||||
try {
|
||||
String separator;
|
||||
int recordLevel = format.header() ? 2 : 1;
|
||||
@ -857,10 +864,12 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void formatXML(Writer writer, XMLFormat format) {
|
||||
if (format == null)
|
||||
format = XMLFormat.DEFAULT_FOR_RESULTS;
|
||||
final XMLFormat defaultXMLFormat() {
|
||||
return XMLFormat.DEFAULT_FOR_RESULTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void formatXML(Writer writer, XMLFormat format) {
|
||||
String newline = format.newline();
|
||||
int recordLevel = format.header() ? 2 : 1;
|
||||
|
||||
@ -1289,9 +1298,11 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
eValue.setAttribute("field", field.getName());
|
||||
eRecord.appendChild(eValue);
|
||||
|
||||
if (value != null) {
|
||||
eValue.setTextContent(format0(value, false, false));
|
||||
}
|
||||
if (value != null)
|
||||
if (value instanceof XML && !format.quoteNested())
|
||||
eValue.appendChild(createContent(builder, document, ((XML) value).data()));
|
||||
else
|
||||
eValue.setTextContent(format0(value, false, false));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1302,6 +1313,61 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
}
|
||||
}
|
||||
|
||||
// Taken from JOOX Util.createContent()
|
||||
static final DocumentFragment createContent(DocumentBuilder builder, Document doc, String text) {
|
||||
|
||||
// [#150] Text might hold XML content, which can be leniently identified by the presence
|
||||
// of either < or & characters (other entities, like >, ", ' are not stricly XML content)
|
||||
if (text != null && (text.contains("<") || text.contains("&"))) {
|
||||
|
||||
// [#162] Prevent log output
|
||||
builder.setErrorHandler(new DefaultHandler());
|
||||
|
||||
try {
|
||||
|
||||
// [#128] Trimming will get rid of leading and trailing whitespace, which would
|
||||
// otherwise cause a HIERARCHY_REQUEST_ERR raised by the parser
|
||||
text = text.trim();
|
||||
|
||||
// There is a processing instruction. We can safely assume
|
||||
// valid XML and parse it as such
|
||||
if (text.startsWith("<?xml")) {
|
||||
Document parsed = builder.parse(new InputSource(new StringReader(text)));
|
||||
DocumentFragment fragment = parsed.createDocumentFragment();
|
||||
fragment.appendChild(parsed.getDocumentElement());
|
||||
|
||||
return (DocumentFragment) doc.importNode(fragment, true);
|
||||
}
|
||||
|
||||
// Any XML document fragment. To be on the safe side, fragments
|
||||
// are wrapped in a dummy root node
|
||||
else {
|
||||
String wrapped = "<dummy>" + text + "</dummy>";
|
||||
Document parsed = builder.parse(new InputSource(new StringReader(wrapped)));
|
||||
DocumentFragment fragment = parsed.createDocumentFragment();
|
||||
NodeList children = parsed.getDocumentElement().getChildNodes();
|
||||
|
||||
// appendChild removes children also from NodeList!
|
||||
while (children.getLength() > 0) {
|
||||
fragment.appendChild(children.item(0));
|
||||
}
|
||||
|
||||
return (DocumentFragment) doc.importNode(fragment, true);
|
||||
}
|
||||
}
|
||||
|
||||
// This does not occur
|
||||
catch (java.io.IOException ignore) {}
|
||||
|
||||
// The XML content is invalid
|
||||
catch (SAXException ignore) {}
|
||||
}
|
||||
|
||||
// Plain text or invalid XML
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final <H extends ContentHandler> H intoXML(H handler, XMLFormat format) throws SAXException {
|
||||
Attributes empty = new AttributesImpl();
|
||||
|
||||
@ -412,6 +412,16 @@ package org.jooq.impl;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -65,7 +65,7 @@ final class XMLElement extends AbstractField<XML> {
|
||||
private final QueryPartList<Field<?>> content;
|
||||
|
||||
XMLElement(Name elementName, XMLAttributes attributes, Collection<? extends Field<?>> content) {
|
||||
super(N_XMLCONCAT, SQLDataType.XML);
|
||||
super(N_XMLELEMENT, SQLDataType.XML);
|
||||
|
||||
this.elementName = elementName;
|
||||
this.attributes = attributes;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user