Skip to content
This repository was archived by the owner on Sep 16, 2024. It is now read-only.

Commit d4bcbb2

Browse files
authored
Merge pull request #195 from marklogic/release/4.6.0
Merging release/4.6.0 into master
2 parents 10ca4fd + 6622cfb commit d4bcbb2

File tree

82 files changed

+1125
-320
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+1125
-320
lines changed

CODEOWNERS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Lines starting with '#' are comments.
2+
# Each line is a file pattern followed by one or more owners.
3+
4+
# These owners will be the default owners for everything in the repo.
5+
* @anu3990 @billfarber @rjrudin

CONTRIBUTING.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
To run the tests for ml-javaclient-util, clone this repository and deploy this project's test application first via
2+
the following steps:
3+
4+
1. Create a file named `gradle-local.properties`.
5+
2. Add `mlPassword=` followed by the password for your MarkLogic admin user.
6+
3. Verify that port 8070 is available on your computer - i.e. no other process is listening on it.
7+
4. Run `./gradlew -i mlDeploy`.
8+
9+
You can then run `./gradlew -i test` to run all of the tests.

Jenkinsfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ pipeline{
2121
export GRADLE_USER_HOME=$WORKSPACE/$GRADLE_DIR
2222
export PATH=$GRADLE_USER_HOME:$JAVA_HOME/bin:$PATH
2323
cd ml-javaclient-util
24+
echo "mlPassword=admin" > gradle-local.properties
25+
./gradlew -i mlDeploy
2426
./gradlew test || true
2527
'''
2628
junit '**/build/**/*.xml'

build.gradle

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,43 @@ plugins {
77
// This plugin requires Java 11; keeping it commented out so that this project can be built and tested via
88
// Java 8, 11 or 17; to use this plugin, uncomment this line and use java 11 or higher
99
// id "com.github.jk1.dependency-license-report" version "2.1"
10+
11+
// For deploying the test app.
12+
id 'net.saliman.properties' version '1.5.2'
13+
id "com.marklogic.ml-gradle" version "4.5.2"
1014
}
1115

1216
group = "com.marklogic"
13-
version = "4.5.1"
17+
version = "4.6.0"
1418

1519
java {
1620
sourceCompatibility = 1.8
1721
targetCompatibility = 1.8
1822
}
1923

2024
repositories {
25+
mavenLocal()
26+
maven {
27+
url "https://nexus.marklogic.com/repository/maven-snapshots/"
28+
}
2129
mavenCentral()
2230
}
2331

2432
dependencies {
25-
api 'com.marklogic:marklogic-client-api:6.2.0'
26-
api 'com.marklogic:marklogic-xcc:11.0.2'
27-
api 'org.springframework:spring-context:5.3.27'
33+
api 'com.marklogic:marklogic-client-api:6.3.0'
34+
api 'com.marklogic:marklogic-xcc:11.0.3'
35+
api 'org.springframework:spring-context:5.3.29'
2836

2937
implementation 'org.jdom:jdom2:2.0.6.1'
3038

31-
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.1'
39+
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'
3240

3341
// This is currently an implementation dependency, though perhaps should be an api dependency due to its usage in
3442
// LoggingObject; not clear yet on whether the protected Logger in that class should make this an api dependency or not
3543
implementation 'org.slf4j:slf4j-api:1.7.36'
3644

37-
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.3'
38-
testImplementation 'org.springframework:spring-test:5.3.27'
45+
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
46+
testImplementation 'org.springframework:spring-test:5.3.29'
3947
testImplementation 'org.mockito:mockito-core:4.11.0'
4048

4149
// Used for testing loading modules from the classpath
@@ -53,7 +61,7 @@ dependencies {
5361

5462
// Including the "new" JAXB libraries to verify that their presence doesn't cause the "old" JAXB libraries to fail
5563
testImplementation "jakarta.xml.bind:jakarta.xml.bind-api:4.0.0"
56-
testImplementation "com.sun.xml.bind:jaxb-impl:4.0.1"
64+
testImplementation "com.sun.xml.bind:jaxb-impl:4.0.3"
5765
}
5866

5967
test {

gradle.properties

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,11 @@ mavenCentralUrl=https://oss.sonatype.org/service/local/staging/deploy/maven2/
99
#signing.keyId=YourKeyId
1010
#signing.password=YourPublicKeyPassword
1111
#signing.secretKeyRingFile=PathToYourKeyRingFile
12+
13+
# For the test app
14+
mlHost=localhost
15+
mlAppName=ml-javaclient-util-test
16+
mlRestPort=8028
17+
mlUsername=admin
18+
mlPassword=change in gradle-local.properties
19+
mlConfigPaths=src/test/ml-config

pom.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ It is not intended to be used to build this project.
1212
<modelVersion>4.0.0</modelVersion>
1313
<groupId>com.marklogic</groupId>
1414
<artifactId>ml-javaclient-util</artifactId>
15-
<version>4.5.1</version>
15+
<version>4.6.0</version>
1616
<name>com.marklogic:ml-javaclient-util</name>
1717
<description>Library that adds functionality on top of the MarkLogic Java Client</description>
1818
<url>https://github.com/marklogic/ml-javaclient-util</url>
@@ -40,19 +40,19 @@ It is not intended to be used to build this project.
4040
<dependency>
4141
<groupId>com.marklogic</groupId>
4242
<artifactId>marklogic-client-api</artifactId>
43-
<version>6.2.0</version>
43+
<version>6.3.0</version>
4444
<scope>compile</scope>
4545
</dependency>
4646
<dependency>
4747
<groupId>com.marklogic</groupId>
4848
<artifactId>marklogic-xcc</artifactId>
49-
<version>11.0.2</version>
49+
<version>11.0.3</version>
5050
<scope>compile</scope>
5151
</dependency>
5252
<dependency>
5353
<groupId>org.springframework</groupId>
5454
<artifactId>spring-context</artifactId>
55-
<version>5.3.27</version>
55+
<version>5.3.29</version>
5656
<scope>compile</scope>
5757
</dependency>
5858
<dependency>
@@ -64,7 +64,7 @@ It is not intended to be used to build this project.
6464
<dependency>
6565
<groupId>com.fasterxml.jackson.core</groupId>
6666
<artifactId>jackson-databind</artifactId>
67-
<version>2.14.1</version>
67+
<version>2.15.2</version>
6868
<scope>runtime</scope>
6969
</dependency>
7070
<dependency>
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright (c) 2023 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.ext.file;
17+
18+
import java.io.File;
19+
import java.io.IOException;
20+
import java.nio.file.FileVisitResult;
21+
import java.nio.file.FileVisitor;
22+
import java.nio.file.Path;
23+
import java.nio.file.attribute.BasicFileAttributes;
24+
import java.util.Properties;
25+
import java.util.Stack;
26+
27+
/**
28+
* Adds a stack to store Properties objects while traversing a directory tree. Implements {@code FileVisitor} so that
29+
* it can be informed when {@code DefaultDocumentFileReader} is entering and exiting a directory.
30+
*
31+
* To preserve backwards compatibility in subclasses, cascading is disabled by default. This will likely change in 5.0
32+
* to be enabled by default.
33+
*
34+
* @since 4.6.0
35+
*/
36+
abstract class CascadingPropertiesDrivenDocumentFileProcessor extends PropertiesDrivenDocumentFileProcessor implements FileVisitor<Path> {
37+
38+
final private Stack<Properties> propertiesStack = new Stack<>();
39+
private boolean cascadingEnabled = false;
40+
41+
protected CascadingPropertiesDrivenDocumentFileProcessor(String propertiesFilename) {
42+
super(propertiesFilename);
43+
}
44+
45+
@Override
46+
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
47+
// If cascading is disabled, we still use a stack to keep track of whether a directory has properties or not.
48+
// We just never grab properties from the stack in case a directory doesn't have properties.
49+
if (logger.isDebugEnabled()) {
50+
logger.debug(format("Visiting directory: %s", dir.toFile().getAbsolutePath()));
51+
}
52+
File propertiesFile = new File(dir.toFile(), this.getPropertiesFilename());
53+
if (propertiesFile.exists()) {
54+
if (logger.isDebugEnabled()) {
55+
logger.debug(format("Loading properties from file: %s", propertiesFile.getAbsolutePath()));
56+
}
57+
this.loadProperties(propertiesFile);
58+
} else {
59+
if (cascadingEnabled && !propertiesStack.isEmpty()) {
60+
if (logger.isDebugEnabled()) {
61+
logger.debug("No properties file, and cascading is enabled, so using properties from top of stack.");
62+
}
63+
this.setProperties(propertiesStack.peek());
64+
} else {
65+
if (logger.isDebugEnabled()) {
66+
logger.debug("No properties file, or cascading is disabled, so using empty properties.");
67+
}
68+
this.setProperties(new Properties());
69+
}
70+
}
71+
propertiesStack.push(this.getProperties());
72+
return FileVisitResult.CONTINUE;
73+
}
74+
75+
@Override
76+
public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
77+
propertiesStack.pop();
78+
if (!propertiesStack.isEmpty()) {
79+
this.setProperties(propertiesStack.peek());
80+
}
81+
return FileVisitResult.CONTINUE;
82+
}
83+
84+
@Override
85+
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
86+
return FileVisitResult.CONTINUE;
87+
}
88+
89+
@Override
90+
public FileVisitResult visitFileFailed(Path file, IOException exc) {
91+
return FileVisitResult.CONTINUE;
92+
}
93+
94+
public boolean isCascadingEnabled() {
95+
return cascadingEnabled;
96+
}
97+
98+
public void setCascadingEnabled(boolean cascadingEnabled) {
99+
this.cascadingEnabled = cascadingEnabled;
100+
}
101+
}

src/main/java/com/marklogic/client/ext/file/CollectionsFileDocumentFileProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* key is the name of a file in the directory, and the value is a comma-delimited list of collections to load the file
2323
* into (which means you can't use a comma in any collection name).
2424
*/
25-
public class CollectionsFileDocumentFileProcessor extends PropertiesDrivenDocumentFileProcessor {
25+
public class CollectionsFileDocumentFileProcessor extends CascadingPropertiesDrivenDocumentFileProcessor {
2626

2727
private String delimiter = ",";
2828

src/main/java/com/marklogic/client/ext/file/DefaultDocumentFileReader.java

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
import java.io.IOException;
2121
import java.net.URI;
2222
import java.net.URISyntaxException;
23-
import java.nio.file.*;
23+
import java.nio.file.FileVisitResult;
24+
import java.nio.file.FileVisitor;
25+
import java.nio.file.Files;
26+
import java.nio.file.Path;
27+
import java.nio.file.Paths;
2428
import java.nio.file.attribute.BasicFileAttributes;
2529
import java.util.ArrayList;
2630
import java.util.List;
@@ -35,7 +39,8 @@ public class DefaultDocumentFileReader extends AbstractDocumentFileReader implem
3539
private List<DocumentFile> documentFiles;
3640
private String uriPrefix = "/";
3741

38-
// Each of these are eagerly instantiated, and we retain a reference in case a client wants to modify them
42+
// As of 4.6.0, these no longer need to be class fields but are being kept for backwards compatibility.
43+
// They should be removed in 5.0.0.
3944
private CollectionsFileDocumentFileProcessor collectionsFileDocumentFileProcessor;
4045
private PermissionsFileDocumentFileProcessor permissionsFileDocumentFileProcessor;
4146

@@ -105,6 +110,11 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th
105110
if (logger.isDebugEnabled()) {
106111
logger.debug("Visiting directory: " + dir);
107112
}
113+
for (DocumentFileProcessor processor : getDocumentFileProcessors()) {
114+
if (processor instanceof FileVisitor) {
115+
((FileVisitor) processor).preVisitDirectory(dir, attrs);
116+
}
117+
}
108118
return FileVisitResult.CONTINUE;
109119
} else {
110120
if (logger.isDebugEnabled()) {
@@ -115,7 +125,7 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th
115125
}
116126

117127
@Override
118-
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
128+
public FileVisitResult visitFileFailed(Path file, IOException exc) {
119129
if (exc != null) {
120130
logger.warn("Failed visiting file: " + exc.getMessage(), exc);
121131
}
@@ -127,11 +137,16 @@ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOEx
127137
if (exc != null) {
128138
logger.warn("Error in postVisitDirectory: " + exc.getMessage(), exc);
129139
}
140+
for (DocumentFileProcessor processor : getDocumentFileProcessors()) {
141+
if (processor instanceof FileVisitor) {
142+
((FileVisitor) processor).postVisitDirectory(dir, exc);
143+
}
144+
}
130145
return FileVisitResult.CONTINUE;
131146
}
132147

133148
@Override
134-
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
149+
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
135150
if (acceptPath(path, attrs)) {
136151
DocumentFile documentFile = buildDocumentFile(path, currentRootPath);
137152
documentFile = processDocumentFile(documentFile);
@@ -202,10 +217,21 @@ public void setUriPrefix(String uriPrefix) {
202217
this.uriPrefix = uriPrefix;
203218
}
204219

220+
/**
221+
*
222+
* @return
223+
* @deprecated since 4.6.0, will be removed in 5.0.0
224+
*/
225+
@Deprecated
205226
public CollectionsFileDocumentFileProcessor getCollectionsFileDocumentFileProcessor() {
206227
return collectionsFileDocumentFileProcessor;
207228
}
208229

230+
/**
231+
*
232+
* @return
233+
* @deprecated since 4.6.0, will be removed in 5.0.0
234+
*/
209235
public PermissionsFileDocumentFileProcessor getPermissionsFileDocumentFileProcessor() {
210236
return permissionsFileDocumentFileProcessor;
211237
}

src/main/java/com/marklogic/client/ext/file/FormatDocumentFileProcessor.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,17 @@
1515
*/
1616
package com.marklogic.client.ext.file;
1717

18+
import com.marklogic.client.ext.helper.LoggingObject;
1819
import com.marklogic.client.io.Format;
1920

21+
import java.util.Arrays;
22+
2023
/**
2124
* Delegates to DefaultDocumentFormatGetter by default for determining what Format to use for the File in a given
2225
* DocumentFile.
2326
*/
24-
public class FormatDocumentFileProcessor implements DocumentFileProcessor {
27+
public class FormatDocumentFileProcessor extends LoggingObject
28+
implements DocumentFileProcessor, SupportsAdditionalBinaryExtensions {
2529

2630
private FormatGetter formatGetter;
2731

@@ -35,14 +39,26 @@ public FormatDocumentFileProcessor(FormatGetter formatGetter) {
3539

3640
@Override
3741
public DocumentFile processDocumentFile(DocumentFile documentFile) {
38-
3942
Format format = formatGetter.getFormat(documentFile.getResource());
4043
if (format != null) {
4144
documentFile.setFormat(format);
4245
}
4346
return documentFile;
4447
}
4548

49+
@Override
50+
public void setAdditionalBinaryExtensions(String[] extensions) {
51+
if (formatGetter instanceof DefaultDocumentFormatGetter) {
52+
DefaultDocumentFormatGetter ddfg = (DefaultDocumentFormatGetter) formatGetter;
53+
for (String ext : extensions) {
54+
ddfg.getBinaryExtensions().add(ext);
55+
}
56+
} else {
57+
logger.warn("FormatGetter is not an instanceof DefaultDocumentFormatGetter, " +
58+
"so unable to add additionalBinaryExtensions: " + Arrays.asList(extensions));
59+
}
60+
}
61+
4662
public FormatGetter getFormatGetter() {
4763
return formatGetter;
4864
}

0 commit comments

Comments
 (0)