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

Commit 9f1dae5

Browse files
committed
Refactoring file loading
Changes: 1. The Cascading processor now implements `FileVisitor` so that DDFR can bind to that instead of the concrete classes. 2. Added two `Supports` interfaces that are a little cheesy but allow for DDFR/GFL to not be bound directly to the collections/permissions processors (though I couldn't completely remove that binding without introducing breaking changes in the public API).
1 parent 572df79 commit 9f1dae5

7 files changed

+113
-54
lines changed

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

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,27 @@
1717

1818
import java.io.File;
1919
import java.io.IOException;
20+
import java.nio.file.FileVisitResult;
21+
import java.nio.file.FileVisitor;
2022
import java.nio.file.Path;
23+
import java.nio.file.attribute.BasicFileAttributes;
2124
import java.util.Properties;
2225
import java.util.Stack;
2326

2427
/**
25-
* Adds a stack to store Properties objects while traversing a directory tree.
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.
2630
*/
27-
abstract class CascadingPropertiesDrivenDocumentFileProcessor extends PropertiesDrivenDocumentFileProcessor {
31+
abstract class CascadingPropertiesDrivenDocumentFileProcessor extends PropertiesDrivenDocumentFileProcessor implements FileVisitor<Path> {
32+
2833
final private Stack<Properties> propertiesStack = new Stack<>();
2934

3035
protected CascadingPropertiesDrivenDocumentFileProcessor(String propertiesFilename) {
3136
super(propertiesFilename);
3237
}
3338

34-
protected void preVisitDirectory(Path dir) throws IOException {
39+
@Override
40+
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
3541
File collectionsPropertiesFile = new File(dir.toFile(), this.getPropertiesFilename());
3642
if (collectionsPropertiesFile.exists()) {
3743
this.loadProperties(collectionsPropertiesFile);
@@ -43,12 +49,25 @@ protected void preVisitDirectory(Path dir) throws IOException {
4349
}
4450
}
4551
propertiesStack.push(this.getProperties());
52+
return FileVisitResult.CONTINUE;
4653
}
4754

48-
protected void postVisitDirectory() {
55+
@Override
56+
public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
4957
propertiesStack.pop();
5058
if (!propertiesStack.isEmpty()) {
5159
this.setProperties(propertiesStack.peek());
5260
}
61+
return FileVisitResult.CONTINUE;
62+
}
63+
64+
@Override
65+
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
66+
return FileVisitResult.CONTINUE;
67+
}
68+
69+
@Override
70+
public FileVisitResult visitFileFailed(Path file, IOException exc) {
71+
return FileVisitResult.CONTINUE;
5372
}
5473
}

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

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,14 @@
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;
25-
import java.util.*;
29+
import java.util.ArrayList;
30+
import java.util.List;
2631

2732
/**
2833
* Non-threadsafe implementation that implements FileVisitor as a way of descending one or more file paths.
@@ -34,7 +39,8 @@ public class DefaultDocumentFileReader extends AbstractDocumentFileReader implem
3439
private List<DocumentFile> documentFiles;
3540
private String uriPrefix = "/";
3641

37-
// 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.
3844
private CollectionsFileDocumentFileProcessor collectionsFileDocumentFileProcessor;
3945
private PermissionsFileDocumentFileProcessor permissionsFileDocumentFileProcessor;
4046

@@ -104,10 +110,11 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th
104110
if (logger.isDebugEnabled()) {
105111
logger.debug("Visiting directory: " + dir);
106112
}
107-
108-
collectionsFileDocumentFileProcessor.preVisitDirectory(dir);
109-
permissionsFileDocumentFileProcessor.preVisitDirectory(dir);
110-
113+
for (DocumentFileProcessor processor : getDocumentFileProcessors()) {
114+
if (processor instanceof FileVisitor) {
115+
((FileVisitor) processor).preVisitDirectory(dir, attrs);
116+
}
117+
}
111118
return FileVisitResult.CONTINUE;
112119
} else {
113120
if (logger.isDebugEnabled()) {
@@ -118,7 +125,7 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th
118125
}
119126

120127
@Override
121-
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
128+
public FileVisitResult visitFileFailed(Path file, IOException exc) {
122129
if (exc != null) {
123130
logger.warn("Failed visiting file: " + exc.getMessage(), exc);
124131
}
@@ -130,15 +137,16 @@ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOEx
130137
if (exc != null) {
131138
logger.warn("Error in postVisitDirectory: " + exc.getMessage(), exc);
132139
}
133-
134-
collectionsFileDocumentFileProcessor.postVisitDirectory();
135-
permissionsFileDocumentFileProcessor.postVisitDirectory();
136-
140+
for (DocumentFileProcessor processor : getDocumentFileProcessors()) {
141+
if (processor instanceof FileVisitor) {
142+
((FileVisitor) processor).postVisitDirectory(dir, exc);
143+
}
144+
}
137145
return FileVisitResult.CONTINUE;
138146
}
139147

140148
@Override
141-
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
149+
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
142150
if (acceptPath(path, attrs)) {
143151
DocumentFile documentFile = buildDocumentFile(path, currentRootPath);
144152
documentFile = processDocumentFile(documentFile);
@@ -209,10 +217,21 @@ public void setUriPrefix(String uriPrefix) {
209217
this.uriPrefix = uriPrefix;
210218
}
211219

220+
/**
221+
*
222+
* @return
223+
* @deprecated since 4.6.0, will be removed in 5.0.0
224+
*/
225+
@Deprecated
212226
public CollectionsFileDocumentFileProcessor getCollectionsFileDocumentFileProcessor() {
213227
return collectionsFileDocumentFileProcessor;
214228
}
215229

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

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
}

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

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424

