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

Commit 6846ed5

Browse files
author
Rob Rudin
committed
#53 Reworked FileLoader, added processors to DocumentFileReader, now supporting collections.properties and permissions.properties
1 parent b60bd1f commit 6846ed5

16 files changed

+404
-298
lines changed
Lines changed: 13 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,28 @@
11
package com.marklogic.client.file;
22

3-
import com.marklogic.client.helper.LoggingObject;
4-
5-
import java.io.File;
6-
import java.io.FileReader;
7-
import java.io.IOException;
8-
import java.util.HashMap;
9-
import java.util.Map;
103
import java.util.Properties;
114

125
/**
136
* Looks for a special file in each directory - defaults to collections.properties - that contains properties where the
147
* key is the name of a file in the directory, and the value is a comma-delimited list of collections to load the file
15-
* into (which means you can't use a comma in any collection name). This will by default NOT load the configured
16-
* properties file, as that's expected to just be configuration data and not something that's intended to be loaded
17-
* into MarkLogic.
8+
* into (which means you can't use a comma in any collection name).
189
*/
19-
public class CollectionsDocumentFileProcessor extends LoggingObject implements DocumentFileProcessor {
20-
21-
private String collectionsFilename = "collections.properties";
22-
23-
// Used to avoid checking for and loading the properties for every file in a directory
24-
private Map<File, Properties> propertiesCache = new HashMap<>();
25-
26-
/**
27-
* @param documentFile
28-
* @return
29-
*/
30-
@Override
31-
public DocumentFile processDocumentFile(DocumentFile documentFile) {
32-
File file = documentFile.getFile();
33-
String name = file.getName();
34-
if (collectionsFilename.equals(name)) {
35-
return null;
36-
}
37-
38-
File collectionsFile = new File(file.getParentFile(), collectionsFilename);
39-
if (collectionsFile.exists()) {
40-
try {
41-
Properties props = loadProperties(collectionsFile);
42-
if (props.containsKey(name)) {
43-
String value = props.getProperty(name);
44-
documentFile.getDocumentMetadata().withCollections(value.split(","));
45-
}
46-
} catch (IOException e) {
47-
logger.warn("Unable to load properties from collections file: " + collectionsFile.getAbsolutePath(), e);
48-
}
49-
}
10+
public class CollectionsDocumentFileProcessor extends PropertiesDrivenDocumentFileProcessor {
5011

51-
return documentFile;
12+
public CollectionsDocumentFileProcessor() {
13+
this("collections.properties");
5214
}
5315

54-
protected Properties loadProperties(File collectionsFile) throws IOException {
55-
Properties props = null;
56-
if (propertiesCache.containsKey(collectionsFile)) {
57-
props = propertiesCache.get(collectionsFile);
58-
}
59-
if (props != null) {
60-
return props;
61-
}
62-
props = new Properties();
63-
FileReader reader = null;
64-
try {
65-
reader = new FileReader(collectionsFile);
66-
props.load(reader);
67-
propertiesCache.put(collectionsFile, props);
68-
return props;
69-
} finally {
70-
if (reader != null) {
71-
reader.close();
72-
}
73-
}
16+
public CollectionsDocumentFileProcessor(String propertiesFilename) {
17+
super(propertiesFilename);
7418
}
7519

76-
public Map<File, Properties> getPropertiesCache() {
77-
return propertiesCache;
78-
}
79-
80-
public void setCollectionsFilename(String collectionsFilename) {
81-
this.collectionsFilename = collectionsFilename;
20+
@Override
21+
protected void processProperties(DocumentFile documentFile, Properties properties) {
22+
String name = documentFile.getFile().getName();
23+
if (properties.containsKey(name)) {
24+
String value = properties.getProperty(name);
25+
documentFile.getDocumentMetadata().withCollections(value.split(","));
26+
}
8227
}
8328
}

src/main/java/com/marklogic/client/file/DefaultDocumentFileFinder.java

Lines changed: 0 additions & 75 deletions
This file was deleted.
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
package com.marklogic.client.file;
2+
3+
import com.marklogic.client.helper.LoggingObject;
4+
import org.springframework.util.ClassUtils;
5+
6+
import java.io.File;
7+
import java.io.FileFilter;
8+
import java.io.IOException;
9+
import java.nio.file.*;
10+
import java.nio.file.attribute.BasicFileAttributes;
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
14+
/**
15+
* Non-threadsafe implementation that implements FileVisitor as a way of descending one or more file paths.
16+
*/
17+
public class DefaultDocumentFileReader extends LoggingObject implements FileVisitor<Path>, DocumentFileReader {
18+
19+
private Path currentRootPath;
20+
private List<FileFilter> fileFilters;
21+
private List<DocumentFile> documentFiles;
22+
private List<DocumentFileProcessor> documentFileProcessors;
23+
24+
public DefaultDocumentFileReader() {
25+
initialize();
26+
}
27+
28+
/**
29+
* Walk the file tree at each of the given paths, applying any configured DocumentFileProcessor instances on each
30+
* DocumentFile that is constructed by a File.
31+
*
32+
* @param paths
33+
* @return
34+
*/
35+
public List<DocumentFile> readDocumentFiles(String... paths) {
36+
documentFiles = new ArrayList<>();
37+
for (String path : paths) {
38+
if (logger.isDebugEnabled()) {
39+
logger.debug(format("Finding documents at path: %s", path));
40+
}
41+
this.currentRootPath = Paths.get(path);
42+
try {
43+
Files.walkFileTree(this.currentRootPath, this);
44+
} catch (IOException ie) {
45+
throw new RuntimeException(format("IO error while walking file tree at path: %s", path), ie);
46+
}
47+
}
48+
return documentFiles;
49+
}
50+
51+
@Override
52+
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
53+
boolean accept = acceptPath(dir, attrs);
54+
if (accept) {
55+
if (logger.isTraceEnabled()) {
56+
logger.trace("Visiting directory: " + dir);
57+
}
58+
return FileVisitResult.CONTINUE;
59+
} else {
60+
if (logger.isTraceEnabled()) {
61+
logger.trace("Skipping directory: " + dir);
62+
}
63+
return FileVisitResult.SKIP_SUBTREE;
64+
}
65+
}
66+
67+
@Override
68+
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
69+
return FileVisitResult.CONTINUE;
70+
}
71+
72+
@Override
73+
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
74+
return FileVisitResult.CONTINUE;
75+
}
76+
77+
@Override
78+
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
79+
if (acceptPath(path, attrs)) {
80+
DocumentFile documentFile = buildDocumentFile(path, currentRootPath);
81+
documentFile = processDocumentFile(documentFile);
82+
if (documentFile != null) {
83+
this.documentFiles.add(documentFile);
84+
}
85+
}
86+
return FileVisitResult.CONTINUE;
87+
}
88+
89+
/**
90+
* If any of the configured FileFilter objects do not accept the Path, then it is not accepted.
91+
*
92+
* @param path
93+
* @param attrs
94+
* @return
95+
*/
96+
protected boolean acceptPath(Path path, BasicFileAttributes attrs) {
97+
if (fileFilters != null) {
98+
File file = path.toFile();
99+
for (FileFilter filter : fileFilters) {
100+
if (!filter.accept(file)) {
101+
return false;
102+
}
103+
}
104+
}
105+
return true;
106+
}
107+
108+
protected DocumentFile buildDocumentFile(Path path, Path currentRootPath) {
109+
Path relPath = currentRootPath.relativize(path);
110+
String uri = "/" + relPath.toString().replace("\\", "/");
111+
File f = path.toFile();
112+
return new DocumentFile(uri, f);
113+
}
114+
115+
protected DocumentFile processDocumentFile(DocumentFile documentFile) {
116+
for (DocumentFileProcessor processor : documentFileProcessors) {
117+
documentFile = processor.processDocumentFile(documentFile);
118+
if (documentFile == null) {
119+
break;
120+
}
121+
}
122+
return documentFile;
123+
}
124+
125+
protected void initialize() {
126+
CollectionsDocumentFileProcessor cdfp = new CollectionsDocumentFileProcessor();
127+
PermissionsDocumentFileProcessor pdfp = new PermissionsDocumentFileProcessor();
128+
129+
addFileFilter(cdfp);
130+
addFileFilter(pdfp);
131+
132+
addDocumentFileProcessor(cdfp);
133+
addDocumentFileProcessor(pdfp);
134+
addDocumentFileProcessor(new FormatDocumentFileProcessor());
135+
}
136+
137+
public DocumentFileProcessor getDocumentFileProcessor(String classShortName) {
138+
for (DocumentFileProcessor processor : documentFileProcessors) {
139+
if (ClassUtils.getShortName(processor.getClass()).equals(classShortName)) {
140+
return processor;
141+
}
142+
}
143+
return null;
144+
}
145+
146+
public void addDocumentFileProcessor(DocumentFileProcessor processor) {
147+
if (documentFileProcessors == null) {
148+
documentFileProcessors = new ArrayList<>();
149+
}
150+
documentFileProcessors.add(processor);
151+
}
152+
153+
public void addFileFilter(FileFilter fileFilter) {
154+
if (fileFilters == null) {
155+
fileFilters = new ArrayList<>();
156+
}
157+
fileFilters.add(fileFilter);
158+
}
159+
160+
public List<DocumentFileProcessor> getDocumentFileProcessors() {
161+
return documentFileProcessors;
162+
}
163+
164+
public void setDocumentFileProcessors(List<DocumentFileProcessor> documentFileProcessors) {
165+
this.documentFileProcessors = documentFileProcessors;
166+
}
167+
168+
public List<FileFilter> getFileFilters() {
169+
return fileFilters;
170+
}
171+
172+
public void setFileFilters(List<FileFilter> fileFilters) {
173+
this.fileFilters = fileFilters;
174+
}
175+
}

0 commit comments

Comments
 (0)