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

Commit b60bd1f

Browse files
author
Rob Rudin
committed
#53 Can now specify a collections.properties file to configure collections for a ruleset
1 parent f4a0b98 commit b60bd1f

File tree

11 files changed

+200
-26
lines changed

11 files changed

+200
-26
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.marklogic.client.file;
2+
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;
10+
import java.util.Properties;
11+
12+
/**
13+
* Looks for a special file in each directory - defaults to collections.properties - that contains properties where the
14+
* 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.
18+
*/
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+
}
50+
51+
return documentFile;
52+
}
53+
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+
}
74+
}
75+
76+
public Map<File, Properties> getPropertiesCache() {
77+
return propertiesCache;
78+
}
79+
80+
public void setCollectionsFilename(String collectionsFilename) {
81+
this.collectionsFilename = collectionsFilename;
82+
}
83+
}

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,32 @@ public DefaultFileLoader(BatchWriter batchWriter, DocumentFileFinder documentFil
3030

3131
protected void initializeDocumentFileProcessors() {
3232
documentFileProcessors = new ArrayList<>();
33+
documentFileProcessors.add(new CollectionsDocumentFileProcessor());
3334
documentFileProcessors.add(new FormatDocumentFileProcessor());
3435
}
3536

3637
@Override
3738
public List<DocumentFile> loadFiles(String... paths) {
3839
List<DocumentFile> documentFiles = documentFileFinder.findDocumentFiles(paths);
39-
processDocumentFiles(documentFiles);
40+
documentFiles = processDocumentFiles(documentFiles);
4041
batchWriter.write(documentFiles);
4142
return documentFiles;
4243
}
4344

4445
protected List<DocumentFile> processDocumentFiles(List<DocumentFile> documentFiles) {
46+
List<DocumentFile> newFiles = new ArrayList<>();
4547
for (DocumentFile file : documentFiles) {
4648
for (DocumentFileProcessor processor : documentFileProcessors) {
47-
if (processor.supportsDocumentFile(file)) {
48-
processor.processDocumentFile(file);
49+
file = processor.processDocumentFile(file);
50+
if (file == null) {
51+
break;
4952
}
5053
}
54+
if (file != null) {
55+
newFiles.add(file);
56+
}
5157
}
52-
return documentFiles;
58+
return newFiles;
5359
}
5460
public DocumentFileProcessor getDocumentFileProcessor(String classShortName) {
5561
for (DocumentFileProcessor processor : documentFileProcessors) {

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
import java.util.List;
44

5+
/**
6+
* Strategy interface for determining which files to load into MarkLogic, with those files being captured as a List of
7+
* DocumentFile objects.
8+
*/
59
public interface DocumentFileFinder {
610

711
List<DocumentFile> findDocumentFiles(String... paths);
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package com.marklogic.client.file;
22

33
/**
4-
* Callback-style interface for processing - i.e. do whatever you want with - a DocumentFile instance before it's
5-
* written to MarkLogic.
4+
* Interface for processing - i.e. do whatever you want with - a DocumentFile instance before it's written to MarkLogic.
65
*/
76
public interface DocumentFileProcessor {
87

9-
boolean supportsDocumentFile(DocumentFile documentFile);
8+
/**
9+
* @param documentFile
10+
* @return the same or a new DocumentFile instance
11+
*/
12+
DocumentFile processDocumentFile(DocumentFile documentFile);
1013

11-
void processDocumentFile(DocumentFile documentFile);
1214
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.marklogic.client.file;
2+
3+
import java.io.FileFilter;
4+
5+
/**
6+
* Simple filter implementation for returning null if the DocumentFile doesn't match the given FileFilter.
7+
*/
8+
public class FilterDocumentFileProcessor implements DocumentFileProcessor {
9+
10+
private FileFilter fileFilter;
11+
12+
public FilterDocumentFileProcessor(FileFilter fileFilter) {
13+
this.fileFilter = fileFilter;
14+
}
15+
16+
@Override
17+
public DocumentFile processDocumentFile(DocumentFile documentFile) {
18+
return fileFilter.accept(documentFile.getFile()) ? documentFile : null;
19+
}
20+
}

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,12 @@ public FormatDocumentFileProcessor(FormatGetter formatGetter) {
2121
}
2222

2323
@Override
24-
public boolean supportsDocumentFile(DocumentFile documentFile) {
25-
return true;
26-
}
27-
28-
@Override
29-
public void processDocumentFile(DocumentFile documentFile) {
24+
public DocumentFile processDocumentFile(DocumentFile documentFile) {
3025
Format format = formatGetter.getFormat(documentFile.getFile());
3126
if (format != null) {
3227
documentFile.setFormat(format);
3328
}
29+
return documentFile;
3430
}
3531

3632
public FormatGetter getFormatGetter() {

src/main/java/com/marklogic/client/schemasloader/impl/TdeDocumentFileProcessor.java

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,18 @@
77
public class TdeDocumentFileProcessor implements DocumentFileProcessor {
88

99
@Override
10-
public boolean supportsDocumentFile(DocumentFile documentFile) {
10+
public DocumentFile processDocumentFile(DocumentFile documentFile) {
1111
String extension = documentFile.getFileExtension();
12-
return "tdej".equals(extension) || "tdex".equals(extension);
13-
}
14-
15-
@Override
16-
public void processDocumentFile(DocumentFile documentFile) {
17-
documentFile.getDocumentMetadata().withCollections("http://marklogic.com/xdmp/tde");
1812

19-
String extension = documentFile.getFileExtension();
20-
if ("tdej".equals(extension)) {
21-
documentFile.setFormat(Format.JSON);
22-
} else if ("tdex".equals(extension)) {
23-
documentFile.setFormat(Format.XML);
13+
if ("tdej".equals(extension) || "tdex".equals(extension)) {
14+
documentFile.getDocumentMetadata().withCollections("http://marklogic.com/xdmp/tde");
15+
if ("tdej".equals(extension)) {
16+
documentFile.setFormat(Format.JSON);
17+
} else if ("tdex".equals(extension)) {
18+
documentFile.setFormat(Format.XML);
19+
}
2420
}
21+
22+
return documentFile;
2523
}
2624
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.marklogic.client.schemasloader.impl;
2+
3+
import com.marklogic.client.AbstractIntegrationTest;
4+
import com.marklogic.client.file.DocumentFile;
5+
import com.marklogic.client.helper.ClientHelper;
6+
import org.junit.Before;
7+
import org.junit.Test;
8+
9+
import java.util.List;
10+
11+
/**
12+
* Created by rrudin on 2/21/2017.
13+
*/
14+
public class LoadRulesetsTest extends AbstractIntegrationTest {
15+
16+
/**
17+
* Wipes out documents matching the ones we intend to load - it's assumed you're not using the Schemas database for
18+
* anything besides ad hoc testing like this.
19+
*/
20+
@Before
21+
public void setup() {
22+
client = newClient("Schemas");
23+
client.newServerEval().xquery("cts:uri-match('/ruleset*.*') ! xdmp:document-delete(.)").eval();
24+
}
25+
26+
@Test
27+
public void test() {
28+
DefaultSchemasLoader loader = new DefaultSchemasLoader(client);
29+
List<DocumentFile> files = loader.loadSchemas("src/test/resources/rulesets/collection-test");
30+
assertEquals(2, files.size());
31+
32+
ClientHelper helper = new ClientHelper(client);
33+
34+
List<String> collections = helper.getCollections("/ruleset1.xml");
35+
assertEquals(1, collections.size());
36+
assertTrue(collections.contains("ruleset-abc"));
37+
38+
collections = helper.getCollections("/ruleset2.json");
39+
assertEquals(2, collections.size());
40+
assertTrue(collections.contains("ruleset-abc"));
41+
assertTrue(collections.contains("ruleset-xyz"));
42+
43+
}
44+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ruleset1.xml=ruleset-abc
2+
ruleset2.json=ruleset-abc,ruleset-xyz
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<rdt:rule xml:lang="zxx" xmlns:rdt="http://marklogic.com/xdmp/redaction">
2+
<rdt:path>//name</rdt:path>
3+
<rdt:method>
4+
<rdt:function>mask-deterministic</rdt:function>
5+
</rdt:method>
6+
<rdt:options>
7+
<length>10</length>
8+
</rdt:options>
9+
</rdt:rule>

0 commit comments

Comments
 (0)