Skip to content

Commit

Permalink
[#5853] Alternative record representations
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaseder committed Feb 9, 2017
1 parent 95f9c12 commit b08e191
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 22 deletions.
77 changes: 65 additions & 12 deletions jOOQ/src/main/java/org/jooq/XMLFormat.java
Expand Up @@ -41,19 +41,21 @@
*/
public final class XMLFormat {

final boolean xmlns;
final boolean format;
final String newline;
final int indent;
final boolean header;
final boolean xmlns;
final boolean format;
final String newline;
final int indent;
final boolean header;
final RecordFormat recordFormat;

public XMLFormat() {
this(
true,
false,
"\n",
2,
true
true,
RecordFormat.VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE
);
}

Expand All @@ -62,13 +64,15 @@ private XMLFormat(
boolean format,
String newline,
int indent,
boolean header
boolean header,
RecordFormat recordFormat
) {
this.xmlns = xmlns;
this.format = format;
this.newline = newline;
this.indent = indent;
this.header = header;
this.recordFormat = recordFormat;
}

/**
Expand All @@ -80,7 +84,8 @@ public XMLFormat xmlns(boolean newXmlns) {
format,
newline,
indent,
header
header,
recordFormat
);
}

Expand All @@ -100,7 +105,8 @@ public XMLFormat format(boolean newFormat) {
newFormat,
newline,
indent,
header
header,
recordFormat
);
}

Expand All @@ -120,7 +126,8 @@ public XMLFormat newline(String newNewline) {
format,
newNewline,
indent,
header
header,
recordFormat
);
}

Expand All @@ -140,7 +147,8 @@ public XMLFormat indent(int newIndent) {
format,
newline,
newIndent,
header
header,
recordFormat
);
}

Expand All @@ -163,7 +171,8 @@ public XMLFormat header(boolean newHeader) {
format,
newline,
indent,
newHeader
newHeader,
recordFormat
);
}

Expand All @@ -173,4 +182,48 @@ public XMLFormat header(boolean newHeader) {
public boolean header() {
return header;
}

/**
* The record format to be applied, defaulting to
* {@link RecordFormat#VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE}.
*/
public XMLFormat recordFormat(RecordFormat newRecordFormat) {
return new XMLFormat(
xmlns,
format,
newline,
indent,
header,
newRecordFormat
);
}

/**
* The record format to be applied, defaulting to
* {@link RecordFormat#VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE}.
*/
public RecordFormat recordFormat() {
return recordFormat;
}

/**
* The format of individual XML records.
*/
public enum RecordFormat {

/**
* The default: <code>/record/value[@field="colname"]/text()</code>.
*/
VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE,

/**
* Simplified: <code>/record/value/text()</code>.
*/
VALUE_ELEMENTS,

/**
* Simplified: <code>/record/colname/text()</code>.
*/
COLUMN_NAME_ELEMENTS,
}
}
42 changes: 33 additions & 9 deletions jOOQ/src/main/java/org/jooq/impl/ResultImpl.java
Expand Up @@ -37,6 +37,8 @@

import static java.lang.Math.max;
import static java.lang.Math.min;
import static org.jooq.XMLFormat.RecordFormat.COLUMN_NAME_ELEMENTS;
import static org.jooq.XMLFormat.RecordFormat.VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE;
import static org.jooq.impl.DSL.insertInto;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.DSL.table;
Expand Down Expand Up @@ -1052,19 +1054,29 @@ public final void formatXML(Writer writer, XMLFormat format) {
writer.append(newline).append(indent[recordLevel]).append("<record>");

for (int index = 0; index < fields.fields.length; index++) {
writer.append(newline).append(indent[valueLevel]);

String tag = format.recordFormat() == COLUMN_NAME_ELEMENTS
? escapeXML(fields.fields[index].getName())
: "value";

Object value = record.get(index);

writer.append(newline).append(indent[valueLevel]).append("<value field=\"");
writer.append(escapeXML(fields.fields[index].getName()));
writer.append("\"");
writer.append("<" + tag);

if (format.recordFormat() == VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE) {
writer.append(" field=\"");
writer.append(escapeXML(fields.fields[index].getName()));
writer.append("\"");
}

if (value == null) {
writer.append("/>");
}
else {
writer.append(">");
writer.append(escapeXML(format0(value, false, false)));
writer.append("</value>");
writer.append("</" + tag + ">");
}
}

Expand Down Expand Up @@ -1195,8 +1207,14 @@ public final Document intoXML(XMLFormat format) {
Field<?> field = fields.fields[index];
Object value = record.get(index);

Element eValue = document.createElement("value");
eValue.setAttribute("field", field.getName());
String tag = format.recordFormat() == COLUMN_NAME_ELEMENTS
? escapeXML(fields.fields[index].getName())
: "value";

Element eValue = document.createElement(tag);

if (format.recordFormat() == VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE)
eValue.setAttribute("field", field.getName());
eRecord.appendChild(eValue);

if (value != null) {
Expand Down Expand Up @@ -1265,17 +1283,23 @@ public final <H extends ContentHandler> H intoXML(H handler, XMLFormat format) t
Field<?> field = fields.fields[index];
Object value = record.get(index);

String tag = format.recordFormat() == COLUMN_NAME_ELEMENTS
? escapeXML(fields.fields[index].getName())
: "value";

AttributesImpl attrs = new AttributesImpl();
attrs.addAttribute("", "", "field", "CDATA", field.getName());

handler.startElement("", "", "value", attrs);
if (format.recordFormat() == VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE)
attrs.addAttribute("", "", "field", "CDATA", field.getName());

handler.startElement("", "", tag, attrs);

if (value != null) {
char[] chars = format0(value, false, false).toCharArray();
handler.characters(chars, 0, chars.length);
}

handler.endElement("", "", "value");
handler.endElement("", "", tag);
}

handler.endElement("", "", "record");
Expand Down
13 changes: 12 additions & 1 deletion jOOQ/src/main/resources/xsd/jooq-export-3.10.0.xsd
Expand Up @@ -38,15 +38,26 @@
</complexType>

<complexType name="Record">
<!--
It is not possible, in XSD, to enforce a choice between a well defined type and a wildcard as below.
If, however, a <value/> element is present, then the following behaviour can be assumed:
- If there are only value elements, then the jooq-export:Value type is parsed
- If there is at least one non-value element, then the wildcard is parsed
<sequence>
<element name="value" type="jooq-export:Value" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
-->
<sequence>
<any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
</sequence>
</complexType>

<complexType name="Value">
<simpleContent>
<extension base="string">
<attribute name="field" type="string"/>
<attribute name="field" type="string" use="optional"/>
</extension>
</simpleContent>
</complexType>
Expand Down

0 comments on commit b08e191

Please sign in to comment.