/**
* 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.storage.rdbms;
import java.io.File;
import java.sql.Connection;
import org.dspace.administer.MetadataImporter;
import org.dspace.administer.RegistryLoader;
import org.dspace.core.Context;
import org.dspace.services.ConfigurationService;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.workflow.factory.WorkflowServiceFactory;
import org.dspace.xmlworkflow.service.XmlWorkflowService;
import org.flywaydb.core.api.MigrationInfo;
import org.flywaydb.core.api.callback.FlywayCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This is a FlywayCallback class which automatically updates the
* Metadata Schema Registry and Bitstream Formats Registries AFTER
* all Database migrations occur.
* <P>
* The reason this runs AFTER all migrations is that the RegistryLoader
* and MetadataImporter now depend on Hibernate and Hibernate cannot be
* initialized until the Database is fully migrated.
* <P>
* If a migration needs to use on one or more registry values, there are
* two options:
* <UL>
* <LI>Create/insert those registry values in the migration itself (via SQL or similar).</LI>
* <LI>Alternatively, first check for the existence of the MetadataSchemaRegistry (or similar)
* before running the migration logic. If the table or fields do not yet exist, you might be
* able to skip the migration logic entirely. See "DatabaseUtils.tableExists()" and similar methods.</LI>
* </UL>
*
* @author Tim Donohue
*/
public class DatabaseRegistryUpdater implements FlywayCallback
{
/** logging category */
private static final Logger log = LoggerFactory.getLogger(DatabaseRegistryUpdater.class);
/**
* Method to actually update our registries from latest configs
*/
private void updateRegistries()
{
ConfigurationService config = DSpaceServicesFactory.getInstance().getConfigurationService();
Context context = null;
try
{
context = new Context();
context.turnOffAuthorisationSystem();
String base = config.getProperty("dspace.dir")
+ File.separator + "config" + File.separator
+ "registries" + File.separator;
// Load updates to Bitstream format registry (if any)
log.info("Updating Bitstream Format Registry based on " + base + "bitstream-formats.xml");
RegistryLoader.loadBitstreamFormats(context, base + "bitstream-formats.xml");
// Load updates to Metadata schema registries (if any)
log.info("Updating Metadata Registries based on metadata type configs in " + base);
MetadataImporter.loadRegistry(base + "dublin-core-types.xml", true);
MetadataImporter.loadRegistry(base + "dcterms-types.xml", true);
MetadataImporter.loadRegistry(base + "local-types.xml", true);
MetadataImporter.loadRegistry(base + "eperson-types.xml", true);
MetadataImporter.loadRegistry(base + "sword-metadata.xml", true);
// Check if XML Workflow is enabled in workflow.cfg
if (WorkflowServiceFactory.getInstance().getWorkflowService() instanceof XmlWorkflowService)
{
// If so, load in the workflow metadata types as well
MetadataImporter.loadRegistry(base + "workflow-types.xml", true);
}
context.restoreAuthSystemState();
// Commit changes and close context
context.complete();
log.info("All Bitstream Format Regitry and Metadata Registry updates were completed.");
}
catch(Exception e)
{
log.error("Error attempting to update Bitstream Format and/or Metadata Registries", e);
throw new RuntimeException("Error attempting to update Bitstream Format and/or Metadata Registries", e);
}
finally
{
// Clean up our context, if it still exists & it was never completed
if(context!=null && context.isValid())
context.abort();
}
}
@Override
public void beforeClean(Connection connection) {
}
@Override
public void afterClean(Connection connection) {
}
@Override
public void beforeMigrate(Connection connection) {
}
@Override
public void afterMigrate(Connection connection) {
// Must run AFTER all migrations complete, since it is dependent on Hibernate
updateRegistries();
}
@Override
public void beforeEachMigrate(Connection connection, MigrationInfo migrationInfo) {
}
@Override
public void afterEachMigrate(Connection connection, MigrationInfo migrationInfo) {
}
@Override
public void beforeValidate(Connection connection) {
}
@Override
public void afterValidate(Connection connection) {
}
@Override
public void beforeBaseline(Connection connection) {
}
@Override
public void afterBaseline(Connection connection) {
}
@Override
public void beforeRepair(Connection connection) {
}
@Override
public void afterRepair(Connection connection) {
}
@Override
public void beforeInfo(Connection connection) {
}
@Override
public void afterInfo(Connection connection) {
}
}