Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1fc2e5e
WIP - SIARDDK export and import support
LizardLump May 8, 2026
3f16e32
WIP - some SIARDDK and data type export fixes
LizardLump May 15, 2026
82847e7
Add SIARDDK128MetadataExportStrategy
LizardLump May 18, 2026
d112504
Fix SIARDDK128 docindex marshalling
LizardLump May 22, 2026
628cd40
Fix JAXB context for DocIndex in SIARD DK 128
LizardLump May 27, 2026
4a96d56
Implement asynchronous LOB conversion with HTTP service and enhance B…
006627 Jun 2, 2026
f26062e
Enhance HttpLobConversionService and SIARDDKDatabaseExportModule for …
006627 Jun 2, 2026
daae156
Enhance SIARDDKDatabaseExportModule with improved logging and gracefu…
006627 Jun 3, 2026
96c8199
Refactor LOB conversion service to support multiple converted files a…
006627 Jun 9, 2026
f3a0c59
Add conversion service options to parameter categories and update inp…
006627 Jun 15, 2026
84d6631
Adapt integration with lob conversion plugin to properly support bina…
LizardLump Jun 16, 2026
b55622f
Ignore invalid mimetypes and unprocessed files in SIARDDK export
LizardLump Jun 17, 2026
0a0549e
Default SIARDDK mimetype and processing status check
LizardLump Jun 17, 2026
1805f1b
Don't convert extension twice in SIARDDKContentExportStrategy
LizardLump Jun 18, 2026
b7fab59
Only write column data for lob columns if lobs are successfully proce…
LizardLump Jun 18, 2026
c5e78fe
Refactor HttpLobConversionService to improve exception handling and u…
006627 Jun 19, 2026
233fce2
Refactor SIARDDKContentExportStrategy to improve artifact handling an…
006627 Jun 21, 2026
3420966
Enhance SIARDDKContentExportStrategy with LOB conversion auditing and…
006627 Jun 21, 2026
e568583
Add ComplianceStatus enum and enhance report models with additional p…
006627 Jun 22, 2026
eb74b38
Include researchIndex.xsd in produced SIARDDK 128
LizardLump Jun 22, 2026
a9f162e
Only include researchIndex.xsd in SIARDDK128
LizardLump Jun 23, 2026
3925b4c
Enhance SQLServerDatatypeImporter to support BLOB type handling for v…
006627 Jun 22, 2026
b5d4d30
Add ExportModuleContextManager for managing export module context and…
006627 Jun 25, 2026
dc30968
refactor: cell value strip trailing
VitorLelis Jul 8, 2026
c364133
fix: original filename of external lobs on doc indexes
VitorLelis Jul 30, 2026
c8a5096
fix: issues after rebase
VitorLelis Sep 9, 2026
e39b143
refactor: non normalizer blobs and siard tests
VitorLelis Sep 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import com.databasepreservation.common.io.providers.TemporaryPathInputStreamProvider;
import com.databasepreservation.model.data.BinaryCell;
import com.databasepreservation.model.data.Cell;
import com.databasepreservation.model.data.Row;
Expand Down Expand Up @@ -539,15 +540,15 @@ protected DatabaseStructure generateDatabaseStructure() throws ModuleException,
new Row(1,
Arrays.asList(new SimpleCell("table02.col121.0", "1"), new SimpleCell("table02.col122.0", "3"),
new SimpleCell("table02.col123.0", "abc"), new SimpleCell("table02.col124.0", "def"),
new BinaryCell("table02.col125.0", newBlob()))),
new BinaryCell("table02.col125.0", new TemporaryPathInputStreamProvider(newBlob()), "image/tiff"))),
new Row(2,
Arrays.asList(new SimpleCell("table02.col121.1", "2"), new SimpleCell("table02.col122.1", "1"),
new SimpleCell("table02.col123.1", "dns"), new SimpleCell("table02.col124.1", "dud"),
new BinaryCell("table02.col125.1", newBlob()))),
new BinaryCell("table02.col125.1", new TemporaryPathInputStreamProvider(newBlob()), "image/tiff"))),
new Row(3,
Arrays.asList(new SimpleCell("table02.col121.2", "3"), new SimpleCell("table02.col122.2", "2"),
new SimpleCell("table02.col123.2", "usl"), new SimpleCell("table02.col124.2", "aps"),
new BinaryCell("table02.col125.2", newBlob())))));
new BinaryCell("table02.col125.2", new TemporaryPathInputStreamProvider(newBlob()), "image/tiff")))));
tableRows.put("schema02.table01", new ArrayList<Row>());
tableRows.put("schema02.table02", new ArrayList<Row>());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import org.apache.commons.lang3.tuple.Pair;

