Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
42 changes: 42 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/api/Datasets.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@
import jakarta.ejb.EJB;
import jakarta.ejb.EJBException;
import jakarta.inject.Inject;
import jakarta.json.Json;
import jakarta.json.JsonArrayBuilder;
import jakarta.json.JsonObjectBuilder;
import jakarta.json.*;
import jakarta.json.stream.JsonParsingException;
import jakarta.servlet.http.HttpServletRequest;
Expand Down Expand Up @@ -5192,6 +5195,45 @@ public Response getExternalToolDVParams(@Context ContainerRequestContext crc,
}
}

/**
* Public endpoint: list dataset-scope external tools applicable to a dataset, with toolUrlWithQueryParams resolved.
* Example: GET /api/datasets/{id}/externalTools?type=explore
* If the request is authenticated, callback URLs for tools that declare allowedApiCalls will be signed.
*/
@GET
@Path("{id}/externalTools")
public Response getDatasetExternalTools(@Context ContainerRequestContext crc,
@PathParam("id") String idSupplied,
@QueryParam("type") String typeSupplied,
@QueryParam("locale") String locale) {
ExternalTool.Type type;
try {
type = ExternalTool.Type.fromString(typeSupplied);
} catch (IllegalArgumentException ex) {
return error(BAD_REQUEST, ex.getLocalizedMessage());
}
try {
Dataset dataset = findDatasetOrDie(idSupplied);

ApiToken apiToken = null;
User user = getRequestUser(crc);
apiToken = authSvc.getValidApiTokenForUser(user);

String localeCode = (locale != null && !locale.isBlank()) ? locale : null;

JsonArrayBuilder tools = Json.createArrayBuilder();
List<ExternalTool> datasetTools = externalToolService.findDatasetToolsByType(type);
for (ExternalTool tool : datasetTools) {
ExternalToolHandler externalToolHandler = new ExternalToolHandler(tool, dataset, apiToken, localeCode);
JsonObjectBuilder toolToJson = externalToolService.getToolAsJsonWithQueryParameters(externalToolHandler);
tools.add(toolToJson);
}
return ok(tools);
} catch (WrappedResponse wr) {
return wr.getResponse();
}
}

@GET
@Path("summaryFieldNames")
public Response getDatasetSummaryFieldNames() {
Expand Down
53 changes: 53 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/api/Files.java
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,59 @@ public Response getExternalToolFMParams(@Context ContainerRequestContext crc, @P
eth = new ExternalToolHandler(externalTool, target.getDataFile(), apiToken, target, locale);
return ok(eth.createPostBody(eth.getParams(JsonUtil.getJsonObject(externalTool.getToolParameters())), JsonUtil.getJsonArray(externalTool.getAllowedApiCalls())));
}

/**
* Public: return all external tools applicable to a file (by its content type and requirements), each with toolUrlWithQueryParams resolved.
* Example: GET /api/files/{id}/externalTools?type=preview|explore|query[&fileMetadataId=...][&locale=en]
*/
@GET
@Path("{id}/externalTools")
public Response getFileExternalTools(@Context ContainerRequestContext crc,
@PathParam("id") String idSupplied,
@QueryParam("type") String typeSupplied,
@QueryParam("fileMetadataId") Long fileMetadataId,
@QueryParam("locale") String locale) {
ExternalTool.Type type;
try {
type = ExternalTool.Type.fromString(typeSupplied);
} catch (IllegalArgumentException ex) {
return error(BAD_REQUEST, ex.getLocalizedMessage());
}
try {
DataFile dataFile = findDataFileOrDie(idSupplied);

// Resolve FileMetadata context
FileMetadata fm = null;
if (fileMetadataId != null) {
fm = fileSvc.findFileMetadata(fileMetadataId);
if (fm == null) {
return error(BAD_REQUEST, "FileMetadata not found for id " + fileMetadataId);
}
} else {
fm = dataFile.getFileMetadata();
}

ApiToken apiToken = null;
User user = getRequestUser(crc);
apiToken = authSvc.getValidApiTokenForUser(user);

String localeCode = (locale != null && !locale.isBlank()) ? locale : null;

// Get all tools of the requested type, then filter by file using service logic (handles tabular/TSV_ALT, requirements, storage access)
List<ExternalTool> typeTools = externalToolService.findFileToolsByType(type);
List<ExternalTool> applicable = externalToolService.findExternalToolsByFile(typeTools, dataFile);

JsonArrayBuilder tools = Json.createArrayBuilder();
for (ExternalTool tool : applicable) {
ExternalToolHandler handler = new ExternalToolHandler(tool, dataFile, apiToken, fm, localeCode);
JsonObjectBuilder toolJson = externalToolService.getToolAsJsonWithQueryParameters(handler);
tools.add(toolJson);
}
return ok(tools);
} catch (WrappedResponse wr) {
return wr.getResponse();
}
}

@GET
@Path("fixityAlgorithm")
Expand Down
Loading