Skip to content
This repository was archived by the owner on Jul 23, 2025. It is now read-only.

Commit 71e73ba

Browse files
committed
Merge branch 'develop'
2 parents f136c15 + 696c07b commit 71e73ba

File tree

12 files changed

+182
-29
lines changed

12 files changed

+182
-29
lines changed

build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
plugins {
22
id "java"
33
id "maven-publish"
4-
id "com.jfrog.bintray" version "1.5"
5-
id "com.github.jk1.dependency-license-report" version "0.3.11"
4+
id "com.jfrog.bintray" version "1.8.4"
5+
id "com.github.jk1.dependency-license-report" version "1.3"
66
}
77

88
sourceCompatibility = "1.8"
@@ -19,7 +19,7 @@ repositories {
1919
}
2020

2121
dependencies {
22-
compile "com.marklogic:marklogic-client-api:4.0.4"
22+
compile "com.marklogic:marklogic-client-api:4.1.1"
2323

2424
testCompile "junit:junit:4+"
2525
testCompile "org.springframework:spring-test:4.3.7.RELEASE"

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
group=com.marklogic
22
javadocsDir=../gh-pages-marklogic-java/javadocs
3-
version=1.1
3+
version=1.2.0

src/main/java/com/marklogic/client/ext/datamovement/job/AbstractQueryBatcherJob.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22

33
import com.marklogic.client.DatabaseClient;
44
import com.marklogic.client.datamovement.*;
5+
import com.marklogic.client.document.ServerTransform;
56
import com.marklogic.client.ext.datamovement.*;
67
import com.marklogic.client.ext.datamovement.listener.SimpleBatchLoggingListener;
8+
import com.marklogic.client.ext.datamovement.util.TransformPropertyValueParser;
79

810
import java.util.ArrayList;
911
import java.util.Arrays;
1012
import java.util.List;
1113
import java.util.Properties;
14+
import java.util.function.BiConsumer;
1215
import java.util.function.Consumer;
1316

1417
/**
@@ -148,6 +151,19 @@ protected void addRequiredJobProperty(String name, String description, Consumer<
148151
jobProperties.add(prop);
149152
}
150153

154+
/**
155+
* Several jobs support a transform parameter, and we want each of them to inherit the support for providing
156+
* optional parameters after the transform name.
157+
*
158+
* @param consumer
159+
*/
160+
protected void addTransformJobProperty(BiConsumer<String, ServerTransform> consumer) {
161+
addJobProperty("transform", "The name of a REST transform to apply to each record. Parameters can be passed " +
162+
"to the transform by appending them to the value of this property, delimited by commas - e.g. myTransform,param1,value1,param2,value2",
163+
value -> consumer.accept(value, TransformPropertyValueParser.parsePropertyValue(value))
164+
);
165+
}
166+
151167
/**
152168
* Can be overridden by the subclass to prepare the QueryBatcher before the job is started.
153169
*

src/main/java/com/marklogic/client/ext/datamovement/job/ExportBatchesToDirectoryJob.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ public ExportBatchesToDirectoryJob() {
3535
addJobProperty("recordSuffix", "Optional content to be written after each record is written",
3636
value -> getExportListener().withRecordSuffix(value));
3737

38-
addJobProperty("transform", "Optional REST transform to apply to each record before it is written",
39-
value -> getExportListener().withTransform(new ServerTransform(value)));
38+
addTransformJobProperty((value, transform) -> getExportListener().withTransform(transform));
4039
}
4140

4241
public ExportBatchesToDirectoryJob(File exportDir) {

src/main/java/com/marklogic/client/ext/datamovement/job/ExportBatchesToZipsJob.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ public ExportBatchesToZipsJob() {
2525
addJobProperty("flattenUri", "Whether or not record URIs are flattened before being used as zip entry names; defaults to false",
2626
value -> getExportListener().withFlattenUri(Boolean.parseBoolean(value)));
2727

28-
addJobProperty("transform", "The name of a REST transform to apply to each record before it is written to the zip file",
29-
value -> getExportListener().withTransform(new ServerTransform(value)));
28+
addTransformJobProperty((value, transform) -> getExportListener().withTransform(transform));
3029

3130
addJobProperty("uriPrefix", "Prefix to prepend to each URI it is used as an entry name; applied after a URI is optionally flattened",
3231
value -> getExportListener().withUriPrefix(value));

src/main/java/com/marklogic/client/ext/datamovement/job/ExportToFileJob.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.marklogic.client.DatabaseClient;
44
import com.marklogic.client.datamovement.ExportToWriterListener;
55
import com.marklogic.client.datamovement.QueryBatcher;
6-
import com.marklogic.client.document.ServerTransform;
76
import com.marklogic.client.ext.datamovement.QueryBatcherJobTicket;
87
import com.marklogic.client.ext.datamovement.listener.XmlOutputListener;
98

@@ -53,8 +52,7 @@ public ExportToFileJob() {
5352
addJobProperty("recordSuffix", "Optional content to be written after each record is written",
5453
value -> setRecordSuffix(value));
5554

56-
addJobProperty("transform", "Optional REST transform to apply to each record before it is written",
57-
value -> getExportListener().withTransform(new ServerTransform(value)));
55+
addTransformJobProperty((value, transform) -> getExportListener().withTransform(transform));
5856
}
5957

6058
public ExportToFileJob(File exportFile) {

src/main/java/com/marklogic/client/ext/datamovement/job/ExportToZipJob.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import com.marklogic.client.document.ServerTransform;
66
import com.marklogic.client.ext.datamovement.QueryBatcherJobTicket;
77
import com.marklogic.client.ext.datamovement.consumer.WriteToZipConsumer;
8+
import com.marklogic.client.ext.datamovement.util.TransformPropertyValueParser;
89

910
import java.io.File;
11+
import java.util.function.BiConsumer;
1012

1113
public class ExportToZipJob extends AbstractQueryBatcherJob {
1214

@@ -23,8 +25,7 @@ public ExportToZipJob() {
2325
addJobProperty("flattenUri", "Whether or not record URIs are flattened before being used as zip entry names; defaults to false",
2426
value -> getWriteToZipConsumer().setFlattenUri(Boolean.parseBoolean(value)));
2527

26-
addJobProperty("transform", "The name of a REST transform to apply to each record before it is written to the zip file",
27-
value -> getExportListener().withTransform(new ServerTransform(value)));
28+
addTransformJobProperty((value, transform) -> getExportListener().withTransform(transform));
2829

2930
addJobProperty("uriPrefix", "Prefix to prepend to each URI it is used as an entry name; applied after a URI is optionally flattened",
3031
value -> getWriteToZipConsumer().setUriPrefix(value));

src/main/java/com/marklogic/client/ext/datamovement/listener/XmlOutputListener.java

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
import com.marklogic.client.io.DOMHandle;
66
import com.marklogic.client.io.Format;
77
import com.marklogic.client.io.StringHandle;
8-
import com.sun.org.apache.xml.internal.serialize.OutputFormat;
9-
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
108
import org.slf4j.Logger;
119
import org.slf4j.LoggerFactory;
1210
import org.w3c.dom.Document;
1311

14-
import java.io.IOException;
12+
import javax.xml.transform.OutputKeys;
13+
import javax.xml.transform.Transformer;
14+
import javax.xml.transform.TransformerFactory;
15+
import javax.xml.transform.dom.DOMSource;
16+
import javax.xml.transform.stream.StreamResult;
1517
import java.io.StringWriter;
1618

1719
/**
@@ -26,23 +28,12 @@ public class XmlOutputListener implements ExportToWriterListener.OutputListener
2628
protected Logger logger = LoggerFactory.getLogger(getClass());
2729

2830
private boolean omitXmlDeclaration = true;
31+
private TransformerFactory transformerFactory = TransformerFactory.newInstance();
2932

3033
@Override
3134
public String generateOutput(DocumentRecord documentRecord) {
3235
if (Format.XML.equals(documentRecord.getFormat())) {
33-
DOMHandle handle = documentRecord.getContent(new DOMHandle());
34-
Document document = handle.get();
35-
36-
OutputFormat format = new OutputFormat(handle.get());
37-
format.setOmitXMLDeclaration(omitXmlDeclaration);
38-
39-
StringWriter writer = new StringWriter();
40-
try {
41-
new XMLSerializer(writer, format).serialize(document);
42-
return writer.toString();
43-
} catch (IOException e) {
44-
throw new RuntimeException("Unable to serialize XML document to string: " + e.getMessage(), e);
45-
}
36+
return convertDocumentToString(documentRecord.getContent(new DOMHandle()).get());
4637
} else if (logger.isDebugEnabled()) {
4738
logger.debug(String.format("Document '%s' has a format of '%s', so will not attempt to remove the XML declaration from it",
4839
documentRecord.getUri(), documentRecord.getFormat().name()));
@@ -51,6 +42,20 @@ public String generateOutput(DocumentRecord documentRecord) {
5142
return documentRecord.getContent(new StringHandle()).get();
5243
}
5344

45+
protected String convertDocumentToString(Document document) {
46+
try {
47+
Transformer transformer = transformerFactory.newTransformer();
48+
if (omitXmlDeclaration) {
49+
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
50+
}
51+
StringWriter writer = new StringWriter();
52+
transformer.transform(new DOMSource(document), new StreamResult(writer));
53+
return writer.toString();
54+
} catch (Exception e) {
55+
throw new RuntimeException("Unable to serialize XML document to string: " + e.getMessage(), e);
56+
}
57+
}
58+
5459
public void setOmitXmlDeclaration(boolean omitXmlDeclaration) {
5560
this.omitXmlDeclaration = omitXmlDeclaration;
5661
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.marklogic.client.ext.datamovement.util;
2+
3+
import com.marklogic.client.document.ServerTransform;
4+
5+
public abstract class TransformPropertyValueParser {
6+
7+
/**
8+
* Utility method for parsing a value which may have transform parameters appended - e.g.
9+
* myTransform,param1,value1,param2,value2.
10+
*
11+
* @param value
12+
* @return
13+
*/
14+
public static ServerTransform parsePropertyValue(String value) {
15+
String[] tokens = value.split(",");
16+
ServerTransform transform = new com.marklogic.client.document.ServerTransform(tokens[0]);
17+
for (int i = 1; i < tokens.length; i += 2) {
18+
transform.addParameter(tokens[i], tokens[i + 1]);
19+
}
20+
return transform;
21+
}
22+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.marklogic.client.ext.datamovement;
2+
3+
import org.junit.Assert;
4+
import org.junit.Test;
5+
6+
public class UrisQueryQueryBatcherBuilderTest extends Assert {
7+
8+
private UrisQueryQueryBatcherBuilder builder = new UrisQueryQueryBatcherBuilder();
9+
10+
@Test
11+
public void javascriptStartingWithFnSubsequence() {
12+
String query = "fn.subsequence(cts.uris(null, null, cts.collectionQuery('Testing')), 1, 3)";
13+
String newQuery = builder.wrapJavascriptIfAppropriate(query);
14+
assertEquals("The query should not be wrapped with cts.uris since it doesn't start with cts.", query, newQuery);
15+
}
16+
17+
@Test
18+
public void javascriptStartingWithCtsUris() {
19+
String query = "cts.uris(null, null, cts.collectionQuery('Testing'))";
20+
String newQuery = builder.wrapJavascriptIfAppropriate(query);
21+
assertEquals("The query should not be wrapped with cts.uris since it already starts with cts.uris", query, newQuery);
22+
}
23+
24+
@Test
25+
public void javascriptStartingWithCtsCollectionQuery() {
26+
String query = "cts.collectionQuery('Testing')";
27+
String newQuery = builder.wrapJavascriptIfAppropriate(query);
28+
assertEquals("The query should not be wrapped with cts.uris since it doesn't start with cts.uris",
29+
"cts.uris(\"\", null, cts.collectionQuery('Testing'))", newQuery);
30+
}
31+
}

0 commit comments

Comments
 (0)