Skip to content

Commit 9bb0adb

Browse files
committed
fix #388 (builds on fixes for #261 and #382) - when woodstox is on the classpath we get errors so we need to (1) flush XMLStreamWriter before writing to the underlying stream, (2) use writeNamespace for xs types since woodstox doesn't catch them when it tries to obey isRepairingNamespaces, (3) never send null to writeCharacters(), (4) don't rely on the default namespace for root elements--explicitly set the namespace to match the default namespace, (5) don't expect XMLEventReader.close() to close the underlying handle (we never should have--the javadocs say it shouldn't), (6) don't rely on XMLEvent.toString() to provide the text contents of an element, instead use asCharacters().getData(), (7) don't expect namespaces in the order they usually come--use JUnit assertXMLEquals instead of assertEquals when comparing XML
(cherry picked from commit 1e0c4d0)
1 parent fda1563 commit 9bb0adb

File tree

8 files changed

+75
-50
lines changed

8 files changed

+75
-50
lines changed

src/main/java/com/marklogic/client/alerting/RuleDefinition.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,8 @@ public void write(OutputStream out) throws IOException {
261261

262262
serializer.writeStartElement(RequestConstants.RESTAPI_PREFIX,
263263
"description", RequestConstants.RESTAPI_NS);
264-
serializer.writeCharacters(getDescription());
264+
String description = getDescription();
265+
if ( description != null ) serializer.writeCharacters(description);
265266
serializer.writeEndElement();
266267
serializer.flush();
267268

@@ -415,6 +416,7 @@ private void writeMetadataElement(final XMLStreamWriter serializer)
415416
TransformerException {
416417
serializer.writeStartElement("rapi", "rule-metadata",
417418
RequestConstants.RESTAPI_NS);
419+
serializer.writeNamespace("xs", XMLConstants.W3C_XML_SCHEMA_NS_URI);
418420

419421
for (Map.Entry<QName, Object> metadataProperty : getMetadata()
420422
.entrySet()) {

src/main/java/com/marklogic/client/impl/CombinedQueryBuilderImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import com.marklogic.client.query.RawCombinedQueryDefinition;
4747
import com.marklogic.client.query.RawQueryDefinition;
4848
import com.marklogic.client.query.RawStructuredQueryDefinition;
49+
import com.marklogic.client.query.StructuredQueryBuilder;
4950
import com.marklogic.client.query.StructuredQueryDefinition;
5051

5152
public class CombinedQueryBuilderImpl implements CombinedQueryBuilder {
@@ -273,7 +274,7 @@ private String makeXMLCombinedQuery(CombinedQueryDefinitionImpl qdef) {
273274
XMLStreamWriter serializer = makeXMLSerializer(out);
274275

275276
serializer.writeStartDocument();
276-
serializer.writeStartElement("search");
277+
serializer.writeStartElement(StructuredQueryBuilder.SEARCH_API_NS, "search");
277278
if ( qtext != null ) {
278279
serializer.writeStartElement("qtext");
279280
serializer.writeCharacters(qtext);

src/main/java/com/marklogic/client/impl/DocumentMetadataPatchBuilderImpl.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ public void writeCall(XMLOutputSerializer out, CallImpl call) throws Exception {
267267
XMLStreamWriter serializer = out.getSerializer();
268268
if (call.isFragment) {
269269
serializer.writeCharacters(""); // force the tag close
270+
serializer.flush();
270271
for (Object fragment: call.args) {
271272
out.getWriter().write(
272273
(fragment instanceof String) ?
@@ -325,6 +326,7 @@ public void process(Object original, String type, String value) {
325326
if (original == null)
326327
return;
327328
try {
329+
serializer.writeNamespace("xs", XMLConstants.W3C_XML_SCHEMA_NS_URI);
328330
serializer.writeAttribute(
329331
"xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type", type);
330332
serializer.writeCharacters(value);
@@ -1059,15 +1061,16 @@ public PatchHandle build() throws MarkLogicIOException {
10591061

10601062
XMLOutputSerializer out = new XMLOutputSerializer(writer, serializer);
10611063

1064+
serializer.writeStartDocument("utf-8", "1.0");
1065+
1066+
serializer.writeStartElement("rapi", "patch", REST_API_NS);
10621067
for (String nsPrefix: namespaces.getAllPrefixes()) {
10631068
serializer.setPrefix(
10641069
nsPrefix, namespaces.getNamespaceURI(nsPrefix)
10651070
);
1071+
serializer.writeNamespace(nsPrefix, namespaces.getNamespaceURI(nsPrefix));
10661072
}
10671073

1068-
serializer.writeStartDocument("utf-8", "1.0");
1069-
1070-
serializer.writeStartElement("rapi", "patch", REST_API_NS);
10711074

10721075
if (libraryNs != null && libraryAt != null) {
10731076
serializer.writeStartElement("rapi", "replace-library", REST_API_NS);

src/main/java/com/marklogic/client/impl/DocumentPatchBuilderImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ public void write(XMLOutputSerializer out) throws Exception {
125125
writeStartReplace(out, selectPath, cardinality);
126126
if (isFragment) {
127127
serializer.writeCharacters(""); // force the tag close
128+
serializer.flush();
128129
out.getWriter().write(inputAsString);
129130
} else {
130131
serializer.writeCharacters(inputAsString);
@@ -167,6 +168,7 @@ public void write(XMLOutputSerializer out) throws Exception {
167168
out, selectPath, contextPath, position.toString(), cardinality
168169
);
169170
serializer.writeCharacters(""); // force the tag close
171+
serializer.flush();
170172
out.getWriter().write(fragment);
171173
serializer.writeEndElement();
172174
}

src/main/java/com/marklogic/client/io/SearchHandle.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ protected void receiveContent(InputStream content) {
166166
SearchResponseImpl response = new SearchResponseImpl();
167167
response.parse(reader);
168168
reader.close();
169+
try {
170+
content.close();
171+
} catch (IOException e) {
172+
// ignore.
173+
}
169174

170175
summary =
171176
(response.tempSummary == null || response.tempSummary.size() < 1) ?
@@ -595,7 +600,12 @@ private void populateExtractedResult(ExtractedResultImpl result, List<XMLEvent>
595600
result.setItems( populateExtractedItems(getSlice(events, extractedItemEvents)) );
596601
// if extractSelected is "include", this is not a root document node
597602
} else if ( Format.JSON == getFormat() && "include".equals(extractSelected) ) {
598-
String json = events.get(startChildren).toString();
603+
XMLEvent event = events.get(startChildren);
604+
if ( XMLStreamConstants.CHARACTERS != event.getEventType() ) {
605+
throw new MarkLogicIOException("Cannot parse JSON for " +
606+
getPath() + "--content should be characters");
607+
}
608+
String json = event.asCharacters().getData();
599609
try {
600610
JsonNode jsonArray = new ObjectMapper().readTree(json);
601611
ArrayList<String> items = new ArrayList<String>(jsonArray.size());
@@ -608,8 +618,14 @@ private void populateExtractedResult(ExtractedResultImpl result, List<XMLEvent>
608618
getPath(), e);
609619
}
610620
} else {
621+
XMLEvent event = events.get(startChildren);
622+
if ( XMLStreamConstants.CHARACTERS != event.getEventType() ) {
623+
throw new MarkLogicIOException("Cannot read " +
624+
getPath() + "--content should be characters");
625+
}
626+
String text = event.asCharacters().getData();
611627
ArrayList<String> items = new ArrayList<String>(1);
612-
items.add( events.get(startChildren).toString() );
628+
items.add( event.asCharacters().getData() );
613629
result.setItems( items );
614630
}
615631
}

src/main/java/com/marklogic/client/query/StructuredQueryBuilder.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
* <pre>StructuredQueryDefinition andQry = structuredQueryBuilder.and(... query definitions ...);</pre>
6161
*/
6262
public class StructuredQueryBuilder {
63-
final static private String SEARCH_API_NS="http://marklogic.com/appservices/search";
63+
public static final String SEARCH_API_NS="http://marklogic.com/appservices/search";
6464

6565
/*
6666
* This map is used to prevent reuse of reserved prefixes in path expressions.
@@ -2422,7 +2422,7 @@ static private XMLStreamWriter makeSerializer(OutputStream out) {
24222422
try {
24232423
XMLStreamWriter serializer = factory.createXMLStreamWriter(out, "UTF-8");
24242424

2425-
serializer.setDefaultNamespace("http://marklogic.com/appservices/search");
2425+
serializer.setDefaultNamespace(SEARCH_API_NS);
24262426
serializer.setPrefix("xs", XMLConstants.W3C_XML_SCHEMA_NS_URI);
24272427

24282428
return serializer;
@@ -2456,7 +2456,7 @@ private void writeStructuredQueryImpl(OutputStream out, Object... objects) {
24562456

24572457
// omit the XML prolog
24582458
// serializer.writeStartDocument();
2459-
serializer.writeStartElement("query");
2459+
serializer.writeStartElement(SEARCH_API_NS, "query");
24602460

24612461
if (objects != null) {
24622462
if (objects instanceof AbstractStructuredQuery[]) {

src/test/java/com/marklogic/client/test/CombinedQueryBuilderTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public void buildCombinedQuery() throws Exception {
9191
public String buildExpected(String qtext, String collection) throws XMLStreamException, UnsupportedEncodingException {
9292
ByteArrayOutputStream baos = new ByteArrayOutputStream();
9393
XMLStreamWriter writer = makeXMLStreamWriter(baos);
94-
writer.writeStartElement("search");
94+
writer.writeStartElement(StructuredQueryBuilder.SEARCH_API_NS, "search");
9595
writer.writeStartElement("qtext");
9696
writer.writeCharacters(qtext);
9797
writer.writeEndElement();
@@ -104,6 +104,7 @@ public String buildExpected(String qtext, String collection) throws XMLStreamExc
104104
writer.writeEndElement();
105105
writeOptions(writer);
106106
writer.writeEndElement();
107+
writer.flush();
107108
return baos.toString("UTF-8");
108109
}
109110

@@ -119,6 +120,7 @@ public void writeOptions(XMLStreamWriter writer) throws XMLStreamException {
119120
writer.writeCharacters("filtered");
120121
writer.writeEndElement();
121122
writer.writeEndElement();
123+
writer.flush();
122124
}
123125

124126
public XMLStreamWriter makeXMLStreamWriter(OutputStream out) throws XMLStreamException {

0 commit comments

Comments
 (0)