From 54d6fc501b1593f8bcffe12e4561a793a53585b9 Mon Sep 17 00:00:00 2001 From: jsavell Date: Tue, 29 May 2018 15:00:04 -0500 Subject: [PATCH 1/2] copy clean rdf MetadataConverterPlugin to additions --- .../conversion/MetadataConverterPlugin.java | 287 ++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 dspace/modules/additions/src/main/java/org/dspace/rdf/conversion/MetadataConverterPlugin.java diff --git a/dspace/modules/additions/src/main/java/org/dspace/rdf/conversion/MetadataConverterPlugin.java b/dspace/modules/additions/src/main/java/org/dspace/rdf/conversion/MetadataConverterPlugin.java new file mode 100644 index 000000000000..d1fc834ec36d --- /dev/null +++ b/dspace/modules/additions/src/main/java/org/dspace/rdf/conversion/MetadataConverterPlugin.java @@ -0,0 +1,287 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +package org.dspace.rdf.conversion; + +import com.hp.hpl.jena.rdf.model.InfModel; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.ResIterator; +import com.hp.hpl.jena.reasoner.Reasoner; +import com.hp.hpl.jena.reasoner.ReasonerRegistry; +import com.hp.hpl.jena.reasoner.ValidityReport; +import com.hp.hpl.jena.util.FileManager; +import com.hp.hpl.jena.util.FileUtils; +import com.hp.hpl.jena.vocabulary.RDF; +import java.io.IOException; +import java.io.InputStream; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.dspace.app.util.factory.UtilServiceFactory; +import org.dspace.authorize.AuthorizeException; +import org.dspace.content.*; +import org.dspace.content.factory.ContentServiceFactory; +import org.dspace.content.service.DSpaceObjectService; +import org.dspace.core.Constants; +import org.dspace.core.Context; +import org.dspace.rdf.RDFUtil; +import org.dspace.services.ConfigurationService; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * @author Pascal-Nicolas Becker (dspace -at- pascal -hyphen- becker -dot- de) + */ +public class MetadataConverterPlugin implements ConverterPlugin +{ + public final static String METADATA_MAPPING_PATH_KEY = "rdf.metadata.mappings"; + public final static String METADATA_SCHEMA_URL_KEY = "rdf.metadata.schema"; + public final static String METADATA_PREFIXES_KEY = "rdf.metadata.prefixes"; + + private final static Logger log = Logger.getLogger(MetadataConverterPlugin.class); + @Autowired(required=true) + protected ConfigurationService configurationService; + + @Override + public void setConfigurationService(ConfigurationService configurationService) { + this.configurationService = configurationService; + } + + @Override + public Model convert(Context context, DSpaceObject dso) + throws SQLException, AuthorizeException { + String uri = RDFUtil.generateIdentifier(context, dso); + DSpaceObjectService dsoService = ContentServiceFactory.getInstance().getDSpaceObjectService(dso); + if (uri == null) + { + log.error("Cannot create URI for " + dsoService.getTypeText(dso) + " " + + dso.getID() + " stopping conversion."); + return null; + } + + Model convertedData = ModelFactory.createDefaultModel(); + String prefixesPath = configurationService.getProperty(METADATA_PREFIXES_KEY); + if (!StringUtils.isEmpty(prefixesPath)) + { + InputStream is = FileManager.get().open(prefixesPath); + if (is == null) + { + log.warn("Cannot find file '" + prefixesPath + "', ignoring..."); + } else { + convertedData.read(is, null, FileUtils.guessLang(prefixesPath)); + try { + is.close(); + } + catch (IOException ex) + { + // nothing to do here. + } + } + } + + Model config = loadConfiguration(); + if (config == null) + { + log.error("Cannot load MetadataConverterPlugin configuration, " + + "skipping this plugin."); + return null; + } + /* + if (log.isDebugEnabled()) + { + StringWriter sw = new StringWriter(); + sw.append("Inferenced the following model:\n"); + config.write(sw, "TURTLE"); + sw.append("\n"); + log.debug(sw.toString()); + try { + sw.close(); + } catch (IOException ex) { + // nothing to do here + } + } + */ + + ResIterator mappingIter = + config.listSubjectsWithProperty(RDF.type, DMRM.DSpaceMetadataRDFMapping); + if (!mappingIter.hasNext()) + { + log.warn("No metadata mappings found, returning null."); + return null; + } + + List mappings = new ArrayList<>(); + while (mappingIter.hasNext()) + { + MetadataRDFMapping mapping = MetadataRDFMapping.getMetadataRDFMapping( + mappingIter.nextResource(), uri); + if (mapping != null) mappings.add(mapping); + } + + // should be changed, if Communities and Collections have metadata as well. + if (!(dso instanceof Item)) + { + log.error("This DspaceObject (" + dsoService.getTypeText(dso) + " " + + dso.getID() + ") should not have bin submitted to this " + + "plugin, as it supports Items only!"); + return null; + } + + List metadata_values = dsoService.getMetadata(dso, MetadataSchema.DC_SCHEMA, Item.ANY, Item.ANY, Item.ANY); + for (MetadataValue value : metadata_values) + { + MetadataField metadataField = value.getMetadataField(); + MetadataSchema metadataSchema = metadataField.getMetadataSchema(); + String fieldname = metadataSchema.getName() + "." + metadataField.getElement(); + if (metadataField.getQualifier() != null) + { + fieldname = fieldname + "." + metadataField.getQualifier(); + } + if (UtilServiceFactory.getInstance().getMetadataExposureService().isHidden(context, metadataSchema.getName(), metadataField.getElement(), + metadataField.getQualifier())) + { + log.debug(fieldname + " is a hidden metadata field, won't " + + "convert it."); + continue; + } + + boolean converted = false; + if (metadataField.getQualifier() != null) + { + Iterator iter = mappings.iterator(); + while (iter.hasNext()) + { + MetadataRDFMapping mapping = iter.next(); + if (mapping.matchesName(fieldname) && mapping.fulfills(value.getValue())) + { + mapping.convert(value.getValue(), value.getLanguage(), uri, convertedData); + converted = true; + } + } + } + if (!converted) + { + String name = metadataSchema.getName() + "." + metadataField.getElement(); + Iterator iter = mappings.iterator(); + while (iter.hasNext() && !converted) + { + MetadataRDFMapping mapping = iter.next(); + if (mapping.matchesName(name) && mapping.fulfills(value.getValue())) + { + mapping.convert(value.getValue(), value.getLanguage(), uri, convertedData); + converted = true; + } + } + } + if (!converted) + { + log.debug("Did not convert " + fieldname + ". Found no " + + "corresponding mapping."); + } + } + config.close(); + if (convertedData.isEmpty()) + { + convertedData.close(); + return null; + } + return convertedData; + } + + @Override + public boolean supports(int type) { + // should be changed, if Communities and Collections have metadata as well. + return (type == Constants.ITEM); + } + + protected Model loadConfiguration() + { + InputStream is = null; + Model config = ModelFactory.createDefaultModel(); + String mapping = configurationService.getProperty(METADATA_MAPPING_PATH_KEY); + if (StringUtils.isEmpty(mapping)) + { + log.error("Cannot find metadata mappings (looking for " + + "property " + METADATA_MAPPING_PATH_KEY + ")!"); + return null; + } + else + { + is = FileManager.get().open(mapping); + if (is == null) + { + log.warn("Cannot find file '" + mapping + "', ignoring..."); + } + config.read(is, "file://" + mapping, FileUtils.guessLang(mapping)); + try { + // Make sure that we have an input stream to avoid NullPointer + if(is != null) + { + is.close(); + } + } + catch (IOException ex) + { + // nothing to do here. + } + } + if (config.isEmpty()) + { + config.close(); + log.warn("Metadata RDF Mapping did not contain any triples!"); + return null; + } + + String schemaURL = configurationService.getProperty(METADATA_SCHEMA_URL_KEY); + if (schemaURL == null) + { + log.error("Cannot find metadata rdf mapping schema (looking for " + + "property " + METADATA_SCHEMA_URL_KEY + ")!"); + } + if (!StringUtils.isEmpty(schemaURL)) + { + log.debug("Going to inference over the rdf metadata mapping."); + // Inferencing over the configuration data let us detect some rdf:type + // properties out of rdfs:domain and rdfs:range properties + // A simple rdfs reasoner is enough for this task. + Model schema = ModelFactory.createDefaultModel(); + schema.read(schemaURL); + Reasoner reasoner = ReasonerRegistry.getRDFSSimpleReasoner().bindSchema(schema); + InfModel inf = ModelFactory.createInfModel(reasoner, config); + + // If we do inferencing, we can easily check for consistency. + ValidityReport reports = inf.validate(); + if (!reports.isValid()) + { + StringBuilder sb = new StringBuilder(); + sb.append("The configuration of the MetadataConverterPlugin is "); + sb.append("not valid regarding the schema ("); + sb.append(DMRM.getURI()); + sb.append(").\nThe following problems were encountered:\n"); + for (Iterator iter = reports.getReports(); + iter.hasNext() ; ) + { + ValidityReport.Report report = iter.next(); + if (report.isError) + { + sb.append(" - " + iter.next() + "\n"); + } + } + log.error(sb.toString()); + return null; + } + return inf; + } + return config; + } + +} From f281a146764f049b8520f648aef5dea01e5948e3 Mon Sep 17 00:00:00 2001 From: jsavell Date: Tue, 29 May 2018 15:34:42 -0500 Subject: [PATCH 2/2] TAMU Customization - Map Community/Collection metadata to RDF --- .../dspace/rdf/conversion/MetadataConverterPlugin.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dspace/modules/additions/src/main/java/org/dspace/rdf/conversion/MetadataConverterPlugin.java b/dspace/modules/additions/src/main/java/org/dspace/rdf/conversion/MetadataConverterPlugin.java index d1fc834ec36d..a1f71169e171 100644 --- a/dspace/modules/additions/src/main/java/org/dspace/rdf/conversion/MetadataConverterPlugin.java +++ b/dspace/modules/additions/src/main/java/org/dspace/rdf/conversion/MetadataConverterPlugin.java @@ -127,14 +127,16 @@ public Model convert(Context context, DSpaceObject dso) if (mapping != null) mappings.add(mapping); } + //TAMU Customization - Map more than just ITEMs // should be changed, if Communities and Collections have metadata as well. + /* if (!(dso instanceof Item)) { log.error("This DspaceObject (" + dsoService.getTypeText(dso) + " " + dso.getID() + ") should not have bin submitted to this " + "plugin, as it supports Items only!"); return null; - } + }*/ List metadata_values = dsoService.getMetadata(dso, MetadataSchema.DC_SCHEMA, Item.ANY, Item.ANY, Item.ANY); for (MetadataValue value : metadata_values) @@ -199,8 +201,8 @@ public Model convert(Context context, DSpaceObject dso) @Override public boolean supports(int type) { - // should be changed, if Communities and Collections have metadata as well. - return (type == Constants.ITEM); + //TAMU Customization - Map more than just ITEMs + return (type == Constants.ITEM || type == Constants.COLLECTION || type == Constants.COMMUNITY); } protected Model loadConfiguration()