be.ugent.rml.conformer.MappingConformer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rmlmapper Show documentation
Show all versions of rmlmapper Show documentation
The RMLMapper executes RML rules to generate high quality Linked Data from multiple originally (semi-)structured data sources.
package be.ugent.rml.conformer;
import be.ugent.rml.Utils;
import be.ugent.rml.store.QuadStore;
import be.ugent.rml.term.NamedNode;
import be.ugent.rml.term.Term;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static be.ugent.rml.NAMESPACES.*;
/**
* Only validates by checking for at least one TriplesMap.
* Converts mapping files to RML. Currently only R2RML converter is implemented.
* InputStream of mapping file is used to create a store. TriplesMaps in store that need conversion
* are detected by applying the converters detection methods and saved. convert tries to convert these
* to RML. Exceptions can be raised during validation and conversion, which the caller has to handle.
* Output of detect() informs if convert() should be used to convert to valid RML.
* The validated RML can be returned as a QuadStore with getStore().
*/
public class MappingConformer {
private QuadStore store;
private List unconvertedTriplesMaps = new ArrayList<>();
private Map mappingOptions;
/**
* Create MappingConformer from InputStream of mapping file in RDF.
*
* @param store A QuadStore with the mapping rules.
* @throws FileNotFoundException
*/
public MappingConformer(QuadStore store) throws Exception {
this(store, null);
}
/**
* Create MappingConformer from InputStream of mapping file in RDF.
*
* @param store A QuadStore with the mapping rules.
* @throws FileNotFoundException
*/
public MappingConformer(QuadStore store, Map mappingOptions) throws Exception {
this.store = store;
this.mappingOptions = mappingOptions;
}
/**
* This method makes the QuadStore conformant to the RML spec.
*
* @return True if the store had to be updated, else false.
* @throws Exception if something goes wrong during detection or conversion.
*/
public boolean conform() throws Exception {
boolean conversionNeeded = this.detect();
if (conversionNeeded) {
this.convert();
}
return conversionNeeded;
}
/**
* Detect if mapping file is valid RML.
*
* @return true if valid RML, false if conversion is needed
* @throws Exception if invalid or unconvertable
*/
private boolean detect() throws Exception {
// TODO generalise for multiple converters
Converter converter = new R2RMLConverter(store);
// grab all terms that contain a subject map
List triplesMaps = Utils.getSubjectsFromQuads(store.getQuads(null, new NamedNode(RR + "subjectMap"), null));
// grab all terms that contain a logical source
List logicalSources = Utils.getSubjectsFromQuads(store.getQuads(null, new NamedNode(RML + "logicalSource"), null));
// grab all terms that contain a logical table
List logicalTables = Utils.getSubjectsFromQuads(store.getQuads(null, new NamedNode(RR + "logicalTable"), null));
triplesMaps = triplesMaps.stream()
.filter(term -> logicalSources.contains(term) || logicalTables.contains(term))
.collect(Collectors.toList());
if (triplesMaps.isEmpty()) {
throw new Exception("Mapping requires at least one TriplesMap");
}
// Find all triples maps
// This could be more efficient with a while loop,
// but these TriplesMaps are needed in any case when calling convert().
for (Term triplesMap : triplesMaps) {
if (converter.detect(triplesMap)) {
unconvertedTriplesMaps.add(triplesMap);
}
}
return !unconvertedTriplesMaps.isEmpty();
}
/**
* Tries to convert to RML. Model should still be valid on failure
*
* @throws Exception conversion failed
*/
private void convert() throws Exception {
// TODO generalise for multiple converters
Converter converter = new R2RMLConverter(store);
for (Term unconvertedTriplesMap : unconvertedTriplesMaps) {
converter.convert(unconvertedTriplesMap, mappingOptions);
}
}
/**
* Debugging helper function to check difference of models
*
* @param store QuadStore which subtracts
* @return boolean this.store isSubset of given store
*/
boolean differenceInConformer(QuadStore store) {
return this.store.isSubset(store);
}
/**
* Debugging helper function to check difference of models
*
* @param store QuadStore which subtracts
* @return boolean given store isSubset of store
*/
boolean differenceInGivenStore(QuadStore store) {
return store.isSubset(this.store);
}
/**
* Get a valid QuadStore
*
* @return a valid QuadStore
*/
public QuadStore getStore() {
return store;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy