Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
e37526d
refactor(export): modularize ExportService by introducing ExporterReg…
poikilotherm Aug 7, 2026
83a8477
refactor(export): make ExportService a @Stateless EJB bean #12686
poikilotherm Aug 7, 2026
d466317
feat(export): introduce new ExportCache subsystem with cache key, inv…
poikilotherm Aug 7, 2026
8a7a5e4
refactor(export): extract file embargo expiry logic from ExportServic…
poikilotherm Aug 7, 2026
be3aeea
refactor(export): move caching logic from ExportService to new Storag…
poikilotherm Aug 7, 2026
8dfdda4
refactor(export): remove legacy unversioned cache logic from StorageI…
poikilotherm Aug 7, 2026
883e438
feat(export): enhance ExportCacheKey with validation and convenience …
poikilotherm Aug 7, 2026
105ba09
refactor(export): relocate service and provider classes to `export.se…
poikilotherm Aug 7, 2026
206c07e
docs(export): add Javadoc to private helpers in StorageIOCache #12686
poikilotherm Aug 18, 2026
7d48a93
refactor(export): move invalidators list from ExportCacheInvalidator …
poikilotherm Aug 18, 2026
60d953f
style(export): rename `exporterRegistry` field to `registry` in Expor…
poikilotherm Aug 18, 2026
9bbec86
feat(export): make ExportCache instance available in service #12686
poikilotherm Aug 18, 2026
38f3243
refactor(export): make cache clearing version-aware #12686
poikilotherm Aug 18, 2026
beefa7b
style(export): move export trigger service methods next to each other…
poikilotherm Aug 18, 2026
c747540
feat(export): add prerequisite dependency verification to ExporterReg…
poikilotherm Aug 19, 2026
642685b
feat(export): cache formatRequiredBy map in ExporterRegistryBean #12686
poikilotherm Aug 19, 2026
357528c
feat(export): add topological comparator to ExporterRegistryBean #12686
poikilotherm Aug 19, 2026
a8f422d
feat(util,export): enforce owner-only permissions on export temp file…
poikilotherm Aug 19, 2026
f3d21d4
fix(export): decouple ExportCacheKey from JPA entities #12686
poikilotherm Aug 20, 2026
aa5c787
refactor(export): replace depth-based comparator with transitive depe…
poikilotherm Aug 20, 2026
34aecb4
refactor(export): replace Labels record with sealed Details interface…
poikilotherm Aug 21, 2026
b59f4af
style(export): convert field comments to block comment style for read…
poikilotherm Aug 21, 2026
1a7c079
refactor(export): store formatName and friendlyVersion again as Expor…
poikilotherm Aug 21, 2026
709198a
refactor(export): remove obsolete exporter lookup methods from Export…
poikilotherm Aug 21, 2026
cfc60d9
fix(export): guard against null formatName in ExporterRegistryBean#ge…
poikilotherm Aug 21, 2026
0399135
feat(util): add FailureEscalation for threshold-based log level escal…
poikilotherm Aug 21, 2026
a4446ec
docs(export): correct legacy cache name behavior in StorageIOCache Ja…
poikilotherm Aug 21, 2026
e1d6642
feat(export): apply FailureEscalation to StorageIOCache log levels #1…
poikilotherm Aug 21, 2026
57e0f0b
feat(export): add ExportPipelineBean as central export orchestration …
poikilotherm Aug 21, 2026
8a49f74
refactor(export): introduce ExportPipelineBean to ExportServiceBean #…
poikilotherm Aug 21, 2026
c7900cb
feat(export): add isCacheable helper centralizing version cache polic…
poikilotherm Aug 21, 2026
4424bc1
refactor(export): rework exportFormats to use pipeline and topologica…
poikilotherm Aug 21, 2026
6ecdba8
refactor(export): delegate ExportService.getExport to ExportPipeline …
poikilotherm Aug 21, 2026
23b31b8
docs(export): note limitations of naive staleness invalidation #12686
poikilotherm Aug 21, 2026
d01ac8b
refactor(commands): replace ExportService.getInstance() with CommandC…
poikilotherm Aug 21, 2026
721c348
refactor(oai): introduce new export service beans #12686
poikilotherm Aug 21, 2026
74fdcb9
refactor(api): introduce export beans at API base infrastructure and …
poikilotherm Aug 21, 2026
4e73e16
refactor(signposting): use export service and registry beans #12686
poikilotherm Aug 21, 2026
75b616c
refactor(ui): use export service and registry beans in FilePage #12686
poikilotherm Aug 21, 2026
cebe87b
refactor(dataset): ask export service directly for dataset aux storag…
poikilotherm Aug 26, 2026
81f72c3
refactor(export): simplify getLatestPublishedAsString with new pipeli…
poikilotherm Aug 26, 2026
d94c10e
refactor(ui): use export service bean in DatasetPage #12686
poikilotherm Aug 26, 2026
13f92b2
docs(export): clarify stream-handling caveats in cached export path #…
poikilotherm Aug 26, 2026
8a76549
refactor(api): use new export service in Datasets API #12686
poikilotherm Aug 26, 2026
cea4534
refactor(export): add createProvider factory for test usage #12686
poikilotherm Sep 2, 2026
f69b8ce
refactor(export): add datasetId context scope to ExportCacheKey #12686
poikilotherm Sep 2, 2026
c7134a1
test(export): add unit tests for ExportCacheKey #12686
poikilotherm Sep 2, 2026
ef51d16
style(export): use lambda for fine-level cache export #12686
poikilotherm Sep 4, 2026
45a5f59
test(export): add unit tests for `StorageIOCache` functionality #12686
poikilotherm Sep 4, 2026
ad87fa4
style: fix leftover invalid imports from git merge
poikilotherm Sep 9, 2026
cbfffc3
refactor(export): increase testability of invalidator handling in Exp…
poikilotherm Sep 9, 2026
a8bb8b8
refactor(export): update `ExportPipelineBean` visibility to public as…
poikilotherm Sep 9, 2026
564d52b
test(export): add unit tests for `ExportPipelineBean` functionality #…
poikilotherm Sep 9, 2026
542506a
refactor(export): unseal `ExportCacheInvalidator` to allow extension …
poikilotherm Sep 9, 2026
421dd44
refactor(export): improve testability of `ExporterRegistryBean` with …
poikilotherm Sep 9, 2026
d4c33e8
test(export): add unit tests for `ExporterRegistryBean` functionality…
poikilotherm Sep 9, 2026
1d952fe
refactor(export): enhance cache eviction logic and improve format han…
poikilotherm Sep 10, 2026
d5b5891
refactor(export): move transitive dependent format expansion logic to…
poikilotherm Sep 10, 2026
b79bcf4
refactor(export): enrich eviction failure exception message with form…
poikilotherm Sep 10, 2026
0e95922
docs(export): fix Javadocs on clearCachedFormats #12686
poikilotherm Sep 10, 2026
751725b
refactor(export): improve `clearCachedFormats` null-check logic and a…
poikilotherm Sep 10, 2026
e6db1a5
fix(export): unseal `ExportCache` to enable EJB proxy classes
poikilotherm Sep 10, 2026
a0863ca
fix(export): improve logging for external exporter JAR access excepti…
poikilotherm Sep 10, 2026
d49c069
refactor(export): migrate `ExportPipelineBean` from EJB to CDI with c…
poikilotherm Sep 10, 2026
feb3f42
doc(export): clarify Javadocs for export methods they cache but don't…
poikilotherm Sep 10, 2026
529702c
Merge branch 'develop' into 12686-enhance-export-subsys
poikilotherm Sep 11, 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
55 changes: 21 additions & 34 deletions src/main/java/edu/harvard/iq/dataverse/DatasetPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,11 @@
import edu.harvard.iq.dataverse.engine.command.impl.PublishDatasetCommand;
import edu.harvard.iq.dataverse.engine.command.impl.PublishDataverseCommand;
import edu.harvard.iq.dataverse.engine.command.impl.UpdateDatasetVersionCommand;
import edu.harvard.iq.dataverse.export.ExportService;
import edu.harvard.iq.dataverse.settings.FeatureFlags;
import edu.harvard.iq.dataverse.export.service.ExportServiceBean;
import edu.harvard.iq.dataverse.export.service.ExporterRegistryBean;
import edu.harvard.iq.dataverse.util.cache.CacheFactoryBean;
import edu.harvard.iq.dataverse.util.json.JsonUtil;
import io.gdcc.spi.export.ExportException;
import io.gdcc.spi.export.Exporter;
import edu.harvard.iq.dataverse.ingest.IngestRequest;
import edu.harvard.iq.dataverse.ingest.IngestServiceBean;
import edu.harvard.iq.dataverse.license.LicenseServiceBean;
Expand Down Expand Up @@ -105,7 +104,6 @@
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.json.Json;
import jakarta.json.JsonObject;
import jakarta.json.JsonObjectBuilder;
import jakarta.persistence.OptimisticLockException;
Expand Down Expand Up @@ -255,6 +253,10 @@
DvObjectServiceBean dvObjectService;
@EJB
CacheFactoryBean cacheFactory;
@EJB
ExportServiceBean exportService;

Check failure on line 257 in src/main/java/edu/harvard/iq/dataverse/DatasetPage.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make non-static "exportService" transient or serializable.

See more on https://sonarcloud.io/project/issues?id=IQSS_dataverse&issues=AaCLqIx9069oWOY1zgim&open=AaCLqIx9069oWOY1zgim&pullRequest=12688
@EJB
ExporterRegistryBean exporterRegistryService;

Check failure on line 259 in src/main/java/edu/harvard/iq/dataverse/DatasetPage.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make non-static "exporterRegistryService" transient or serializable.

See more on https://sonarcloud.io/project/issues?id=IQSS_dataverse&issues=AaCLqIx9069oWOY1zgin&open=AaCLqIx9069oWOY1zgin&pullRequest=12688
@Inject
DataverseRequestServiceBean dvRequestService;
@Inject
Expand Down Expand Up @@ -4898,31 +4900,18 @@
}

public List< String[]> getExporters(){
List<String[]> retList = new ArrayList<>();
String myHostURL = getDataverseSiteUrl();
for (String [] provider : ExportService.getInstance().getExportersLabels() ){
String formatName = provider[1];
String formatDisplayName = provider[0];

Exporter exporter = null;
try {
exporter = ExportService.getInstance().getExporter(formatName);
} catch (ExportException ex) {
logger.warning("Failed to get : " + formatName);
logger.warning(ex.getLocalizedMessage());
exporter = null;
}
if (exporter != null && exporter.isAvailableToUsers()) {
// Not all metadata exports should be presented to the web users!
// Some are only for harvesting clients.

String[] temp = new String[2];
temp[0] = formatDisplayName;
temp[1] = myHostURL + "/api/datasets/export?exporter=" + formatName + "&persistentId=" + dataset.getGlobalId().asString();
retList.add(temp);
}
}
return retList;
String urlTemplate = getDataverseSiteUrl() + "/api/datasets/export?exporter=%s&persistentId=%s";

return exporterRegistryService.getDetails().stream()
.filter(ExporterRegistryBean.Details::isAvailableToUsers)
.map(details -> new String[]{
details.localizedDisplayName(),
urlTemplate.formatted(
details.formatName(),
dataset.getGlobalId().asString()
)
})
.toList();
}


Expand Down Expand Up @@ -6136,8 +6125,7 @@
// The full version is available from the "Export Metadata" dropdown.
// Both versions are available via API.
final String CROISSANT_SCHEMA_NAME = "croissantSlim";
ExportService instance = ExportService.getInstance();
String croissant = instance.getLatestPublishedAsString(dataset, CROISSANT_SCHEMA_NAME);
String croissant = exportService.getLatestPublishedAsString(dataset, CROISSANT_SCHEMA_NAME);
if (FeatureFlags.CROISSANT_WITH_LOCAL_REVIEWS.enabled()) {
// Rewrite the export on the fly and insert local reviews until we have a solution for https://github.com/gdcc/dataverse-spi/issues/5
JsonObjectBuilder reviewsJsonObj = null;
Expand Down Expand Up @@ -6169,8 +6157,7 @@

public String getJsonLd() {
if (isThisLatestReleasedVersion()) {
ExportService instance = ExportService.getInstance();
String jsonLd = instance.getLatestPublishedAsString(dataset, SchemaDotOrgExporter.NAME);
String jsonLd = exportService.getLatestPublishedAsString(dataset, SchemaDotOrgExporter.NAME);
if (jsonLd != null) {
logger.fine("Returning cached schema.org JSON-LD.");
return jsonLd;
Expand Down Expand Up @@ -7019,7 +7006,7 @@
return null;
}
if (signpostingLinkHeader == null) {
SignpostingResources sr = new SignpostingResources(systemConfig, workingVersion,
SignpostingResources sr = new SignpostingResources(systemConfig, exporterRegistryService, workingVersion,
JvmSettings.SIGNPOSTING_LEVEL1_AUTHOR_LIMIT.lookupOptional().orElse(""),
JvmSettings.SIGNPOSTING_LEVEL1_ITEM_LIMIT.lookupOptional().orElse(""));
signpostingLinkHeader = sr.getLinks();
Expand Down
18 changes: 8 additions & 10 deletions src/main/java/edu/harvard/iq/dataverse/DatasetServiceBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import edu.harvard.iq.dataverse.authorization.Permission;
import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser;
import edu.harvard.iq.dataverse.authorization.users.User;
import edu.harvard.iq.dataverse.dataaccess.DataAccess;

Check warning on line 8 in src/main/java/edu/harvard/iq/dataverse/DatasetServiceBean.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this unused import 'edu.harvard.iq.dataverse.dataaccess.DataAccess'.

See more on https://sonarcloud.io/project/issues?id=IQSS_dataverse&issues=AaCLqI0l069oWOY1zgis&open=AaCLqI0l069oWOY1zgis&pullRequest=12688
import edu.harvard.iq.dataverse.dataaccess.ImageThumbConverter;
import edu.harvard.iq.dataverse.dataaccess.StorageIO;
import edu.harvard.iq.dataverse.dataset.DatasetUtil;
Expand All @@ -16,7 +16,7 @@
import edu.harvard.iq.dataverse.engine.command.impl.DestroyDatasetCommand;
import edu.harvard.iq.dataverse.engine.command.impl.FinalizeDatasetPublicationCommand;
import edu.harvard.iq.dataverse.engine.command.impl.GetDatasetStorageSizeCommand;
import edu.harvard.iq.dataverse.export.ExportService;
import edu.harvard.iq.dataverse.export.service.ExportServiceBean;
import edu.harvard.iq.dataverse.globus.GlobusServiceBean;
import edu.harvard.iq.dataverse.harvest.server.OAIRecordServiceBean;
import edu.harvard.iq.dataverse.pidproviders.FailedPIDResolutionLoggingServiceBean;
Expand Down Expand Up @@ -103,6 +103,9 @@

@EJB
UserNotificationServiceBean userNotificationService;

@EJB
ExportServiceBean exportService;

Check failure on line 108 in src/main/java/edu/harvard/iq/dataverse/DatasetServiceBean.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make non-static "exportService" transient or serializable.

See more on https://sonarcloud.io/project/issues?id=IQSS_dataverse&issues=AaCLqI0l069oWOY1zgir&open=AaCLqI0l069oWOY1zgir&pullRequest=12688

private static final SimpleDateFormat logFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH-mm-ss");

Expand Down Expand Up @@ -1081,15 +1084,10 @@
if (countCachedExtras) {
// count the sizes of the files cached for the dataset itself
// (i.e., the metadata exports):
StorageIO<Dataset> datasetSIO = DataAccess.getStorageIO(dataset);

for (String[] exportProvider : ExportService.getInstance().getExportersLabels()) {
String exportLabel = "export_" + exportProvider[1] + ".cached";
try {
total += datasetSIO.getAuxObjectSize(exportLabel);
} catch (IOException ioex) {
// safe to ignore; object not cached
}
try {
total += exportService.usedCacheStorage(dataset);
} catch (IOException ioex) {
// safe to ignore; object not cached
}
}

Expand Down
20 changes: 19 additions & 1 deletion src/main/java/edu/harvard/iq/dataverse/EjbDataverseEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import edu.harvard.iq.dataverse.authorization.AuthenticationServiceBean;
import edu.harvard.iq.dataverse.authorization.providers.builtin.BuiltinUserServiceBean;
import edu.harvard.iq.dataverse.dataverse.featured.DataverseFeaturedItemServiceBean;
import edu.harvard.iq.dataverse.export.service.ExportServiceBean;
import edu.harvard.iq.dataverse.export.service.ExporterRegistryBean;
import edu.harvard.iq.dataverse.license.LicenseServiceBean;
import edu.harvard.iq.dataverse.util.cache.CacheFactoryBean;
import edu.harvard.iq.dataverse.engine.DataverseEngine;
Expand Down Expand Up @@ -209,6 +211,12 @@ public class EjbDataverseEngine {
@EJB
CacheFactoryBean cacheFactory;

@EJB
ExportServiceBean exportService;

@EJB
ExporterRegistryBean exporterRegistry;

@Resource
EJBContext ejbCtxt;

Expand Down Expand Up @@ -664,7 +672,17 @@ public MetadataBlockServiceBean metadataBlocks() {
public DatasetTypeServiceBean datasetTypes() {
return datasetTypeService;
}


@Override
public ExportServiceBean exportService() {
return exportService;
}

@Override
public ExporterRegistryBean exporterRegistry() {
return exporterRegistry;
}

@Override
public void beginCommandSequence() {
this.commandsCalled = new Stack();
Expand Down
54 changes: 22 additions & 32 deletions src/main/java/edu/harvard/iq/dataverse/FilePage.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@
import edu.harvard.iq.dataverse.engine.command.impl.RestrictFileCommand;
import edu.harvard.iq.dataverse.engine.command.impl.UningestFileCommand;
import edu.harvard.iq.dataverse.engine.command.impl.UpdateDatasetVersionCommand;
import edu.harvard.iq.dataverse.export.ExportService;
import edu.harvard.iq.dataverse.export.service.ExportServiceBean;
import edu.harvard.iq.dataverse.export.service.ExporterRegistryBean;
import edu.harvard.iq.dataverse.export.service.ExporterRegistryBean.Details;
import io.gdcc.spi.export.ExportException;
import io.gdcc.spi.export.Exporter;
import edu.harvard.iq.dataverse.externaltools.ExternalTool;
import edu.harvard.iq.dataverse.externaltools.ExternalToolHandler;
import edu.harvard.iq.dataverse.externaltools.ExternalToolServiceBean;
Expand All @@ -36,7 +37,6 @@
import edu.harvard.iq.dataverse.makedatacount.MakeDataCountLoggingServiceBean;
import edu.harvard.iq.dataverse.makedatacount.MakeDataCountLoggingServiceBean.MakeDataCountEntry;
import edu.harvard.iq.dataverse.privateurl.PrivateUrlServiceBean;
import edu.harvard.iq.dataverse.settings.FeatureFlags;
import edu.harvard.iq.dataverse.settings.JvmSettings;
import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
import edu.harvard.iq.dataverse.util.BundleUtil;
Expand Down Expand Up @@ -64,7 +64,6 @@
import jakarta.faces.application.FacesMessage;
import jakarta.faces.component.UIComponent;
import jakarta.faces.context.FacesContext;
import jakarta.faces.validator.ValidatorException;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
Expand Down Expand Up @@ -129,6 +128,10 @@
IngestServiceBean ingestService;
@EJB
SystemConfig systemConfig;
@EJB
ExportServiceBean exportService;

Check failure on line 132 in src/main/java/edu/harvard/iq/dataverse/FilePage.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make non-static "exportService" transient or serializable.

See more on https://sonarcloud.io/project/issues?id=IQSS_dataverse&issues=AaCLqIzb069oWOY1zgio&open=AaCLqIzb069oWOY1zgio&pullRequest=12688
@EJB
ExporterRegistryBean exporterRegistryService;

Check failure on line 134 in src/main/java/edu/harvard/iq/dataverse/FilePage.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make non-static "exporterRegistryService" transient or serializable.

See more on https://sonarcloud.io/project/issues?id=IQSS_dataverse&issues=AaCLqIzb069oWOY1zgip&open=AaCLqIzb069oWOY1zgip&pullRequest=12688


@Inject
Expand Down Expand Up @@ -466,30 +469,19 @@
this.version = version;
}

public List< String[]> getExporters(){
List<String[]> retList = new ArrayList<>();
String myHostURL = systemConfig.getDataverseSiteUrl();
for (String [] provider : ExportService.getInstance().getExportersLabels() ){
String formatName = provider[1];
String formatDisplayName = provider[0];

Exporter exporter = null;
try {
exporter = ExportService.getInstance().getExporter(formatName);
} catch (ExportException ex) {
exporter = null;
}
if (exporter != null && exporter.isAvailableToUsers()) {
// Not all metadata exports should be presented to the web users!
// Some are only for harvesting clients.

String[] temp = new String[2];
temp[0] = formatDisplayName;
temp[1] = myHostURL + "/api/datasets/export?exporter=" + formatName + "&persistentId=" + fileMetadata.getDatasetVersion().getDataset().getGlobalId().asString();
retList.add(temp);
}
}
return retList;
public List<String[]> getExporters(){
String urlTemplate = systemConfig.getDataverseSiteUrl() + "/api/datasets/export?exporter=%s&persistentId=%s";

return exporterRegistryService.getDetails().stream()
.filter(Details::isAvailableToUsers)
.map(details -> new String[]{
details.localizedDisplayName(),
urlTemplate.formatted(
details.formatName(),
fileMetadata.getDatasetVersion().getDataset().getGlobalId().asString()
)
})
.toList();
}

public String saveProvFreeform(String freeformTextInput, DataFile dataFileFromPopup) throws CommandException {
Expand Down Expand Up @@ -640,15 +632,13 @@
editDataset = file.getOwner();
if (editDataset.isReleased()) {
try {
ExportService instance = ExportService.getInstance();
instance.exportAllFormats(editDataset);

exportService.exportAllFormats(editDataset);
} catch (ExportException ex) {
// Something went wrong!
// Just like with indexing, a failure to export is not a fatal
// condition. We'll just log the error as a warning and keep
// going:
logger.log(Level.WARNING, "Uningest: Exception while exporting:{0}", ex.getMessage());
logger.log(Level.WARNING, "Uningest: Exception while exporting: {0}", ex);

Check warning on line 641 in src/main/java/edu/harvard/iq/dataverse/FilePage.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Not enough arguments.

See more on https://sonarcloud.io/project/issues?id=IQSS_dataverse&issues=AaCLqIzb069oWOY1zgiq&open=AaCLqIzb069oWOY1zgiq&pullRequest=12688
}
}
datafileService.save(file);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import edu.harvard.iq.dataverse.engine.command.impl.GetLatestAccessibleDatasetVersionCommand;
import edu.harvard.iq.dataverse.engine.command.impl.GetLatestPublishedDatasetVersionCommand;
import edu.harvard.iq.dataverse.engine.command.impl.GetSpecificPublishedDatasetVersionCommand;
import edu.harvard.iq.dataverse.export.service.ExportServiceBean;
import edu.harvard.iq.dataverse.export.service.ExporterRegistryBean;
import edu.harvard.iq.dataverse.externaltools.ExternalToolServiceBean;
import edu.harvard.iq.dataverse.license.LicenseServiceBean;
import edu.harvard.iq.dataverse.makedatacount.DatasetMetricsServiceBean;
Expand Down Expand Up @@ -246,6 +248,12 @@ String getWrappedMessageWhenJson() {

@EJB
TemplateServiceBean templateSvc;

@EJB
ExportServiceBean exportSvc;

@EJB
ExporterRegistryBean exporterRegistrySvc;

@Inject
FailedPIDResolutionLoggingServiceBean fprLogService;
Expand Down
35 changes: 19 additions & 16 deletions src/main/java/edu/harvard/iq/dataverse/api/Datasets.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
import edu.harvard.iq.dataverse.engine.command.exception.PermissionException;
import edu.harvard.iq.dataverse.engine.command.exception.UnforcedCommandException;
import edu.harvard.iq.dataverse.engine.command.impl.*;
import edu.harvard.iq.dataverse.export.ExportService;
import edu.harvard.iq.dataverse.export.croissant.CroissantExportUtil;
import edu.harvard.iq.dataverse.export.service.ExporterRegistryBean.Details;
import edu.harvard.iq.dataverse.externaltools.ExternalTool;
import edu.harvard.iq.dataverse.externaltools.ExternalToolHandler;
import edu.harvard.iq.dataverse.globus.GlobusServiceBean;
Expand Down Expand Up @@ -251,9 +251,11 @@
@Produces({"application/xml", "application/json", "application/html", "application/ld+json", "*/*" })
@Operation(summary = "Export dataset metadata",
description = "Exports dataset metadata by persistent id using the requested version and exporter.")
public Response exportDataset(@Context ContainerRequestContext crc, @Parameter(description = "Persistent identifier.") @QueryParam("persistentId") String persistentId,
@Parameter(description = "Dataset version selector.") @QueryParam("version") String versionId, @Parameter(description = "Exporter option.") @QueryParam("exporter") String exporter,
@Context UriInfo uriInfo, @Context HttpHeaders headers, @Context HttpServletResponse response) {
public Response exportDataset(
@Context ContainerRequestContext crc, @Context UriInfo uriInfo, @Context HttpHeaders headers, @Context HttpServletResponse response,
@QueryParam("persistentId") @Parameter(description = "Persistent identifier.") String persistentId,
@QueryParam("version") @Parameter(description = "Dataset version selector.") String versionId,
@QueryParam("exporter") @Parameter(description = "Exporter option.") String exporter) {

try {
Dataset dataset = datasetService.findByGlobalId(persistentId);
Expand Down Expand Up @@ -285,10 +287,13 @@
return error(BAD_REQUEST, "Non-draft version requested (" + versionId + ") but for published versions only the latest (" + DS_VERSION_LATEST_PUBLISHED + ") is supported.");
}
}

ExportService instance = ExportService.getInstance();

InputStream is = instance.getExport(datasetVersion, exporter);

Optional<Details> exporterDetails = exporterRegistrySvc.getDetail(exporter);
if (exporterDetails.isEmpty()) {
return error(BAD_REQUEST, "Export failed: no exporter registered for format name " + exporter);
}

InputStream is = exportSvc.getExport(datasetVersion, exporter);
if (FeatureFlags.CROISSANT_WITH_LOCAL_REVIEWS.enabled()
&& (exporter.equals("croissant") || exporter.equals("croissantSlim"))) {
// Rewrite the export on the fly and insert local reviews until we have a solution for https://github.com/gdcc/dataverse-spi/issues/5
Expand All @@ -300,18 +305,16 @@
.add("reviews", reviews.build().getJsonArray("reviews")).build().toString();
is = new ByteArrayInputStream(updatedContent.getBytes(StandardCharsets.UTF_8));
}

String mediaType = instance.getMediaType(exporter);


if (datasetVersion.isReleased()) {
MakeDataCountLoggingServiceBean.MakeDataCountEntry entry = new MakeDataCountEntry(uriInfo, headers, dvRequestService, dataset);
mdcLogService.logEntry(entry);
}

return Response.ok()
.entity(is)
.type(mediaType).
build();
.entity(is)
.type(exporterDetails.get().mediaType()).
build();
} catch (Exception wr) {
logger.warning(wr.getMessage());
return error(Response.Status.FORBIDDEN, "Export Failed");
Expand Down Expand Up @@ -801,7 +804,7 @@
return Response
.ok(JsonUtil.createObjectBuilder()
.add("linkset",
new SignpostingResources(systemConfig, dsv,
new SignpostingResources(systemConfig, exporterRegistrySvc, dsv,
JvmSettings.SIGNPOSTING_LEVEL1_AUTHOR_LIMIT.lookupOptional().orElse(""),
JvmSettings.SIGNPOSTING_LEVEL1_ITEM_LIMIT.lookupOptional().orElse(""))
.getJsonLinkset())
Expand Down Expand Up @@ -1997,7 +2000,7 @@

// dateAvailable is within limits
if (minRetentionDateTime != null){
if (dateUnavailable.isBefore(minRetentionDateTime.minusDays(1))){

Check warning on line 2003 in src/main/java/edu/harvard/iq/dataverse/api/Datasets.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Merge this if statement with the enclosing one.

See more on https://sonarcloud.io/project/issues?id=IQSS_dataverse&issues=AaCLqIbn069oWOY1zgiF&open=AaCLqIbn069oWOY1zgiF&pullRequest=12688
return error(Status.BAD_REQUEST, "Date unavailable can not be earlier than MinRetentionDurationInMonths: "+minRetentionDurationInMonths + " from now");
}
}
Expand Down
Loading
Loading