2525
import java.io.FileFilter;
2626
import java.util.ArrayList;
27-
import java.util.Arrays;
2827
import java.util.List;
2928
import java.util.stream.Collectors;
3029

@@ -178,46 +177,27 @@ public void initializeDocumentFileReader() {
178177
* @param reader
179178
*/
180179
public void prepareAbstractDocumentFileReader(AbstractDocumentFileReader reader) {
181-
for (DocumentFileProcessor processor : buildDocumentFileProcessors()) {
182-
reader.addDocumentFileProcessor(processor);
183-
}
184-
185-
applyTokenReplacerOnKnownDocumentProcessors(reader);
180+
buildDocumentFileProcessors().forEach(processor -> reader.addDocumentFileProcessor(processor));
186181

187-
if (additionalBinaryExtensions != null) {
188-
FormatDocumentFileProcessor processor = reader.getFormatDocumentFileProcessor();
189-
FormatGetter formatGetter = processor.getFormatGetter();
190-
if (formatGetter instanceof DefaultDocumentFormatGetter) {
191-
DefaultDocumentFormatGetter ddfg = (DefaultDocumentFormatGetter) formatGetter;
192-
for (String ext : additionalBinaryExtensions) {
193-
ddfg.getBinaryExtensions().add(ext);
194-
}
195-
} else {
196-
logger.warn("FormatGetter is not an instanceof DefaultDocumentFormatGetter, " +
197-
"so unable to add additionalBinaryExtensions: " + Arrays.asList(additionalBinaryExtensions));
182+
reader.getDocumentFileProcessors().forEach(processor -> {
183+
if (tokenReplacer != null && processor instanceof SupportsTokenReplacer) {
184+
((SupportsTokenReplacer) processor).setTokenReplacer(tokenReplacer);
198185
}
199-
}
186+
if (additionalBinaryExtensions != null && processor instanceof SupportsAdditionalBinaryExtensions) {
187+
((SupportsAdditionalBinaryExtensions) processor).setAdditionalBinaryExtensions(additionalBinaryExtensions);
188+
}
189+
});
200190
}
201191

202192
/**
203-
* If this is an instance of DefaultDocumentFileReader and a TokenReplacer has been set on the instance of this
204-
* class, then pass the TokenReplacer along to the known processors in the reader so that those processors
205-
* can replace token occurrences in property values.
206-
*
207193
* @param reader
194+
* @deprecated since 4.6.0, will be removed in 5.0.0.
208195
*/
196+
@Deprecated
209197
protected void applyTokenReplacerOnKnownDocumentProcessors(AbstractDocumentFileReader reader) {
210-
if (reader instanceof DefaultDocumentFileReader && tokenReplacer != null) {
211-
DefaultDocumentFileReader defaultReader = (DefaultDocumentFileReader) reader;
212-
CollectionsFileDocumentFileProcessor cp = defaultReader.getCollectionsFileDocumentFileProcessor();
213-
if (cp != null) {
214-
cp.setTokenReplacer(tokenReplacer);
215-
}
216-
PermissionsFileDocumentFileProcessor pp = defaultReader.getPermissionsFileDocumentFileProcessor();
217-
if (pp != null) {
218-
pp.setTokenReplacer(tokenReplacer);
219-
}
220-
}
198+
// The logic previously performed here is now handled via prepareAbstractDocumentFileReader . This is being
199+
// kept here solely to avoid any compilation issues in case this class was extended and this method was
200+
// overridden.
221201
}
222202

223203
/**

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
* Base class for processors that look for a special file in each directory and intend to perform some processing based
2929
* on the contents of that file. By default, that special file is NOT loaded into MarkLogic.
3030
*/
31-
public abstract class PropertiesDrivenDocumentFileProcessor extends LoggingObject implements DocumentFileProcessor, FileFilter {
31+
public abstract class PropertiesDrivenDocumentFileProcessor extends LoggingObject
32+
implements DocumentFileProcessor, FileFilter, SupportsTokenReplacer {
3233

3334
protected final static String WILDCARD_KEY = "*";
3435

@@ -83,14 +84,15 @@ public String getPropertiesFilename() {
8384
return propertiesFilename;
8485
}
8586

87+
@Override
8688
public void setTokenReplacer(TokenReplacer tokenReplacer) {
8789
this.tokenReplacer = tokenReplacer;
8890
}
8991

9092
protected TokenReplacer getTokenReplacer() {
9193
return tokenReplacer;
9294
}
93-
95+
9496
protected void setProperties(Properties properties) {
9597
this.properties = properties;
9698
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.marklogic.client.ext.file;
2+
3+
/**
4+
* Intended to allow for {@code DefaultDocumentFileReader} to pass along a user-supplied list of additional binary
5+
* extensions without being coupled tightly to the {@code DocumentFileProcessor} that uses them.
6+
*/
7+
public interface SupportsAdditionalBinaryExtensions {
8+
9+
void setAdditionalBinaryExtensions(String[] extensions);
10+
11+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.marklogic.client.ext.file;
2+
3+
import com.marklogic.client.ext.tokenreplacer.TokenReplacer;
4+
5+
/**
6+
* Intended to be implemented by instances of {@code DocumentFileProcessor} that wish to use a
7+
* {@code TokenReplacer} on the files that they read.
8+
*/
9+
public interface SupportsTokenReplacer {
10+
11+
void setTokenReplacer(TokenReplacer tokenReplacer);
12+
}

0 commit comments

Comments
 (0)