Skip to content

Commit 234ab5a

Browse files
committed
Fix put_rdfmap (metafacture-core#415)
- add tests - add to README
1 parent b11a77e commit 234ab5a

File tree

4 files changed

+129
-44
lines changed

4 files changed

+129
-44
lines changed

README.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,17 @@ Options:
200200
- `key_column`: Defines the column to be used for keys. Uses zero index. (Default: `0`)
201201
- `value_column`: Defines the column to be used for values. Uses zero index. (Default: `1`)
202202

203+
##### `put_rdfmap`
204+
205+
Defines an external RDF map for lookup from a file or an HTTP(S) resource.
206+
As the RDF map is reducing RDF triples to a key/value map it is mandatory to set the target.
207+
The targeted RDF property can optional be bound by an RDF language tag.
208+
209+
```perl
210+
put_rdfmap("<rdfResource>", "<rdfMapName>", target: "<rdfProperty>")
211+
put_rdfmap("<rdfResource>", "<rdfMapName>", target: "<rdfProperty>, target_language: "<rdfLanguageTag>"")
212+
```
213+
203214
##### `put_map`
204215

205216
Defines an internal map for [lookup](#lookup) from key/value pairs.
@@ -608,12 +619,15 @@ lookup("path.to.field", "map-name", print_unknown: "true", destination: "unknown
608619

609620
##### `lookup_rdf`
610621

611-
Looks up matching values in an RDF resource and replaces the field value with this match. A file as well as an HTTP(S) resource can be used.
622+
Looks up matching values in an RDF resource and replaces the field value with a match defined by a targeted RDF property. External files or HTTP(S) resources as well as internal RDF maps can be used.
623+
The targeted RDF property can optional be bound by an RDF language tag.
612624

613625
```perl
614-
lookup_rdf("<sourceField>", "<rdfResource>", target: "<rdfProperty>")
615-
lookup_rdf("<sourceField>", "<rdfResource>", target: "<rdfProperty>", target_language: "<rdfLanguageTag>")
616-
lookup_rdf("<sourceField>", "<rdfResource>", target: "<rdfProperty>", __default: "NA")
626+
lookup_rdf("<sourceField>", "<rdfFile>", target: "<rdfProperty>")
627+
lookup_rdf("<sourceField>", "<rdfHttpUri>", target: "<rdfProperty>")
628+
lookup_rdf("<sourceField>", "<rdfMapName>", target: "<rdfProperty>")
629+
lookup_rdf("<sourceField>", "<rdfMapName>", target: "<rdfProperty>", target_language: "<rdfLanguageTag>")
630+
lookup_rdf("<sourceField>", "<rdfMapName>", target: "<rdfProperty>", __default: "NA")
617631
```
618632

619633
##### `prepend`

metafix/src/main/java/org/metafacture/metafix/FixMethod.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,14 @@ public void apply(final Metafix metafix, final Record record, final List<String>
9696
put_rdfmap {
9797
@Override
9898
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
99-
final String fileName = params.get(0);
99+
final String resourceName = params.get(0);
100100
final RdfMap rdf = new RdfMap();
101-
rdf.setFile(metafix.resolvePath(fileName));
102-
withOption(options, "target", rdf::setTarget);
103-
withOption(options, "target_language", rdf::setTargetLanguage);
101+
rdf.setResource(metafix.resolvePath(resourceName));
102+
withOption(options, RdfMap.TARGET, rdf::setTarget);
103+
withOption(options, RdfMap.TARGET_LANGUAGE, rdf::setTargetLanguage);
104104
withOption(options, Maps.DEFAULT_MAP_KEY, rdf::setDefault);
105-
metafix.putMap(params.size() > 1 ? params.get(1) : fileName, rdf);
105+
final String mapName = (params.size() > 1 ? params.get(1) : params.get(0)) + options.get(RdfMap.TARGET) + options.getOrDefault(RdfMap.TARGET_LANGUAGE, "");
106+
metafix.putMap(mapName, rdf);
106107
}
107108
},
108109
put_var {
@@ -680,15 +681,20 @@ private static Map<String, String> getMap(final Metafix metafix, final Record re
680681
map = options;
681682
}
682683
else {
683-
final String mapName = params.get(1);
684-
684+
final String mapName;
685+
if (kindOfMap.equals(KIND_OF_FILEMAP)) {
686+
mapName = params.get(1);
687+
}
688+
else {
689+
mapName = params.get(1) + options.get(RdfMap.TARGET) + options.getOrDefault(RdfMap.TARGET_LANGUAGE, "");
690+
}
685691
if (!metafix.getMapNames().contains(mapName)) {
686692
if (mapName.contains(".") || mapName.contains(File.separator)) {
687693
if (kindOfMap.equals(KIND_OF_FILEMAP)) {
688694
put_filemap.apply(metafix, record, Arrays.asList(mapName), options);
689695
}
690696
if (kindOfMap.equals(KIND_OF_RDFMAP)) {
691-
put_rdfmap.apply(metafix, record, Arrays.asList(mapName), options);
697+
put_rdfmap.apply(metafix, record, Arrays.asList(params.get(1)), options);
692698
}
693699
}
694700
else {

metafix/src/main/java/org/metafacture/metafix/maps/RdfMap.java

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -56,30 +56,30 @@
5656
* @see org.metafacture.metamorph.maps.FileMap
5757
*/
5858
public final class RdfMap extends AbstractReadOnlyMap<String, String> {
59-
private static String targetLanguage = "";
60-
private static String target;
61-
private static final Logger LOG = LoggerFactory.getLogger(RdfMap.class);
59+
public static final String TARGET = "target";
60+
public static final String TARGET_LANGUAGE = "target_language";
6261
private static final int MAX_REDIRECTIONS = 10;
6362
private static final int MIN_HTTP_STATUS_CODE = 299;
6463
private static final int MAX_HTTP_STATUS_CODE = 400;
65-
64+
private static final Logger LOG = LoggerFactory.getLogger(RdfMap.class);
6665
private Model model;
6766
private boolean isUninitialized = true;
6867
private final ArrayList<String> filenames = new ArrayList<>();
6968
private final Map<String, String> map = new HashMap<>();
69+
private String targetLanguage = "";
70+
private String target;
7071

7172
/**
7273
* Creates an instance of {@link RdfMap}.
7374
*/
7475
public RdfMap() {
7576
targetLanguage = "";
77+
setDefault(Maps.DEFAULT_MAP_KEY);
78+
7679
}
7780

7881
private void init() {
7982
loadFiles();
80-
if (!map.containsKey(Maps.DEFAULT_MAP_KEY)) {
81-
setDefault(Maps.DEFAULT_MAP_KEY);
82-
}
8383
if (!target.toLowerCase().startsWith("http")) {
8484
final String[] nsPrefixAndProperty = target.split(":");
8585
target = nsPrefixAndProperty.length == 2 ? model.getNsPrefixURI(nsPrefixAndProperty[0]) + nsPrefixAndProperty[1] : nsPrefixAndProperty[0];
@@ -101,7 +101,7 @@ public void setFiles(final String files) {
101101
*
102102
* @param file the file
103103
*/
104-
public void setFile(final String file) {
104+
public void setResource(final String file) {
105105
Collections.addAll(filenames, file);
106106
}
107107

@@ -147,20 +147,20 @@ private void loadFile(final String file) {
147147
*/
148148
@Override
149149
public String get(final Object key) {
150-
if (isUninitialized) {
151-
init();
152-
}
153150
String ret;
154151
if (map.containsKey(key.toString())) {
155152
ret = map.get(key.toString());
156153
}
157154
else {
155+
if (isUninitialized) {
156+
init();
157+
}
158158
final Resource resource = ResourceFactory.createResource(key.toString());
159159
final Property targetProperty = ResourceFactory.createProperty(target);
160160
try {
161161
//first try to get LITERAL using SUBJECT and PROPERTY
162-
if (!RdfMap.targetLanguage.isEmpty()) {
163-
ret = model.getRequiredProperty(resource, targetProperty, RdfMap.targetLanguage).getString();
162+
if (!targetLanguage.isEmpty()) {
163+
ret = model.getRequiredProperty(resource, targetProperty, targetLanguage).getString();
164164
}
165165
else {
166166
ret = model.getRequiredProperty(resource, targetProperty).getString();
@@ -174,7 +174,7 @@ public String get(final Object key) {
174174
ret = getLiteralOfPredicateUsingOtherPredicate(key, targetProperty);
175175
}
176176
else {
177-
LOG.info("Could not lookup:'" + key + "@" + (RdfMap.targetLanguage.isEmpty() ? RdfMap.targetLanguage : "") + " for " + target + "'. Going with default value.");
177+
LOG.info("Could not lookup:'" + key + (targetLanguage.isEmpty() ? "@" + targetLanguage : "") + " for " + target + "'. Going with default value.");
178178
}
179179
}
180180
map.put(key.toString(), ret);
@@ -194,7 +194,7 @@ private String getLiteralOfPredicateUsingOtherPredicate(final Object key, final
194194
final StmtIterator iterProp = resource.listProperties(targetProperty);
195195
while (iterProp.hasNext()) {
196196
stmt = iterProp.nextStatement();
197-
if (stmt.getLanguage().equals(RdfMap.targetLanguage) && !stmt.getString().equals(key)) {
197+
if (stmt.getLanguage().equals(targetLanguage) && !stmt.getString().equals(key)) {
198198
ret = stmt.getString();
199199
}
200200
}
@@ -210,8 +210,8 @@ private String getSubjectUsingPropertyAndLiteral(final Object key, final Propert
210210
while (iter.hasNext()) {
211211
resource = iter.nextResource();
212212
if (resource.getProperty(targetProperty).getString().equals(key.toString())) {
213-
if (!RdfMap.targetLanguage.isEmpty()) {
214-
if (resource.getProperty(targetProperty).getLanguage().equals(RdfMap.targetLanguage)) {
213+
if (!this.targetLanguage.isEmpty()) {
214+
if (resource.getProperty(targetProperty).getLanguage().equals(targetLanguage)) {
215215
ret = resource.getURI();
216216
}
217217
}
@@ -223,6 +223,16 @@ private String getSubjectUsingPropertyAndLiteral(final Object key, final Propert
223223
return ret;
224224
}
225225

226+
/**
227+
* Gets the language of the target Property which is queried in the RDF. Valid values are defined by BCP47.
228+
* <br>
229+
*
230+
* @return the targeted language
231+
*/
232+
public String getTargetLanguage() {
233+
return targetLanguage;
234+
}
235+
226236
/**
227237
* Sets the language of the target Property which is queried in the RDF. Valid values are defined by BCP47.
228238
* <br>
@@ -231,7 +241,17 @@ private String getSubjectUsingPropertyAndLiteral(final Object key, final Propert
231241
* @param targetLanguage the language of the target Property to be queried
232242
*/
233243
public void setTargetLanguage(final String targetLanguage) {
234-
RdfMap.targetLanguage = targetLanguage;
244+
this.targetLanguage = targetLanguage;
245+
}
246+
247+
/**
248+
* Gets the target Property which is queried in the RDF. Namespaces are allowed.
249+
* <br>
250+
*
251+
* @return the target Property to be queried
252+
*/
253+
public String getTarget() {
254+
return target;
235255
}
236256

237257
/**
@@ -242,7 +262,7 @@ public void setTargetLanguage(final String targetLanguage) {
242262
* @param target the Property to be queried
243263
*/
244264
public void setTarget(final String target) {
245-
RdfMap.target = target;
265+
this.target = target;
246266
}
247267

248268
/**

metafix/src/test/java/org/metafacture/metafix/MetafixLookupTest.java

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,30 @@ public void shouldPrintUnknownToFileWithoutAppend() throws IOException {
958958
MetafixTestHelpers.assertTempFile("you\ntoo\n", p -> shouldPrintUnknown(", destination: '" + p + "', append: 'false'", null, ""));
959959
}
960960

961+
@Test
962+
public void shouldLookupInSeparateExternalRdfFileMapWithName() {
963+
assertRdfMap(
964+
"put_rdfmap('" + RDF_MAP + "', 'testMapSkosNotation', target: 'skos:notation')",
965+
"lookup_rdf('notation', 'testMapSkosNotation', target: 'skos:notation')"
966+
);
967+
}
968+
969+
@Test
970+
public void shouldLookupInSeparateExternalRdfFileMapWithDifferentTargets() {
971+
assertRdfMapWithDifferentTargets(
972+
"put_rdfmap('" + RDF_MAP + "', 'testRdfMapSkosNotation', target: 'skos:notation')",
973+
"put_rdfmap('" + RDF_MAP + "', 'testRdfMapCreated', target: 'created')",
974+
"lookup_rdf('notation', 'testRdfMapSkosNotation', target: 'skos:notation')",
975+
"lookup_rdf('created', 'testRdfMapCreated', target: 'created')");
976+
}
977+
978+
@Test
979+
public void shouldLookupInExternalRdfWithDifferentTargets() {
980+
assertRdfMapWithDifferentTargets(
981+
"lookup_rdf('notation', '" + RDF_MAP + "', target: 'skos:notation')",
982+
"lookup_rdf('created', '" + RDF_MAP + "', target: 'created')");
983+
}
984+
961985
@Test
962986
public void shouldLookupInExternalRdfUseDefinedDefaultValueIfNotFound() {
963987
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
@@ -996,19 +1020,8 @@ public void shouldLookupInExternalRdfUseDefaultValueIfNotFound() {
9961020

9971021
@Test
9981022
public void shouldLookupInExternalRdfMapGetObjectOfSubjectWithTargetedPredicate() {
999-
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
1000-
"lookup_rdf('notation', '" + RDF_MAP + "', target: 'skos:notation')"
1001-
),
1002-
i -> {
1003-
i.startRecord("1");
1004-
i.literal("notation", "https://w3id.org/kim/hochschulfaechersystematik/n4");
1005-
i.endRecord();
1006-
},
1007-
o -> {
1008-
o.get().startRecord("1");
1009-
o.get().literal("notation", "4");
1010-
o.get().endRecord();
1011-
}
1023+
assertRdfMap(
1024+
"lookup_rdf('notation', '" + RDF_MAP + "', target: 'skos:notation')"
10121025
);
10131026
}
10141027

@@ -1114,4 +1127,36 @@ private void assertMap(final String... fixDef) {
11141127
);
11151128
}
11161129

1130+
private void assertRdfMap(final String... fixDef) {
1131+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(fixDef),
1132+
i -> {
1133+
i.startRecord("1");
1134+
i.literal("notation", "https://w3id.org/kim/hochschulfaechersystematik/n4");
1135+
i.endRecord();
1136+
},
1137+
o -> {
1138+
o.get().startRecord("1");
1139+
o.get().literal("notation", "4");
1140+
o.get().endRecord();
1141+
}
1142+
);
1143+
}
1144+
1145+
private void assertRdfMapWithDifferentTargets(final String... fixDef) {
1146+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(fixDef),
1147+
i -> {
1148+
i.startRecord("1");
1149+
i.literal("notation", "https://w3id.org/kim/hochschulfaechersystematik/n4");
1150+
i.literal("created", "https://w3id.org/kim/hochschulfaechersystematik/n4");
1151+
i.endRecord();
1152+
},
1153+
o -> {
1154+
o.get().startRecord("1");
1155+
o.get().literal("notation", "4");
1156+
o.get().literal("created", "__default");
1157+
o.get().endRecord();
1158+
}
1159+
);
1160+
}
1161+
11171162
}

0 commit comments

Comments
 (0)