import com.databasepreservation.managers.ExportModuleContextManager;
import com.databasepreservation.model.exception.ModuleException;
import com.databasepreservation.model.modules.DatabaseImportModule;
import com.databasepreservation.model.modules.DatabaseModuleFactory;
Expand Down Expand Up @@ -60,67 +61,75 @@ public DatabaseImportModule getImportModule() throws ModuleException {
public void migrate() throws ModuleException {
validate();

// get import module and export module instance
Map<Parameter, String> importParameters = buildParametersFromStringParameters(importModuleFactory,
importModuleFactoryStringParameters);
Map<Parameter, String> exportParameters = buildParametersFromStringParameters(exportModuleFactory,
exportModuleFactoryStringParameters);

DatabaseImportModule importModule = importModuleFactory.buildImportModule(importParameters, reporter);
DatabaseFilterModule exportModule = exportModuleFactory.buildExportModule(exportParameters, reporter);

List<DatabaseFilterModule> beforeFilterModules = new ArrayList<>();
List<DatabaseFilterModule> afterFilterModules = new ArrayList<>();
for (int i = 0; i < filterFactories.size(); i++) {
Map<Parameter, String> filterParameters = new HashMap<>();
if (!filterFactoriesStringParameters.isEmpty()) {
filterParameters = buildParametersFromStringParameters(filterFactories.get(i),
filterFactoriesStringParameters.get(i));
try {
if (exportModuleFactory != null) {
ExportModuleContextManager.getInstance().setup(exportModuleFactory);
}

if (filterFactories.get(i).getExecutionOrder().equals(ExecutionOrder.AFTER)) {
afterFilterModules.add(filterFactories.get(i).buildFilterModule(filterParameters, reporter));
} else {
beforeFilterModules.add(filterFactories.get(i).buildFilterModule(filterParameters, reporter));
// get import module and export module instance
Map<Parameter, String> importParameters = buildParametersFromStringParameters(importModuleFactory,
importModuleFactoryStringParameters);
Map<Parameter, String> exportParameters = buildParametersFromStringParameters(exportModuleFactory,
exportModuleFactoryStringParameters);

DatabaseImportModule importModule = importModuleFactory.buildImportModule(importParameters, reporter);
DatabaseFilterModule exportModule = exportModuleFactory.buildExportModule(exportParameters, reporter);

List<DatabaseFilterModule> beforeFilterModules = new ArrayList<>();
List<DatabaseFilterModule> afterFilterModules = new ArrayList<>();
for (int i = 0; i < filterFactories.size(); i++) {
Map<Parameter, String> filterParameters = new HashMap<>();
if (!filterFactoriesStringParameters.isEmpty()) {
filterParameters = buildParametersFromStringParameters(filterFactories.get(i),
filterFactoriesStringParameters.get(i));
}

if (filterFactories.get(i).getExecutionOrder().equals(ExecutionOrder.AFTER)) {
afterFilterModules.add(filterFactories.get(i).buildFilterModule(filterParameters, reporter));
} else {
beforeFilterModules.add(filterFactories.get(i).buildFilterModule(filterParameters, reporter));
}
}
}

// set reporters
importModule.setOnceReporter(reporter);
for (DatabaseFilterModule filterModule : beforeFilterModules) {
filterModule.setOnceReporter(reporter);
}
// set reporters
importModule.setOnceReporter(reporter);
for (DatabaseFilterModule filterModule : beforeFilterModules) {
filterModule.setOnceReporter(reporter);
}

for (DatabaseFilterModule filterModule : afterFilterModules) {
filterModule.setOnceReporter(reporter);
}
for (DatabaseFilterModule filterModule : filterModules) {
filterModule.setOnceReporter(reporter);
}
exportModule.setOnceReporter(reporter);
for (DatabaseFilterModule filterModule : afterFilterModules) {
filterModule.setOnceReporter(reporter);
}
for (DatabaseFilterModule filterModule : filterModules) {
filterModule.setOnceReporter(reporter);
}
exportModule.setOnceReporter(reporter);

// create module chain with filters in the middle
Collections.reverse(filterModules);
Collections.reverse(beforeFilterModules);
Collections.reverse(afterFilterModules);
// create module chain with filters in the middle
Collections.reverse(filterModules);
Collections.reverse(beforeFilterModules);
Collections.reverse(afterFilterModules);

DatabaseFilterModule sinkModule = new SinkModule();
DatabaseFilterModule sinkModule = new SinkModule();

for (DatabaseFilterModule filterModule : afterFilterModules) {
sinkModule = filterModule.migrateDatabaseTo(sinkModule);
}
for (DatabaseFilterModule filterModule : afterFilterModules) {
sinkModule = filterModule.migrateDatabaseTo(sinkModule);
}

sinkModule = exportModule.migrateDatabaseTo(sinkModule);
sinkModule = exportModule.migrateDatabaseTo(sinkModule);

for (DatabaseFilterModule filterModule : beforeFilterModules) {
sinkModule = filterModule.migrateDatabaseTo(sinkModule);
}
for (DatabaseFilterModule filterModule : beforeFilterModules) {
sinkModule = filterModule.migrateDatabaseTo(sinkModule);
}

for (DatabaseFilterModule filterModule : filterModules) {
sinkModule = filterModule.migrateDatabaseTo(sinkModule);
}
for (DatabaseFilterModule filterModule : filterModules) {
sinkModule = filterModule.migrateDatabaseTo(sinkModule);
}

importModule.migrateDatabaseTo(sinkModule);
importModule.migrateDatabaseTo(sinkModule);
} finally {
ExportModuleContextManager.destroy();
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.databasepreservation.managers;

import com.databasepreservation.model.exception.UnsupportedModuleException;
import com.databasepreservation.model.modules.DatabaseModuleFactory;
import com.databasepreservation.model.parameters.Parameters;

/**
* @author Gabriel Barros <gbarros@keep.pt>
*/
public class ExportModuleContextManager {
private static ExportModuleContextManager instance = null;
private String moduleName;
private Parameters exportModuleParameters;

public static ExportModuleContextManager getInstance() {
if (instance == null) {
instance = new ExportModuleContextManager();
}

return instance;
}

public static void destroy() {
instance = null;
}

public void setup(DatabaseModuleFactory exportModuleFactory) throws UnsupportedModuleException {
moduleName = exportModuleFactory.getModuleName();
exportModuleParameters = exportModuleFactory.getExportModuleParameters();
}

public String getModuleName() {
return moduleName;
}

public Parameters getExportModuleParameters() {
return exportModuleParameters;
}

public boolean isSiadDKModule() {
return moduleName.contains("siard-dk");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class BinaryCell extends Cell implements InputStreamProvider {
private InputStreamProvider inputStreamProvider;
private String file;
private long length;
private String mimeType;

/**
* Creates a binary cell. This binary cell will mostly just be a wrapper around
Expand Down Expand Up @@ -75,6 +76,12 @@ public BinaryCell(String id, InputStreamProvider inputStreamProvider) {
this.inputStreamProvider = inputStreamProvider;
}

public BinaryCell(String id, InputStreamProvider inputStreamProvider, String mimeType) {
super(id);
this.inputStreamProvider = inputStreamProvider;
this.mimeType = mimeType;
}

/**
* Creates a binary cell. This binary cell is a wrapper around a
* ProvidesInputStream object (whilst also providing Cell functionality).
Expand Down Expand Up @@ -128,4 +135,12 @@ public String getFile() {
public long getLength() {
return length;
}

public String getMimeType() {
return mimeType;
}

public void setFile(String file) {
this.file = file;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public enum INPUT_TYPE {

/* GUI Helper for SIARD Export Module */
public enum CATEGORY_TYPE {
SIARD_EXPORT_OPTIONS, METADATA_EXPORT_OPTIONS, EXTERNAL_LOBS, NONE
SIARD_EXPORT_OPTIONS, METADATA_EXPORT_OPTIONS, EXTERNAL_LOBS, CONVERSION_SERVICE_OPTIONS, NONE
}

public enum FILE_FILTER_TYPE {
Expand Down Expand Up @@ -312,7 +312,9 @@ public Parameter defaultSelectedIndex(Integer index) {
return this;
}

public Integer getDefaultSelectedIndex() { return defaultSelectedIndex; }
public Integer getDefaultSelectedIndex() {
return defaultSelectedIndex;
}

/**
* Gets the export option type for this parameter; Helper to automatize the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,25 @@ public Cell handleCell(String cellId, String cellValue) throws ModuleException {
return newCell;
}

Path blobPath = basePath.resolve(cellValue);
String cellValueStripTrailing = cellValue.stripTrailing();

Path blobPath = basePath.resolve(cellValueStripTrailing);

if (Files.exists(blobPath)) {
if (Files.isRegularFile(blobPath)) {
try {
newCell = new BinaryCell(cellId, new PathInputStreamProvider(blobPath));
} catch (ModuleException e) {
reporter.ignored("Cell " + cellId,
blobPath.toString() + " ignore due to: " + e.getMessage() + "; Base path: " + this.basePath + " Cell Value: " + cellValue);
blobPath.toString() + " ignore due to: " + e.getMessage() + "; Base path: " + this.basePath + " Cell Value: " + cellValueStripTrailing);
}
} else {
reporter.ignored("Cell " + cellId,
blobPath.toString() + " is not a file; Base path: " + this.basePath + " Cell Value: " + cellValue);
blobPath.toString() + " is not a file; Base path: " + this.basePath + " Cell Value: " + cellValueStripTrailing);
}
} else {
reporter.ignored("Cell " + cellId, "Path: " + blobPath.toString() + " could not be found; Base path: "
+ this.basePath + " Cell Value: " + cellValue);
+ this.basePath + " Cell Value: " + cellValueStripTrailing);
}
return newCell;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@
import java.util.Map;
import java.util.Set;

import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.databasepreservation.managers.ExportModuleContextManager;
import com.databasepreservation.managers.ModuleConfigurationManager;
import com.databasepreservation.model.data.BinaryCell;
import com.databasepreservation.model.data.Cell;
import com.databasepreservation.model.data.NullCell;
import com.databasepreservation.model.data.Row;
Expand Down Expand Up @@ -93,12 +96,7 @@ public void handleStructure(DatabaseStructure structure) throws ModuleException

Type original = column.getType();
description.append(". Original description: '").append(original.getDescription()).append("')");
SimpleTypeBinary newType = new SimpleTypeBinary();
newType.setSql99TypeName("BINARY VARYING", 1);
newType.setSql2008TypeName("BINARY VARYING", 1);
newType.setOriginalTypeName(original.getOriginalTypeName());
newType.setOutsideDatabase(true);

SimpleTypeBinary newType = getSimpleTypeBinary(original);
column.setType(newType);
column.setDescription(description.toString());
}
Expand All @@ -110,6 +108,21 @@ public void handleStructure(DatabaseStructure structure) throws ModuleException
this.exportModule.handleStructure(structure);
}

@NotNull
private static SimpleTypeBinary getSimpleTypeBinary(Type original) {
SimpleTypeBinary newType = new SimpleTypeBinary();
if (ExportModuleContextManager.getInstance().isSiadDKModule()) {
newType.setSql99TypeName("BINARY LARGE OBJECT");
newType.setSql2008TypeName("BINARY LARGE OBJECT");
} else {
newType.setSql99TypeName("BINARY VARYING", 1);
newType.setSql2008TypeName("BINARY VARYING", 1);
}
newType.setOriginalTypeName(original.getOriginalTypeName());
newType.setOutsideDatabase(true);
return newType;
}

@Override
public void handleDataOpenSchema(String schemaName) throws ModuleException {
this.exportModule.handleDataOpenSchema(schemaName);
Expand Down Expand Up @@ -155,6 +168,9 @@ public void handleDataRow(Row row) throws ModuleException {
.get(currentTable.getId() + index);
Cell newCell = getExternalLOBSCellHandler(externalLobsConfiguration).handleCell(cell.getId(),
simpleCell.getSimpleData());
if (newCell instanceof BinaryCell binaryCell) {
binaryCell.setFile(simpleCell.getSimpleData());
}
rowCells.set(index, newCell);
} else {
reporter.ignored("Cell " + cell.getId(), "reference to external LOB is null");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ protected void handleSimpleTypeStringDataCell(String data, PreparedStatement ps,

protected void handleSimpleTypeNumericExactDataCell(String data, PreparedStatement ps, int index, Cell cell,
ColumnStructure column) throws SQLException {
if (data != null) {
if (data != null && !data.isEmpty()) {
BigDecimal bd = new BigDecimal(data);
ps.setBigDecimal(index, bd);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public String escapeSchemaName(String schema) {

@Override
public String escapeTableName(String table) {
return getStartQuote() + table + getEndQuote();
return getStartQuote() + StringUtils.strip(table, "\"") + getEndQuote();
}

/**
Expand Down
Loading
Loading