Skip to content

Commit edd1344

Browse files
committed
fix #292 - modify implementation to match updates to REST implementation: remove context and format, expect top-level 'selected' attribute
1 parent 777d732 commit edd1344

File tree

3 files changed

+58
-102
lines changed

3 files changed

+58
-102
lines changed

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

Lines changed: 49 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -523,15 +523,17 @@ private class MatchDocumentSummaryImpl implements MatchDocumentSummary {
523523
private EventRange metadataEvents;
524524
private EventRange relevanceEvents;
525525
private ArrayList<String> similarUris;
526+
private String extractSelected;
526527

527-
public MatchDocumentSummaryImpl(String uri, int score, double confidence, double fitness, String path, String mimeType, Format format) {
528+
public MatchDocumentSummaryImpl(String uri, int score, double confidence, double fitness, String path, String mimeType, Format format, String extractSelected) {
528529
this.uri = uri;
529530
this.score = score;
530531
conf = confidence;
531532
fit = fitness;
532533
this.path = path;
533534
this.mimeType = mimeType;
534535
this.format = format;
536+
this.extractSelected = extractSelected;
535537
}
536538

537539
@Override
@@ -575,65 +577,66 @@ private void populateExtractedResult(ExtractedResultImpl result, List<XMLEvent>
575577
QName elementName = element.getName();
576578
if ( "extracted-none".equals(elementName.getLocalPart()) ) {
577579
result.isEmpty = true;
578-
}
579-
@SuppressWarnings("unchecked")
580-
Iterator<Attribute> attributes = element.getAttributes();
581-
while ( attributes.hasNext() ) {
582-
Attribute attr = attributes.next();
583-
String attrName = attr.getName().getLocalPart();
584-
if ( "context".equals(attrName) ) {
585-
result.context = attr.getValue();
586-
} else if ( "format".equals(attrName) ) {
587-
result.format = Format.valueOf(attr.getValue().toUpperCase());
588-
} else if ( "kind".equals(attrName) ) {
589-
result.kind = attr.getValue();
580+
} else {
581+
@SuppressWarnings("unchecked")
582+
Iterator<Attribute> attributes = element.getAttributes();
583+
while ( attributes.hasNext() ) {
584+
Attribute attr = attributes.next();
585+
String attrName = attr.getName().getLocalPart();
586+
if ( "kind".equals(attrName) ) {
587+
result.kind = attr.getValue();
588+
}
590589
}
591-
}
592-
int startChildren = start + 1;
593-
int endChildren = end - 1;
594-
// now get the children (extracted items) as strings
595-
EventRange extractedItemEvents = new EventRange(startChildren, endChildren);
596-
if ( Format.XML == getFormat() ) {
597-
result.setItems( populateExtractedItems(getSlice(events, extractedItemEvents)) );
598-
// if result.context is populated, this is not a root document node
599-
} else if ( Format.JSON == getFormat() && ! result.isEmpty && result.context != null ) {
600-
String json = events.get(startChildren).toString();
601-
try {
602-
JsonNode jsonArray = new ObjectMapper().readTree(json);
603-
ArrayList<String> items = new ArrayList<String>(jsonArray.size());
604-
for ( JsonNode item : jsonArray ) {
605-
items.add( item.toString() );
590+
int startChildren = start + 1;
591+
int endChildren = end - 1;
592+
// now get the children (extracted items) as strings
593+
EventRange extractedItemEvents = new EventRange(startChildren, endChildren);
594+
if ( Format.XML == getFormat() ) {
595+
result.setItems( populateExtractedItems(getSlice(events, extractedItemEvents)) );
596+
// if extractSelected is "include", this is not a root document node
597+
} else if ( Format.JSON == getFormat() && "include".equals(extractSelected) ) {
598+
String json = events.get(startChildren).toString();
599+
try {
600+
JsonNode jsonArray = new ObjectMapper().readTree(json);
601+
ArrayList<String> items = new ArrayList<String>(jsonArray.size());
602+
for ( JsonNode item : jsonArray ) {
603+
items.add( item.toString() );
604+
}
605+
result.setItems( items );
606+
} catch (Throwable e) {
607+
throw new MarkLogicIOException("Cannot parse JSON '" + json + "' for " +
608+
getPath(), e);
606609
}
610+
} else {
611+
ArrayList<String> items = new ArrayList<String>(1);
612+
items.add( events.get(startChildren).toString() );
607613
result.setItems( items );
608-
} catch (Throwable e) {
609-
throw new MarkLogicIOException("Cannot parse JSON '" + json + "' for " +
610-
result.context, e);
611614
}
612-
} else {
613-
ArrayList<String> items = new ArrayList<String>(1);
614-
items.add( events.get(startChildren).toString() );
615-
result.setItems( items );
616615
}
617616
}
618617

619618
private List<String> populateExtractedItems(List<XMLEvent> events) {
620619
List<String> items = new ArrayList<String>();
621620
List<XMLEvent> itemEvents = new ArrayList<XMLEvent>();
622-
QName startName = null;
621+
List<QName> startNames = new ArrayList<QName>();
623622
for ( XMLEvent event : events ) {
624623
itemEvents.add(event);
625624
switch (event.getEventType()) {
626625
case XMLStreamConstants.START_ELEMENT: {
627-
if (startName == null ) {
628-
startName = event.asStartElement().getName();
629-
}
626+
startNames.add(event.asStartElement().getName());
630627
break;
631628
}
632629
case XMLStreamConstants.END_ELEMENT: {
633-
if (startName.equals(event.asEndElement().getName())) {
634-
startName = null;
635-
items.add(Utilities.eventsToString(itemEvents));
636-
itemEvents = new ArrayList<XMLEvent>();
630+
QName startName = startNames.remove(startNames.size() - 1);
631+
if (startNames.size() == 0 ) {
632+
if ( startName.equals(event.asEndElement().getName())) {
633+
items.add(Utilities.eventsToString(itemEvents));
634+
itemEvents = new ArrayList<XMLEvent>();
635+
} else {
636+
throw new IllegalStateException("Error parsing xml \"" +
637+
Utilities.eventsToString(itemEvents) + "\", element " + startName +
638+
" doesn't end as expected");
639+
}
637640
}
638641
break;
639642
}
@@ -1060,6 +1063,7 @@ private class SearchResponseImpl {
10601063
private LinkedHashMap<String, EventRange> tempConstraints;
10611064

10621065
private String tempSnippetType;
1066+
private String tempExtractSelected;
10631067
private ArrayList<String> qtextList;
10641068

10651069
private EventRange tempQueryEvents;
@@ -1133,6 +1137,7 @@ private void handleResponse(XMLEventReader reader, StartElement element)
11331137
}
11341138
tempPageLength = Integer.parseInt(getAttribute(element, "page-length"));
11351139
tempStart = Long.parseLong(getAttribute(element, "start"));
1140+
tempExtractSelected = getAttribute(element, "selected");
11361141

11371142
collectTop(reader, element);
11381143
}
@@ -1173,7 +1178,7 @@ private void handleResult(XMLEventReader reader, StartElement element)
11731178
double fitness = Double.parseDouble(getAttribute(element, "fitness"));
11741179

11751180
currSummary = new MatchDocumentSummaryImpl(
1176-
ruri, score, confidence, fitness, path, mimeType, format);
1181+
ruri, score, confidence, fitness, path, mimeType, format, tempExtractSelected);
11771182

11781183
if (tempSummary == null) {
11791184
tempSummary = new ArrayList<MatchDocumentSummary>();
@@ -1611,8 +1616,6 @@ public <T> T getAs(Class<T> as) {
16111616

16121617
static private class ExtractedResultImpl implements ExtractedResult {
16131618
boolean isEmpty = false;
1614-
Format format;
1615-
String context;
16161619
String kind;
16171620
private List<String> itemStrings;
16181621
private List<ExtractedItem> items;
@@ -1621,12 +1624,6 @@ static private class ExtractedResultImpl implements ExtractedResult {
16211624
public boolean isEmpty() {
16221625
return isEmpty;
16231626
}
1624-
public Format getFormat() {
1625-
return format;
1626-
}
1627-
public String getContext() {
1628-
return context;
1629-
}
16301627
public String getKind() {
16311628
return kind;
16321629
}
@@ -1661,8 +1658,6 @@ public String toString() {
16611658
StringBuffer sb = new StringBuffer();
16621659
sb.append("ExtractedResult: ");
16631660
sb.append(isEmpty == true ? "isEmpty:[true] " : "");
1664-
sb.append(format != null ? "format:[" + format.toString() + "] " : "");
1665-
sb.append(context != null ? "context:[" + context + "] " : "");
16661661
sb.append(kind != null ? "kind:[" + kind + "] " : "");
16671662
for ( int i=1; i <= itemStrings.size(); i++ ) {
16681663
String item = itemStrings.get(i - 1);

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,6 @@
5050
**/
5151
public interface ExtractedResult extends Iterable<ExtractedItem> {
5252

53-
/** The format of the extracted data. Not always available, returns null if
54-
* unavailable. **/
55-
public Format getFormat();
56-
57-
/** The xquery to retrieve the parent document. Not always available, returns
58-
* null if unavailable. **/
59-
public String getContext();
60-
6153
/** The xquery type of the extracted data. For XML it will be "element". For
6254
* JSON it will be "object" or "array". Not always available, returns null if
6355
* unavailable. **/

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

Lines changed: 9 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public class RawQueryDefinitionTest {
7575
public static void beforeClass() {
7676
Common.connectAdmin();
7777
queryMgr = Common.client.newQueryManager();
78-
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.wire", "debug");
78+
//System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.wire", "debug");
7979
}
8080

8181
@AfterClass
@@ -366,8 +366,7 @@ public void testExtractDocumentData() throws Exception {
366366
for (MatchDocumentSummary summary : summaries) {
367367
ExtractedResult extracted = summary.getExtracted();
368368
if ( Format.XML == summary.getFormat() ) {
369-
assertEquals("fn:doc(\"/sample/first.xml\")", extracted.getContext());
370-
// we don't test for format or kind because they aren't sent in this case
369+
// we don't test for kind because it isn't sent in this case
371370
assertEquals(3, extracted.size());
372371
Document item1 = extracted.next().getAs(Document.class);
373372
assertEquals("1", item1.getFirstChild().getAttributes().getNamedItem("id").getNodeValue());
@@ -377,8 +376,7 @@ public void testExtractDocumentData() throws Exception {
377376
assertEquals("3", item3.getFirstChild().getAttributes().getNamedItem("id").getNodeValue());
378377
continue;
379378
} else if ( Format.JSON == summary.getFormat() ) {
380-
assertEquals("fn:doc(\"/basic1.json\")", extracted.getContext());
381-
// we don't test for format or kind because they aren't sent in this case
379+
// we don't test for kind because it isn't sent in this case
382380
assertEquals(3, extracted.size());
383381
for ( ExtractedItem item : extracted ) {
384382
String stringJsonItem = item.getAs(String.class);
@@ -405,11 +403,11 @@ public void testExtractDocumentData() throws Exception {
405403
for (int i=0; i < jsonSummaries.size(); i++ ) {
406404
JsonNode summary = jsonSummaries.get(i);
407405
String format = summary.get("format").textValue();
406+
String docPath = summary.get("path").textValue();
407+
assertNotNull(docPath);
408408
JsonNode extracted = summary.get("extracted");
409409
if ( "xml".equals(format) ) {
410-
String context = extracted.get("context").textValue();
411-
if ( context.contains("/sample/first.xml") ) {
412-
assertEquals("fn:doc(\"/sample/first.xml\")", context);
410+
if ( docPath.contains("/sample/first.xml") ) {
413411
JsonNode extractedItems = extracted.path("content");
414412
assertEquals(3, extractedItems.size());
415413
assertEquals(3, extractedItems.size());
@@ -422,9 +420,7 @@ public void testExtractDocumentData() throws Exception {
422420
continue;
423421
}
424422
} else if ( "json".equals(format) ) {
425-
String context = extracted.get("context").textValue();
426-
if ( context.contains("/basic1.json") ) {
427-
assertEquals("fn:doc(\"/basic1.json\")", context);
423+
if ( docPath.contains("/basic1.json") ) {
428424
JsonNode items = extracted.get("content");
429425
assertNotNull(items);
430426
assertEquals(3, items.size());
@@ -452,9 +448,6 @@ public void testExtractDocumentData() throws Exception {
452448
for (MatchDocumentSummary summary : summaries) {
453449
ExtractedResult extracted = summary.getExtracted();
454450
if ( Format.XML == summary.getFormat() ) {
455-
// TODO: find out why we don't get the context attribute in this case?
456-
//assertEquals("fn:doc(\"/sample/first.xml\")", extracted.getContext());
457-
assertEquals(Format.XML, extracted.getFormat());
458451
assertEquals("element", extracted.getKind());
459452
assertEquals(1, extracted.size());
460453
Document root = extracted.next().getAs(Document.class);
@@ -469,8 +462,6 @@ public void testExtractDocumentData() throws Exception {
469462
assertEquals("3", item3.getAttributes().getNamedItem("id").getNodeValue());
470463
continue;
471464
} else if ( Format.JSON == summary.getFormat() ) {
472-
// we don't test for context because it isn't sent in this case
473-
assertEquals(Format.JSON, extracted.getFormat());
474465
assertEquals("object", extracted.getKind());
475466
String jsonDocument = extracted.next().getAs(String.class);
476467
assertEquals("{\"a\":{\"b1\":{\"c\":\"jsonValue1\"}, \"b2\":[\"b2 val1\", \"b2 val2\"]}}",
@@ -489,6 +480,7 @@ public void testExtractDocumentData() throws Exception {
489480
JsonNode summary = jsonSummaries.get(i);
490481
String format = summary.get("format").textValue();
491482
String docPath = summary.get("path").textValue();
483+
assertNotNull(docPath);
492484
JsonNode extracted = summary.get("extracted");
493485
if ( "xml".equals(format) ) {
494486
if ( docPath.contains("/sample/first.xml") ) {
@@ -510,7 +502,6 @@ public void testExtractDocumentData() throws Exception {
510502
} else if ( "json".equals(format) ) {
511503
if ( docPath.contains("/basic1.json") ) {
512504
assertEquals("fn:doc(\"/basic1.json\")", docPath);
513-
assertEquals("json", extracted.get("format").textValue());
514505
assertEquals("object", extracted.get("kind").textValue());
515506
JsonNode items = extracted.get("content");
516507
assertNotNull(items);
@@ -541,16 +532,6 @@ public void testExtractDocumentData() throws Exception {
541532
for (MatchDocumentSummary summary : summaries) {
542533
ExtractedResult extracted = summary.getExtracted();
543534
assertTrue(extracted.isEmpty());
544-
if ( Format.XML == summary.getFormat() ) {
545-
assertEquals("fn:doc(\"/sample/first.xml\")", extracted.getContext());
546-
// we don't test for format or kind because they aren't sent in this case
547-
continue;
548-
} else if ( Format.JSON == summary.getFormat() ) {
549-
assertEquals("fn:doc(\"/basic1.json\")", extracted.getContext());
550-
// we don't test for format or kind because they aren't sent in this case
551-
continue;
552-
}
553-
fail("unexpected search result:" + summary.getUri());
554535
}
555536

556537
// test JSON response with XML and JSON document matches with path that does not match
@@ -560,21 +541,9 @@ public void testExtractDocumentData() throws Exception {
560541
assertEquals(2, jsonSummaries.size());
561542
for (int i=0; i < jsonSummaries.size(); i++ ) {
562543
JsonNode summary = jsonSummaries.get(i);
563-
String format = summary.get("format").textValue();
564544
JsonNode extractedNone = summary.get("extracted-none");
565545
assertNotNull(extractedNone);
566-
if ( "xml".equals(format) ) {
567-
String context = extractedNone.get("context").textValue();
568-
assertEquals("fn:doc(\"/sample/first.xml\")", context);
569-
assertEquals(1, extractedNone.size());
570-
continue;
571-
} else if ( "json".equals(format) ) {
572-
String context = extractedNone.get("context").textValue();
573-
assertEquals("fn:doc(\"/basic1.json\")", context);
574-
assertEquals(1, extractedNone.size());
575-
continue;
576-
}
577-
fail("unexpected search result:" + summary);
546+
assertEquals(0, extractedNone.size());
578547
}
579548
}
580549

0 commit comments

Comments
 (0)