Skip to content

Commit f7e2d8c

Browse files
author
ehennum
committed
clean up on handles and service customization #1111
1 parent 0200bc0 commit f7e2d8c

File tree

16 files changed

+470
-171
lines changed

16 files changed

+470
-171
lines changed

marklogic-client-api/src/main/java/com/marklogic/client/impl/BaseProxy.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,22 @@ static protected ObjectMapper getMapper() {
7676

7777
public BaseProxy() {
7878
}
79+
public BaseProxy(DatabaseClient db, String endpointDir, JSONWriteHandle serviceDeclaration) {
80+
this();
81+
if (serviceDeclaration == null) {
82+
init(db, endpointDir);
83+
} else {
84+
JsonNode serviceDecl = NodeConverter.handleToJsonNode(serviceDeclaration);
85+
86+
JsonNode endpointDirProp = serviceDecl.get("endpointDirectory");
87+
if (endpointDirProp == null) {
88+
throw new IllegalArgumentException("Service declaration without endpointDirectory property");
89+
}
90+
91+
init(db, endpointDirProp.asText());
92+
}
93+
}
94+
// backward-compatible constructor for 4.x legacy
7995
public BaseProxy(DatabaseClient db, String endpointDir) {
8096
this();
8197
if (db == null) {

ml-development-tools/src/main/kotlin/com/marklogic/client/tools/proxy/Generator.kt

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,17 @@ class Generator {
2626

2727
fun getJavaConverterName(): Map<String,String> {
2828
return mapOf(
29-
"com.marklogic.client.io.marker.BinaryReadHandle" to "BinaryHandle",
30-
"com.marklogic.client.io.marker.BinaryWriteHandle" to "BinaryHandle",
3129
"java.io.InputStream" to "InputStream",
3230
"java.io.Reader" to "Reader",
3331
"com.fasterxml.jackson.databind.JsonNode" to "JacksonJsonNode",
3432
"com.fasterxml.jackson.core.JsonParser" to "JacksonJsonParser",
3533
"com.fasterxml.jackson.databind.node.ArrayNode" to "JacksonArrayNode",
3634
"com.fasterxml.jackson.databind.node.ObjectNode" to "JacksonObjectNode",
37-
"com.marklogic.client.io.marker.JSONReadHandle" to "JSONHandle",
38-
"com.marklogic.client.io.marker.JSONWriteHandle" to "JSONHandle",
39-
"com.marklogic.client.io.marker.TextReadHandle" to "TextHandle",
40-
"com.marklogic.client.io.marker.TextWriteHandle" to "TextHandle",
4135
"org.w3c.dom.Document" to "XMLDOMDocument",
4236
"org.xml.sax.InputSource" to "XMLSaxInputSource",
4337
"javax.xml.transform.Source" to "XMLTransformSource",
4438
"javax.xml.stream.XMLEventReader" to "XMLEventReader",
4539
"javax.xml.stream.XMLStreamReader" to "XMLStreamReader",
46-
"com.marklogic.client.io.marker.XMLReadHandle" to "XMLHandle",
47-
"com.marklogic.client.io.marker.XMLWriteHandle" to "XMLHandle",
4840

4941
"java.math.BigDecimal" to "BigDecimal",
5042
"java.lang.Boolean" to "Boolean",
@@ -156,35 +148,25 @@ class Generator {
156148
"java.io.Reader",
157149
"java.lang.String",
158150
"com.fasterxml.jackson.databind.node.ArrayNode",
159-
"com.fasterxml.jackson.core.JsonParser",
160-
"com.marklogic.client.io.marker.JSONReadHandle",
161-
"com.marklogic.client.io.marker.JSONWriteHandle"),
151+
"com.fasterxml.jackson.core.JsonParser"),
162152
"binaryDocument" to setOf(
163-
"java.io.InputStream",
164-
"com.marklogic.client.io.marker.BinaryReadHandle",
165-
"com.marklogic.client.io.marker.BinaryWriteHandle"),
153+
"java.io.InputStream"),
166154
"jsonDocument" to setOf(
167155
"java.io.InputStream",
168156
"java.io.Reader",
169157
"java.lang.String",
170158
"com.fasterxml.jackson.databind.JsonNode",
171-
"com.fasterxml.jackson.core.JsonParser",
172-
"com.marklogic.client.io.marker.JSONReadHandle",
173-
"com.marklogic.client.io.marker.JSONWriteHandle"),
159+
"com.fasterxml.jackson.core.JsonParser"),
174160
"object" to setOf(
175161
"java.io.InputStream",
176162
"java.io.Reader",
177163
"java.lang.String",
178164
"com.fasterxml.jackson.databind.node.ObjectNode",
179-
"com.fasterxml.jackson.core.JsonParser",
180-
"com.marklogic.client.io.marker.JSONReadHandle",
181-
"com.marklogic.client.io.marker.JSONWriteHandle"),
165+
"com.fasterxml.jackson.core.JsonParser"),
182166
"textDocument" to setOf(
183167
"java.io.InputStream",
184168
"java.io.Reader",
185-
"java.lang.String",
186-
"com.marklogic.client.io.marker.TextReadHandle",
187-
"com.marklogic.client.io.marker.TextWriteHandle"),
169+
"java.lang.String"),
188170
"xmlDocument" to setOf(
189171
"java.io.InputStream",
190172
"java.io.Reader",
@@ -193,9 +175,7 @@ class Generator {
193175
"org.xml.sax.InputSource",
194176
"javax.xml.transform.Source",
195177
"javax.xml.stream.XMLEventReader",
196-
"javax.xml.stream.XMLStreamReader",
197-
"com.marklogic.client.io.marker.XMLReadHandle",
198-
"com.marklogic.client.io.marker.XMLWriteHandle")
178+
"javax.xml.stream.XMLStreamReader")
199179
)
200180
}
201181
fun getAllDataTypes(): Map<String,String> {
@@ -503,9 +483,7 @@ ${funcDecls}
503483
when (paramKind) {
504484
"document" -> {
505485
funcDepend.add("com.marklogic.client.io.Format")
506-
if (mappedType.contains(".") == true) {
507-
funcDepend.add("com.marklogic.client.io.marker.AbstractWriteHandle")
508-
} else {
486+
if (mappedType.contains(".") != true) {
509487
funcDepend.add("java.io.$mappedType")
510488
}
511489
}
@@ -521,9 +499,7 @@ ${funcDecls}
521499

522500
if (returnKind == "document") {
523501
funcDepend.add("com.marklogic.client.io.Format")
524-
if (returnMapped?.contains(".") == true) {
525-
funcDepend.add("com.marklogic.client.io.marker.AbstractWriteHandle")
526-
} else {
502+
if (returnMapped?.contains(".") != true) {
527503
funcDepend.add("java.io.$returnMapped")
528504
}
529505
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.marklogic.client.test.dbfunction.positive;
2+
3+
// IMPORTANT: Do not edit. This file is generated.
4+
5+
import com.marklogic.client.io.Format;
6+
7+
8+
import com.marklogic.client.DatabaseClient;
9+
import com.marklogic.client.io.marker.JSONWriteHandle;
10+
11+
import com.marklogic.client.impl.BaseProxy;
12+
13+
/**
14+
* Provides a set of operations on the database server
15+
*/
16+
public interface DecoratorCustomBundle {
17+
/**
18+
* Creates a DecoratorCustomBundle object for executing operations on the database server.
19+
*
20+
* The DatabaseClientFactory class can create the DatabaseClient parameter. A single
21+
* client object can be used for any number of requests and in multiple threads.
22+
*
23+
* @param db provides a client for communicating with the database server
24+
* @return an object for executing database operations
25+
*/
26+
static DecoratorCustomBundle on(DatabaseClient db) {
27+
return on(db, null);
28+
}
29+
/**
30+
* Creates a DecoratorCustomBundle object for executing operations on the database server.
31+
*
32+
* The DatabaseClientFactory class can create the DatabaseClient parameter. A single
33+
* client object can be used for any number of requests and in multiple threads.
34+
*
35+
* The service declaration uses a custom implementation of the same service instead
36+
* of the default implementation of the service by specifying an endpoint directory
37+
* in the modules database with the implementation. A service.json file with the
38+
* declaration can be read with FileHandle or a string serialization of the JSON
39+
* declaration with StringHandle.
40+
*
41+
* @param db provides a client for communicating with the database server
42+
* @param serviceDeclaration substitutes a custom implementation of the service
43+
* @return an object for executing database operations
44+
*/
45+
static DecoratorCustomBundle on(DatabaseClient db, JSONWriteHandle serviceDeclaration) {
46+
final class DecoratorCustomBundleImpl implements DecoratorCustomBundle {
47+
private BaseProxy baseProxy;
48+
49+
private DecoratorCustomBundleImpl(DatabaseClient dbClient, JSONWriteHandle servDecl) {
50+
baseProxy = new BaseProxy(dbClient, "/dbf/test/decoratorCustom/", servDecl);
51+
}
52+
53+
@Override
54+
public com.fasterxml.jackson.databind.JsonNode docify(String value) {
55+
return BaseProxy.JsonDocumentType.toJsonNode(
56+
baseProxy
57+
.request("docify.sjs", BaseProxy.ParameterValuesKind.SINGLE_ATOMIC)
58+
.withSession()
59+
.withParams(
60+
BaseProxy.atomicParam("value", true, BaseProxy.StringType.fromString(value)))
61+
.withMethod("POST")
62+
.responseSingle(true, Format.JSON)
63+
);
64+
}
65+
66+
}
67+
68+
return new DecoratorCustomBundleImpl(db, serviceDeclaration);
69+
}
70+
71+
/**
72+
* Invokes the docify operation on the database server
73+
*
74+
* @param value provides input
75+
* @return as output
76+
*/
77+
com.fasterxml.jackson.databind.JsonNode docify(String value);
78+
79+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright 2019 MarkLogic Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.marklogic.client.test.dbfunction.positive;
17+
18+
import com.fasterxml.jackson.databind.JsonNode;
19+
import com.marklogic.client.io.StringHandle;
20+
import com.marklogic.client.test.dbfunction.DBFunctionTestUtil;
21+
import org.junit.Test;
22+
23+
import static org.junit.Assert.*;
24+
25+
public class DecoratorCustomBundleTest {
26+
// execute the same implementation via direct interface and via a customized implementation of an interface
27+
DecoratorCustomBundle testDirectInterface = DecoratorCustomBundle.on(DBFunctionTestUtil.db);
28+
DecoratorDefaultBundle testCustomOverride = DecoratorDefaultBundle.on(DBFunctionTestUtil.db,
29+
new StringHandle("{\"endpointDirectory\":\"/dbf/test/decoratorCustom/\"}")
30+
);
31+
32+
@Test
33+
public void testDocify() {
34+
try {
35+
JsonNode[] dbNodes = new JsonNode[]{
36+
testDirectInterface.docify("value0"),
37+
testCustomOverride.docify("value1")
38+
};
39+
40+
for (int i=0; i < dbNodes.length; i++) {
41+
String interfaceType = (i == 0) ? "default" : "custom";
42+
43+
JsonNode dbNode = dbNodes[i];
44+
assertNotNull("failed to read "+interfaceType+" docified value from database", dbNode );
45+
46+
// System.out.println(dbNode.toString());
47+
48+
for (String key: new String[]{"value", "type"}) {
49+
String value = (key == "value") ? "value"+i : "string";
50+
JsonNode dbValue = dbNode.get(key);
51+
assertNotNull("no "+key+" key in "+interfaceType+" docified response", dbValue);
52+
assertTrue(interfaceType+" docified "+key+" is not textual", dbValue.isTextual());
53+
assertEquals("unexpected "+interfaceType+" docified "+key, value, dbValue.asText());
54+
}
55+
}
56+
} catch(Exception e) {
57+
fail(e.getClass().getSimpleName()+": "+e.getMessage());
58+
}
59+
}
60+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.marklogic.client.test.dbfunction.positive;
2+
3+
// IMPORTANT: Do not edit. This file is generated.
4+
5+
import com.marklogic.client.io.Format;
6+
7+
8+
import com.marklogic.client.DatabaseClient;
9+
import com.marklogic.client.io.marker.JSONWriteHandle;
10+
11+
import com.marklogic.client.impl.BaseProxy;
12+
13+
/**
14+
* Provides a set of operations on the database server
15+
*/
16+
public interface DecoratorDefaultBundle {
17+
/**
18+
* Creates a DecoratorDefaultBundle object for executing operations on the database server.
19+
*
20+
* The DatabaseClientFactory class can create the DatabaseClient parameter. A single
21+
* client object can be used for any number of requests and in multiple threads.
22+
*
23+
* @param db provides a client for communicating with the database server
24+
* @return an object for executing database operations
25+
*/
26+
static DecoratorDefaultBundle on(DatabaseClient db) {
27+
return on(db, null);
28+
}
29+
/**
30+
* Creates a DecoratorDefaultBundle object for executing operations on the database server.
31+
*
32+
* The DatabaseClientFactory class can create the DatabaseClient parameter. A single
33+
* client object can be used for any number of requests and in multiple threads.
34+
*
35+
* The service declaration uses a custom implementation of the same service instead
36+
* of the default implementation of the service by specifying an endpoint directory
37+
* in the modules database with the implementation. A service.json file with the
38+
* declaration can be read with FileHandle or a string serialization of the JSON
39+
* declaration with StringHandle.
40+
*
41+
* @param db provides a client for communicating with the database server
42+
* @param serviceDeclaration substitutes a custom implementation of the service
43+
* @return an object for executing database operations
44+
*/
45+
static DecoratorDefaultBundle on(DatabaseClient db, JSONWriteHandle serviceDeclaration) {
46+
final class DecoratorDefaultBundleImpl implements DecoratorDefaultBundle {
47+
private BaseProxy baseProxy;
48+
49+
private DecoratorDefaultBundleImpl(DatabaseClient dbClient, JSONWriteHandle servDecl) {
50+
baseProxy = new BaseProxy(dbClient, "/dbf/test/decoratorDefault/", servDecl);
51+
}
52+
53+
@Override
54+
public com.fasterxml.jackson.databind.JsonNode docify(String value) {
55+
return BaseProxy.JsonDocumentType.toJsonNode(
56+
baseProxy
57+
.request("docify.sjs", BaseProxy.ParameterValuesKind.SINGLE_ATOMIC)
58+
.withSession()
59+
.withParams(
60+
BaseProxy.atomicParam("value", true, BaseProxy.StringType.fromString(value)))
61+
.withMethod("POST")
62+
.responseSingle(true, Format.JSON)
63+
);
64+
}
65+
66+
}
67+
68+
return new DecoratorDefaultBundleImpl(db, serviceDeclaration);
69+
}
70+
71+
/**
72+
* Invokes the docify operation on the database server
73+
*
74+
* @param value provides input
75+
* @return as output
76+
*/
77+
com.fasterxml.jackson.databind.JsonNode docify(String value);
78+
79+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright 2019 MarkLogic Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.marklogic.client.test.dbfunction.positive;
17+
18+
import com.fasterxml.jackson.databind.JsonNode;
19+
import com.marklogic.client.impl.NodeConverter;
20+
import com.marklogic.client.test.dbfunction.DBFunctionTestUtil;
21+
import org.junit.Test;
22+
23+
import java.io.File;
24+
import java.io.FileReader;
25+
import java.io.Reader;
26+
27+
import static org.junit.Assert.*;
28+
29+
public class DecoratorDefaultBundleTest {
30+
DecoratorDefaultBundle testObj = DecoratorDefaultBundle.on(DBFunctionTestUtil.db);
31+
32+
@Test
33+
public void testDocify() {
34+
try {
35+
JsonNode dbNode = testObj.docify("value1");
36+
assertNotNull("failed to read docified value from database", dbNode );
37+
38+
JsonNode dbValue = dbNode.get("value");
39+
assertNotNull("no value key in docified value", dbValue);
40+
assertTrue("docified value is not textual", dbValue.isTextual());
41+
assertEquals("unexpected docified value", "value1", dbValue.asText());
42+
} catch(Exception e) {
43+
fail(e.getClass().getSimpleName()+": "+e.getMessage());
44+
}
45+
}
46+
}

0 commit comments

Comments
 (0)