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

Commit d63fd65

Browse files
author
Rob Rudin
committed
#49 Can now load schemas from subdirectories
1 parent b0d59cf commit d63fd65

File tree

20 files changed

+609
-98
lines changed

20 files changed

+609
-98
lines changed

CHANGELOG.mdown

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Releases past 2.7.0 now tracked in Github
88

99
## 2.6.1
1010

11-
* [#17](https://github.com/rjrudin/ml-javaclient-util/issues/17) Extension metadata can now be loaded from the classpath
11+
* [#17](https://github.com/rjrudin/ml-javaclient-util/issues/17) Extension documentMetadata can now be loaded from the classpath
1212

1313
## 2.6
1414

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.marklogic.client.file;
2+
3+
import com.marklogic.client.helper.LoggingObject;
4+
5+
import java.io.File;
6+
import java.io.FileFilter;
7+
import java.io.IOException;
8+
import java.nio.file.*;
9+
import java.nio.file.attribute.BasicFileAttributes;
10+
import java.util.ArrayList;
11+
import java.util.List;
12+
13+
public class DefaultDocumentFileFinder extends LoggingObject implements FileVisitor<Path>, DocumentFileFinder {
14+
15+
private Path currentAssetPath;
16+
private FileFilter fileFilter;
17+
private List<DocumentFile> documentFiles;
18+
19+
public List<DocumentFile> findDocumentFiles(String... paths) {
20+
documentFiles = new ArrayList<>();
21+
for (String path : paths) {
22+
if (logger.isDebugEnabled()) {
23+
logger.debug(format("Finding documents at path: %s", path));
24+
}
25+
this.currentAssetPath = Paths.get(path);
26+
try {
27+
Files.walkFileTree(this.currentAssetPath, this);
28+
} catch (IOException ie) {
29+
throw new RuntimeException(format("IO error while walking file tree at path: %s", path), ie);
30+
}
31+
}
32+
return documentFiles;
33+
}
34+
35+
@Override
36+
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
37+
boolean accept = fileFilter == null || fileFilter.accept(dir.toFile());
38+
if (accept) {
39+
if (logger.isTraceEnabled()) {
40+
logger.trace("Visiting directory: " + dir);
41+
}
42+
return FileVisitResult.CONTINUE;
43+
} else {
44+
if (logger.isTraceEnabled()) {
45+
logger.trace("Skipping directory: " + dir);
46+
}
47+
return FileVisitResult.SKIP_SUBTREE;
48+
}
49+
}
50+
51+
@Override
52+
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
53+
if (fileFilter == null || fileFilter.accept(path.toFile())) {
54+
Path relPath = currentAssetPath.relativize(path);
55+
String uri = "/" + relPath.toString().replace("\\", "/");
56+
File f = path.toFile();
57+
this.documentFiles.add(new DocumentFile(uri, f));
58+
}
59+
return FileVisitResult.CONTINUE;
60+
}
61+
62+
@Override
63+
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
64+
return FileVisitResult.CONTINUE;
65+
}
66+
67+
@Override
68+
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
69+
return FileVisitResult.CONTINUE;
70+
}
71+
72+
public void setFileFilter(FileFilter fileFilter) {
73+
this.fileFilter = fileFilter;
74+
}
75+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package com.marklogic.client.file;
2+
3+
import com.marklogic.client.batch.BatchWriter;
4+
import com.marklogic.client.helper.LoggingObject;
5+
import org.springframework.util.ClassUtils;
6+
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
10+
public class DefaultFileLoader extends LoggingObject implements FileLoader {
11+
12+
private DocumentFileFinder documentFileFinder;
13+
private BatchWriter batchWriter;
14+
private List<DocumentFileProcessor> documentFileProcessors;
15+
16+
public DefaultFileLoader(BatchWriter batchWriter) {
17+
this(batchWriter, new DefaultDocumentFileFinder());
18+
}
19+
20+
/**
21+
* @param batchWriter This is assumed to have already been initialized, as this class is not interested in managing
22+
* the lifecycle of a BatchWriter
23+
* @param documentFileFinder
24+
*/
25+
public DefaultFileLoader(BatchWriter batchWriter, DocumentFileFinder documentFileFinder) {
26+
this.batchWriter = batchWriter;
27+
this.documentFileFinder = documentFileFinder;
28+
initializeDocumentFileProcessors();
29+
}
30+
31+
protected void initializeDocumentFileProcessors() {
32+
documentFileProcessors = new ArrayList<>();
33+
documentFileProcessors.add(new FormatDocumentFileProcessor());
34+
}
35+
36+
@Override
37+
public List<DocumentFile> loadFiles(String... paths) {
38+
List<DocumentFile> documentFiles = documentFileFinder.findDocumentFiles(paths);
39+
processDocumentFiles(documentFiles);
40+
batchWriter.write(documentFiles);
41+
return documentFiles;
42+
}
43+
44+
protected List<DocumentFile> processDocumentFiles(List<DocumentFile> documentFiles) {
45+
for (DocumentFile file : documentFiles) {
46+
for (DocumentFileProcessor processor : documentFileProcessors) {
47+
if (processor.supportsDocumentFile(file)) {
48+
processor.processDocumentFile(file);
49+
}
50+
}
51+
}
52+
return documentFiles;
53+
}
54+
public DocumentFileProcessor getDocumentFileProcessor(String classShortName) {
55+
for (DocumentFileProcessor processor : documentFileProcessors) {
56+
if (ClassUtils.getShortName(processor.getClass()).equals(classShortName)) {
57+
return processor;
58+
}
59+
}
60+
return null;
61+
}
62+
63+
public void addDocumentFileProcessor(DocumentFileProcessor processor) {
64+
if (documentFileProcessors == null) {
65+
documentFileProcessors = new ArrayList<>();
66+
}
67+
documentFileProcessors.add(processor);
68+
}
69+
70+
public List<DocumentFileProcessor> getDocumentFileProcessors() {
71+
return documentFileProcessors;
72+
}
73+
74+
public void setDocumentFileProcessors(List<DocumentFileProcessor> documentFileProcessors) {
75+
this.documentFileProcessors = documentFileProcessors;
76+
}
77+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.marklogic.client.file;
2+
3+
import com.marklogic.client.document.DocumentWriteOperation;
4+
import com.marklogic.client.io.DocumentMetadataHandle;
5+
import com.marklogic.client.io.FileHandle;
6+
import com.marklogic.client.io.Format;
7+
import com.marklogic.client.io.marker.AbstractWriteHandle;
8+
import com.marklogic.client.io.marker.DocumentMetadataWriteHandle;
9+
10+
import java.io.File;
11+
12+
/**
13+
* Encapsulates a file that should be written to MarkLogic as a single document. Implements DocumentWriteOperation so
14+
* that it can be easily written via the Java Client API.
15+
*/
16+
public class DocumentFile implements DocumentWriteOperation {
17+
18+
private String uri;
19+
private File file;
20+
private Format format;
21+
private DocumentMetadataHandle documentMetadata;
22+
23+
public DocumentFile(String uri, File file) {
24+
this.uri = uri;
25+
this.file = file;
26+
this.documentMetadata = new DocumentMetadataHandle();
27+
}
28+
29+
public String getUri() {
30+
return uri;
31+
}
32+
33+
public File getFile() {
34+
return file;
35+
}
36+
37+
public String getFileExtension() {
38+
String name = file.getName();
39+
int pos = name.lastIndexOf('.');
40+
return pos < 0 ? name : name.substring(pos + 1);
41+
}
42+
43+
@Override
44+
public OperationType getOperationType() {
45+
return OperationType.DOCUMENT_WRITE;
46+
}
47+
48+
@Override
49+
public DocumentMetadataWriteHandle getMetadata() {
50+
return documentMetadata;
51+
}
52+
53+
@Override
54+
public AbstractWriteHandle getContent() {
55+
FileHandle h = new FileHandle(file);
56+
return format != null ? h.withFormat(format) : h;
57+
}
58+
59+
public void setFormat(Format format) {
60+
this.format = format;
61+
}
62+
63+
public DocumentMetadataHandle getDocumentMetadata() {
64+
return documentMetadata;
65+
}
66+
67+
public void setDocumentMetadata(DocumentMetadataHandle documentMetadata) {
68+
this.documentMetadata = documentMetadata;
69+
}
70+
71+
public void setUri(String uri) {
72+
this.uri = uri;
73+
}
74+
75+
public void setFile(File file) {
76+
this.file = file;
77+
}
78+
79+
public Format getFormat() {
80+
return format;
81+
}
82+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.marklogic.client.file;
2+
3+
import java.util.List;
4+
5+
public interface DocumentFileFinder {
6+
7+
List<DocumentFile> findDocumentFiles(String... paths);
8+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.marklogic.client.file;
2+
3+
/**
4+
* Callback-style interface for processing - i.e. do whatever you want with - a DocumentFile instance before it's
5+
* written to MarkLogic.
6+
*/
7+
public interface DocumentFileProcessor {
8+
9+
boolean supportsDocumentFile(DocumentFile documentFile);
10+
11+
void processDocumentFile(DocumentFile documentFile);
12+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.marklogic.client.file;
2+
3+
public interface DocumentMetadataSetter {
4+
5+
void setMetadata(DocumentFile documentFile);
6+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.marklogic.client.file;
2+
3+
import java.util.List;
4+
5+
/**
6+
* Interface for loading files from a set of paths, returning a list of the files that were loaded as DocumentFile
7+
* objects.
8+
*/
9+
public interface FileLoader {
10+
11+
List<DocumentFile> loadFiles(String... paths);
12+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.marklogic.client.file;
2+
3+
import com.marklogic.client.io.Format;
4+
import com.marklogic.client.modulesloader.impl.FormatGetter;
5+
import com.marklogic.client.modulesloader.xcc.DefaultDocumentFormatGetter;
6+
7+
/**
8+
* Delegates to DefaultDocumentFormatGetter by default for determining what Format to use for the File in a given
9+
* DocumentFile.
10+
*/
11+
public class FormatDocumentFileProcessor implements DocumentFileProcessor {
12+
13+
private FormatGetter formatGetter;
14+
15+
public FormatDocumentFileProcessor() {
16+
this(new DefaultDocumentFormatGetter());
17+
}
18+
19+
public FormatDocumentFileProcessor(FormatGetter formatGetter) {
20+
this.formatGetter = formatGetter;
21+
}
22+
23+
@Override
24+
public boolean supportsDocumentFile(DocumentFile documentFile) {
25+
return true;
26+
}
27+
28+
@Override
29+
public void processDocumentFile(DocumentFile documentFile) {
30+
Format format = formatGetter.getFormat(documentFile.getFile());
31+
if (format != null) {
32+
documentFile.setFormat(format);
33+
}
34+
}
35+
36+
public FormatGetter getFormatGetter() {
37+
return formatGetter;
38+
}
39+
40+
public void setFormatGetter(FormatGetter formatGetter) {
41+
this.formatGetter = formatGetter;
42+
}
43+
}

0 commit comments

Comments
 (0)