/** * 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.content.crosswalk; import org.apache.commons.lang3.tuple.ImmutableTriple; import org.apache.commons.lang3.tuple.Triple; import org.dspace.authorize.AuthorizeException; import org.dspace.content.MetadataField; import org.dspace.content.MetadataSchema; import org.dspace.content.NonUniqueMetadataException; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.MetadataFieldService; import org.dspace.content.service.MetadataSchemaService; import org.dspace.core.ConfigurationManager; import org.dspace.core.Context; import java.sql.SQLException; import java.util.Date; import java.util.HashMap; import java.util.Map; public class CrosswalkMetadataValidator { protected MetadataSchemaService metadataSchemaService; protected MetadataFieldService metadataFieldService; private String schemaChoice; private String fieldChoice; private Map<Triple<String, String, String>, MetadataField> validatedMetadataFields; public CrosswalkMetadataValidator() { metadataSchemaService = ContentServiceFactory.getInstance().getMetadataSchemaService(); metadataFieldService = ContentServiceFactory.getInstance().getMetadataFieldService(); validatedMetadataFields = new HashMap<>(); // The two options, with three possibilities each: add, ignore, fail schemaChoice = ConfigurationManager.getProperty("oai", "harvester.unknownSchema"); if (schemaChoice == null) { schemaChoice = "fail"; } fieldChoice = ConfigurationManager.getProperty("oai", "harvester.unknownField"); if (fieldChoice == null) { fieldChoice = "fail"; } } /** * Scans metadata for elements not defined in this DSpace instance. It then takes action based * on a configurable parameter (fail, ignore, add). * * @param context * The relevant DSpace Context. * @param schema metadata field schema * @param element metadata field element * @param qualifier metadata field qualifier * @param forceCreate if true, force addinga schema or metadata field * @return metadata field * @throws SQLException * An exception that provides information on a database access error or other errors. * @throws AuthorizeException * Exception indicating the current user of the context does not have permission * to perform a particular action. * @throws CrosswalkException * Superclass for more-specific crosswalk exceptions. */ public MetadataField checkMetadata(Context context, String schema, String element, String qualifier, boolean forceCreate) throws SQLException, AuthorizeException, CrosswalkException { if (!validatedBefore(schema, element, qualifier)) { // Verify that the schema exists MetadataSchema mdSchema = metadataSchemaService.find(context, schema); MetadataField mdField = null; if (mdSchema == null) { // add a new schema, giving it a namespace of "unknown". Possibly a very bad idea. if (forceCreate && schemaChoice.equals("add")) { try { mdSchema = metadataSchemaService.create(context, schema, String.valueOf(new Date().getTime())); mdSchema.setNamespace("unknown" + mdSchema.getID()); metadataSchemaService.update(context, mdSchema); } catch (NonUniqueMetadataException e) { // This case should not be possible e.printStackTrace(); } } // ignore the offending schema, quietly dropping all of its metadata elements before they clog our gears else if (!schemaChoice.equals("ignore")) { throw new CrosswalkException("The '" + schema + "' schema has not been defined in this DSpace instance. "); } } if (mdSchema != null) { // Verify that the element exists; this part is reachable only if the metadata schema is valid mdField = metadataFieldService.findByElement(context, mdSchema, element, qualifier); if (mdField == null) { if (forceCreate && fieldChoice.equals("add")) { try { metadataFieldService.create(context, mdSchema, element, qualifier, null); } catch (NonUniqueMetadataException e) { // This case should also not be possible e.printStackTrace(); } } else if (!fieldChoice.equals("ignore")) { throw new CrosswalkException("The '" + element + "." + qualifier + "' element has not been defined in this DSpace instance. "); } } } validatedMetadataFields.put(createKey(schema, element, qualifier), mdField); } return validatedMetadataFields.get(createKey(schema, element, qualifier)); } private boolean validatedBefore(String schema, String element, String qualifier) { return validatedMetadataFields.containsKey(createKey(schema, element, qualifier)); } private ImmutableTriple<String, String, String> createKey(final String schema, final String element, final String qualifier) { return new ImmutableTriple<String, String, String>(schema, element, qualifier); } }