Skip to content

Commit

Permalink
Merge pull request #155 from TAMULib/dame-sprint-may-b03474-rdf-enhan…
Browse files Browse the repository at this point in the history
…cement

[B03474] Map the metadata of Communities and Collections in RDF webapp
  • Loading branch information
jcreel authored Jun 4, 2018
2 parents 5550754 + f281a14 commit a592aa1
Showing 1 changed file with 289 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,289 @@
/**
* 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<DSpaceObject> 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<MetadataRDFMapping> mappings = new ArrayList<>();
while (mappingIter.hasNext())
{
MetadataRDFMapping mapping = MetadataRDFMapping.getMetadataRDFMapping(
mappingIter.nextResource(), uri);
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<MetadataValue> 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<MetadataRDFMapping> 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<MetadataRDFMapping> 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) {
//TAMU Customization - Map more than just ITEMs
return (type == Constants.ITEM || type == Constants.COLLECTION || type == Constants.COMMUNITY);
}

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<ValidityReport.Report> 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;
}

}

0 comments on commit a592aa1

Please sign in to comment.