diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
index ce99efb778..591217510d 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/CI.yml
@@ -37,7 +37,7 @@ jobs:
ports:
- 1025:1025
openldap:
- image: docker.io/bitnami/openldap:2.6
+ image: docker.io/bitnamilegacy/openldap:2.6
ports:
- 1389:1389
- 1636:1636
diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml
index ee18b8ae3e..e369c94268 100644
--- a/.github/workflows/development.yml
+++ b/.github/workflows/development.yml
@@ -36,7 +36,7 @@ jobs:
POSTGRES_PASSWORD: roda
POSTGRES_DB: roda_core_db
openldap:
- image: docker.io/bitnami/openldap:2.6
+ image: docker.io/bitnamilegacy/openldap:2.6
ports:
- 1389:1389
- 1636:1636
diff --git a/.github/workflows/latest.yml b/.github/workflows/latest.yml
index 9d793515aa..287fa755a6 100644
--- a/.github/workflows/latest.yml
+++ b/.github/workflows/latest.yml
@@ -36,7 +36,7 @@ jobs:
ports:
- 1025:1025
openldap:
- image: docker.io/bitnami/openldap:2.6
+ image: docker.io/bitnamilegacy/openldap:2.6
ports:
- 1389:1389
- 1636:1636
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index c915f1502a..ec256989c7 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -38,7 +38,7 @@ jobs:
ports:
- 1025:1025
openldap:
- image: docker.io/bitnami/openldap:2.6
+ image: docker.io/bitnamilegacy/openldap:2.6
ports:
- 1389:1389
- 1636:1636
@@ -142,8 +142,8 @@ jobs:
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
- file: roda-ui/roda-wui/target/roda-wui-${{ env.release_version }}.war
- asset_name: roda-wui-${{ env.release_version }}.war
+ file: roda-ui/roda-wui/target/roda-wui-${{ env.release_version }}.jar
+ asset_name: roda-wui-${{ env.release_version }}.jar
tag: ${{ github.ref }}
release_name: ${{ github.ref_name }}
draft: true
diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml
index 7593e4edf3..d4c70baa07 100644
--- a/.github/workflows/staging.yml
+++ b/.github/workflows/staging.yml
@@ -36,7 +36,7 @@ jobs:
ports:
- 1025:1025
openldap:
- image: docker.io/bitnami/openldap:2.6
+ image: docker.io/bitnamilegacy/openldap:2.6
ports:
- 1389:1389
- 1636:1636
diff --git a/deploys/standalone/docker-compose-dev.yaml b/deploys/standalone/docker-compose-dev.yaml
index b8aeb079ce..ecd695b152 100644
--- a/deploys/standalone/docker-compose-dev.yaml
+++ b/deploys/standalone/docker-compose-dev.yaml
@@ -79,7 +79,7 @@ services:
- "8025:8025" # web ui
openldap:
- image: docker.io/bitnami/openldap:2.6
+ image: docker.io/bitnamilegacy/openldap:2.6
container_name: openldap
restart: unless-stopped
user: 1001:root
diff --git a/pom.xml b/pom.xml
index fd06d1da61..b63ce7768c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -123,16 +123,16 @@
2.12.2
4.0.4
2.2.34
- 2.19.1
+ 2.20.1
6.2.11
- 9.8.1
+ 9.10.0
1.1.4
5.5
2.10.0
3.2.6
https://roda-community.org
all
- 3.4.10
+ 3.5.7
provided
1.5.19
@@ -478,6 +478,13 @@
jaxb-runtime
4.0.5
+
+ com.fasterxml.jackson
+ jackson-bom
+ 2.20.0
+ import
+ pom
+
org.springframework.boot
@@ -486,36 +493,6 @@
pom
import
-
- com.fasterxml.jackson.core
- jackson-core
- ${jackson.version}
-
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
-
- com.fasterxml.jackson.core
- jackson-annotations
- ${jackson.version}
-
-
- com.fasterxml.jackson.dataformat
- jackson-dataformat-xml
- ${jackson.version}
-
-
- com.fasterxml.jackson.dataformat
- jackson-dataformat-yaml
- ${jackson.version}
-
-
- com.fasterxml.jackson.datatype
- jackson-datatype-jsr310
- ${jackson.version}
-
org.gwtproject
gwt-dev
@@ -560,7 +537,7 @@
commons-io
commons-io
- 2.19.0
+ 2.20.0
commons-logging
@@ -960,19 +937,11 @@
icu4j
63.2
-
org.springframework.boot
spring-boot-starter-tomcat
provided
-
-
-
- com.google.code.gson
- gson
- 2.11.0
-
diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/common/RodaConstants.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/common/RodaConstants.java
index d394118bab..613e122d59 100644
--- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/common/RodaConstants.java
+++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/common/RodaConstants.java
@@ -401,6 +401,9 @@ public enum DateGranularity {
// dips
public static final String API_REST_V2_DIPS = "api/v2/dips/";
+ // dipfiles
+ public static final String API_REST_V2_DIPFILES = "api/v2/dip-files/";
+
// representation-information
public static final String API_REST_V2_REPRESENTATION_INFORMATION = "api/v2/representation-information/";
diff --git a/roda-common/roda-common-data/src/main/java/org/roda/core/data/utils/URNUtils.java b/roda-common/roda-common-data/src/main/java/org/roda/core/data/utils/URNUtils.java
index 6861161e6f..0a3e415902 100644
--- a/roda-common/roda-common-data/src/main/java/org/roda/core/data/utils/URNUtils.java
+++ b/roda-common/roda-common-data/src/main/java/org/roda/core/data/utils/URNUtils.java
@@ -51,7 +51,7 @@ public static String createRodaPreservationURN(PreservationMetadataType preserva
}
public static String createRodaTechnicalMetadataURN(String id, String instanceId, String technicalMetadataType) {
- return getTechnicalMetadataPrefix(technicalMetadataType, instanceId) + id;
+ return getTechnicalMetadataPrefix(technicalMetadataType, instanceId) + id + RodaConstants.REPRESENTATION_INFORMATION_FILE_EXTENSION;
}
public static String getTechnicalMetadataPrefix(String technicalMetadataType, String instanceId) {
diff --git a/roda-common/roda-common-utils/src/main/java/org/roda/core/util/HTTPUtility.java b/roda-common/roda-common-utils/src/main/java/org/roda/core/util/HTTPUtility.java
index 96d4a03089..fc4e8c4d17 100644
--- a/roda-common/roda-common-utils/src/main/java/org/roda/core/util/HTTPUtility.java
+++ b/roda-common/roda-common-utils/src/main/java/org/roda/core/util/HTTPUtility.java
@@ -32,39 +32,41 @@ private HTTPUtility() {
// do nothing
}
+ public static String doMethodBearer(String url, String method, Optional token) throws GenericException {
+ try {
+ URL obj = new URL(url);
+ HttpURLConnection con = (HttpURLConnection) obj.openConnection();
+ con.setRequestProperty("Accept", "application/json");
+ con.setRequestProperty("Content-Type", "application/json");
+ con.setRequestMethod(method);
+ addBearerAuthToConnection(con, token);
+ return executeRequest(con);
+ } catch (IOException e) {
+ throw new GenericException("Unable to connect to server", e);
+ }
+ }
+
public static String doMethod(String url, String method, Optional> basicAuth)
throws GenericException {
- String res = null;
try {
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod(method);
addBasicAuthToConnection(con, basicAuth);
- int responseCode = con.getResponseCode();
- if (responseCode == 200) {
- InputStream is = con.getInputStream();
- BufferedReader in = new BufferedReader(new InputStreamReader(is));
- String inputLine;
- StringBuilder response = new StringBuilder();
- while ((inputLine = in.readLine()) != null) {
- response.append(inputLine);
- }
- in.close();
- is.close();
- res = response.toString();
- } else {
- throw new GenericException("Unable to connect to server, response code: " + responseCode);
- }
+ return executeRequest(con);
} catch (IOException e) {
throw new GenericException("Unable to connect to server", e);
}
- return res;
}
public static String doGet(String url) throws GenericException {
return doMethod(url, METHOD_GET, Optional.empty());
}
+ public static String doGetBearer(String url, Optional token) throws GenericException {
+ return doMethodBearer(url, METHOD_GET, token);
+ }
+
public static String doGet(String url, Optional> basicAuth) throws GenericException {
return doMethod(url, METHOD_GET, basicAuth);
}
@@ -77,6 +79,10 @@ public static String doDelete(String url, Optional> basicAu
return doMethod(url, METHOD_DELETE, basicAuth);
}
+ public static String doDeleteBearer(String url, Optional token) throws GenericException {
+ return doMethodBearer(url, METHOD_DELETE, token);
+ }
+
private static void addBasicAuthToConnection(HttpURLConnection connection,
Optional> credentials) {
if (credentials.isPresent()) {
@@ -85,4 +91,28 @@ private static void addBasicAuthToConnection(HttpURLConnection connection,
connection.setRequestProperty("Authorization", "Basic " + encoded);
}
}
+
+ private static void addBearerAuthToConnection(HttpURLConnection connection, Optional token) {
+ token.ifPresent(s -> connection.setRequestProperty("Authorization", "Bearer " + s));
+ }
+
+ private static String executeRequest(HttpURLConnection con) throws IOException, GenericException {
+ int resCode = con.getResponseCode();
+
+ if (resCode == 200) {
+ InputStream is = con.getInputStream();
+ try (BufferedReader in = new BufferedReader(new InputStreamReader(is))) {
+ String inputLine;
+ StringBuilder response = new StringBuilder();
+ while ((inputLine = in.readLine()) != null) {
+ response.append(inputLine);
+ }
+ return response.toString();
+ } finally {
+ is.close();
+ }
+ } else {
+ throw new GenericException("Unable to connect to server, response code: " + resCode);
+ }
+ }
}
diff --git a/roda-common/roda-common-utils/src/main/java/org/roda/core/util/IdUtils.java b/roda-common/roda-common-utils/src/main/java/org/roda/core/util/IdUtils.java
index 104f01c2e8..ef06a327b7 100644
--- a/roda-common/roda-common-utils/src/main/java/org/roda/core/util/IdUtils.java
+++ b/roda-common/roda-common-utils/src/main/java/org/roda/core/util/IdUtils.java
@@ -191,6 +191,12 @@ public static String getTransferredResourceUUID(Path relativeToBase) {
return getTransferredResourceUUID(relativeToBase.toString());
}
+ public static String createTechnicalMetadataFileId(String fileId, List fileDirectoryPath){
+ if(fileDirectoryPath.isEmpty()) return fileId;
+ String pathPrefix = String.join(ID_SEPARATOR, fileDirectoryPath);
+ return pathPrefix + ID_SEPARATOR + fileId;
+ }
+
public static String getTransferredResourceUUID(String relativeToBase) {
return IdUtils.createUUID(relativeToBase);
}
diff --git a/roda-core/roda-core-tests/pom.xml b/roda-core/roda-core-tests/pom.xml
index 1373dcfc8e..011b376fea 100644
--- a/roda-core/roda-core-tests/pom.xml
+++ b/roda-core/roda-core-tests/pom.xml
@@ -155,7 +155,7 @@
org.testcontainers
testcontainers
- 1.21.1
+ 2.0.2
diff --git a/roda-core/roda-core-tests/src/main/java/org/roda/core/security/LdapUtilityTestHelper.java b/roda-core/roda-core-tests/src/main/java/org/roda/core/security/LdapUtilityTestHelper.java
index 68197c94d8..c24c2be83b 100644
--- a/roda-core/roda-core-tests/src/main/java/org/roda/core/security/LdapUtilityTestHelper.java
+++ b/roda-core/roda-core-tests/src/main/java/org/roda/core/security/LdapUtilityTestHelper.java
@@ -38,7 +38,7 @@ public LdapUtility getLdapUtility() {
public LdapUtilityTestHelper() {
final String ldapBaseDN = "dc=roda,dc=org";
- DockerImageName OPENLDAP_IMAGE = DockerImageName.parse("docker.io/bitnami/openldap:2.6");
+ DockerImageName OPENLDAP_IMAGE = DockerImageName.parse("docker.io/bitnamilegacy/openldap:2.6");
openldap = new GenericContainer<>(OPENLDAP_IMAGE);
openldap.withExposedPorts(1389);
diff --git a/roda-core/roda-core/pom.xml b/roda-core/roda-core/pom.xml
index d3897a54d2..78b96d1278 100644
--- a/roda-core/roda-core/pom.xml
+++ b/roda-core/roda-core/pom.xml
@@ -46,16 +46,12 @@
jar-with-dependencies
false
-
-
-
+
+
+
org.roda.core.RodaCoreFactory
-
+
reference.conf
@@ -96,16 +92,12 @@
jar-with-dependencies
false
-
-
-
+
+
+
org.roda.core.RodaCoreFactory
-
+
reference.conf
@@ -164,7 +156,7 @@
org.apache.zookeeper
zookeeper
- 3.9.3
+ 3.9.4
diff --git a/roda-core/roda-core/src/main/java/org/roda/core/index/schema/collections/FileCollection.java b/roda-core/roda-core/src/main/java/org/roda/core/index/schema/collections/FileCollection.java
index c5e1c9b34d..b9b6e6b60c 100644
--- a/roda-core/roda-core/src/main/java/org/roda/core/index/schema/collections/FileCollection.java
+++ b/roda-core/roda-core/src/main/java/org/roda/core/index/schema/collections/FileCollection.java
@@ -195,8 +195,11 @@ public SolrInputDocument toSolrDocument(ModelService model, File file, IndexingA
Long sizeInBytes = 0L;
- SolrUtils.indexRepresentationTechnicalMetadata(model,
- getRepresentationTechnicalMetadata(((Info) info).aip, file.getRepresentationId()), fileId, doc);
+ if (!file.isDirectory()) {
+ String techMdFileId = IdUtils.createTechnicalMetadataFileId(fileId, file.getPath());
+ SolrUtils.indexRepresentationTechnicalMetadata(model,
+ getRepresentationTechnicalMetadata(((Info) info).aip, file.getRepresentationId()), techMdFileId, doc);
+ }
// Add information from PREMIS
Binary premisFile = getFilePremisFile(model, file);
diff --git a/roda-core/roda-core/src/main/java/org/roda/core/index/utils/SolrUtils.java b/roda-core/roda-core/src/main/java/org/roda/core/index/utils/SolrUtils.java
index efd3877c8b..99425125dd 100644
--- a/roda-core/roda-core/src/main/java/org/roda/core/index/utils/SolrUtils.java
+++ b/roda-core/roda-core/src/main/java/org/roda/core/index/utils/SolrUtils.java
@@ -1545,7 +1545,7 @@ public static void indexRepresentationTechnicalMetadata(ModelService model,
StoragePath storagePath = ModelUtils.getTechnicalMetadataStoragePath(techMd.getAipId(),
techMd.getRepresentationId(), Collections.singletonList(techMd.getType()),
- urn + RodaConstants.REPRESENTATION_INFORMATION_FILE_EXTENSION);
+ urn);
Binary binary = model.getStorage().getBinary(storagePath);
diff --git a/roda-core/roda-core/src/main/java/org/roda/core/model/DefaultModelService.java b/roda-core/roda-core/src/main/java/org/roda/core/model/DefaultModelService.java
index 347df8c33e..f461c2e783 100644
--- a/roda-core/roda-core/src/main/java/org/roda/core/model/DefaultModelService.java
+++ b/roda-core/roda-core/src/main/java/org/roda/core/model/DefaultModelService.java
@@ -721,6 +721,12 @@ public Binary retrieveDescriptiveMetadataBinary(String aipId, String representat
return storage.getBinary(binaryPath);
}
+ public Binary retrieveTechnicalMetadataBinary(String aipId, String representationId, List fileDirectoryPath, String fileId)
+ throws RequestNotValidException, GenericException, NotFoundException, AuthorizationDeniedException {
+ StoragePath binaryPath = ModelUtils.getTechnicalMetadataStoragePath(aipId, representationId, fileDirectoryPath, fileId);
+ return storage.getBinary(binaryPath);
+ }
+
@Override
public DescriptiveMetadata retrieveDescriptiveMetadata(String aipId, String descriptiveMetadataId)
throws RequestNotValidException, GenericException, NotFoundException, AuthorizationDeniedException {
@@ -1790,20 +1796,59 @@ public void createTechnicalMetadata(String aipId, String representationId, Strin
StoragePath binaryPath = ModelUtils.getTechnicalMetadataStoragePath(aipId, representationId,
Collections.singletonList(metadataType), urn);
storage.createBinary(binaryPath, payload, false);
- TechnicalMetadata techMd = new TechnicalMetadata(metadataType, aipId, representationId, metadataType);
- AIP updatedAIP = null;
if (aipId != null) {
AIP aip = ResourceParseUtils.getAIPMetadata(getStorage(), aipId);
- aip.addTechnicalMetadata(techMd);
- updatedAIP = updateAIPMetadata(aip, createdBy);
+ addTechnicalMetadataToAIPMetadata(aip, representationId, metadataType, createdBy, notify);
+ }
+ }
+
+ @Override
+ public void updateTechnicalMetadata(String aipId, String representationId, String metadataType, String fileId,
+ ContentPayload payload, String createdBy, boolean notify)
+ throws AuthorizationDeniedException, RequestNotValidException, NotFoundException, GenericException {
+ RodaCoreFactory.checkIfWriteIsAllowedAndIfFalseThrowException(nodeType);
+
+ String urn = URNUtils.createRodaTechnicalMetadataURN(fileId, RODAInstanceUtils.getLocalInstanceIdentifier(),
+ metadataType.toLowerCase());
+ StoragePath binaryPath = ModelUtils.getTechnicalMetadataStoragePath(aipId, representationId,
+ Collections.singletonList(metadataType), urn);
+ storage.updateBinaryContent(binaryPath, payload, false, false, true, null);
+ // update technicalmetadata logic
+ if (aipId != null) {
+ AIP aip = ResourceParseUtils.getAIPMetadata(getStorage(), aipId);
+ List techMetadataList = getTechnicalMetadata(aip, representationId);
+ techMetadataList.removeIf(tm -> tm.getId().equals(metadataType));
+ addTechnicalMetadataToAIPMetadata(aip, representationId, metadataType, createdBy, notify);
}
+ }
+
+ private void addTechnicalMetadataToAIPMetadata(AIP aip, String representationId, String metadataType,
+ String createdBy, boolean notify)
+ throws RequestNotValidException, GenericException, NotFoundException, AuthorizationDeniedException {
+ TechnicalMetadata techMd = new TechnicalMetadata(metadataType, aip.getId(), representationId, metadataType);
+
+ aip.addTechnicalMetadata(techMd);
+ AIP updatedAIP = updateAIPMetadata(aip, createdBy);
if (notify && updatedAIP != null) {
notifyAipUpdatedOnChanged(updatedAIP).failOnError();
}
}
+ private List getTechnicalMetadata(AIP aip, String representationId) {
+ if (representationId == null) {
+ return new ArrayList<>();
+ }
+ Optional oRep = aip.getRepresentations().stream()
+ .filter(rep -> rep.getId().equals(representationId)).findFirst();
+ if (oRep.isPresent()) {
+ return oRep.get().getTechnicalMetadata();
+ }
+
+ return new ArrayList<>();
+ }
+
@Override
public PreservationMetadata createPreservationMetadata(PreservationMetadataType type, String aipId,
String representationId, List fileDirectoryPath, String fileId, ContentPayload payload, String username,
diff --git a/roda-core/roda-core/src/main/java/org/roda/core/model/DefaultTransactionalModelService.java b/roda-core/roda-core/src/main/java/org/roda/core/model/DefaultTransactionalModelService.java
index 4fa1334fd7..0d701343d3 100644
--- a/roda-core/roda-core/src/main/java/org/roda/core/model/DefaultTransactionalModelService.java
+++ b/roda-core/roda-core/src/main/java/org/roda/core/model/DefaultTransactionalModelService.java
@@ -439,6 +439,23 @@ public Binary retrieveDescriptiveMetadataBinary(String aipId, String representat
}
}
+ @Override
+ public Binary retrieveTechnicalMetadataBinary(String aipId, String representationId, List fileDirectoryPath,
+ String fileId) throws AuthorizationDeniedException, RequestNotValidException, NotFoundException, GenericException {
+ List operationLogs = operationRegistry.registerOperationForTechnicalMetadata(aipId,
+ representationId, fileDirectoryPath, fileId, OperationType.READ);
+
+ try {
+ Binary binary = stagingModelService.retrieveTechnicalMetadataBinary(aipId, representationId, fileDirectoryPath,
+ fileId);
+ operationRegistry.updateOperationState(operationLogs, OperationState.SUCCESS);
+ return binary;
+ } catch (RequestNotValidException | GenericException | NotFoundException | AuthorizationDeniedException e) {
+ operationRegistry.updateOperationState(operationLogs, OperationState.FAILURE);
+ throw e;
+ }
+ }
+
@Override
public DescriptiveMetadata retrieveDescriptiveMetadata(String aipId, String descriptiveMetadataId)
throws RequestNotValidException, GenericException, NotFoundException, AuthorizationDeniedException {
@@ -1491,6 +1508,23 @@ public void createTechnicalMetadata(String aipId, String representationId, Strin
}
}
+ @Override
+ public void updateTechnicalMetadata(String aipId, String representationId, String metadataType, String fileId,
+ ContentPayload payload, String createdBy, boolean notify) throws AuthorizationDeniedException,
+ RequestNotValidException, AlreadyExistsException, NotFoundException, GenericException {
+ List operationLogs = operationRegistry.registerOperationForRepresentation(aipId,
+ representationId, OperationType.UPDATE);
+ try {
+ getModelService().updateTechnicalMetadata(aipId, representationId, metadataType, fileId, payload, createdBy,
+ notify);
+ operationRegistry.updateOperationState(operationLogs, OperationState.SUCCESS);
+ } catch (AuthorizationDeniedException | RequestNotValidException | AlreadyExistsException | NotFoundException
+ | GenericException e) {
+ operationRegistry.updateOperationState(operationLogs, OperationState.FAILURE);
+ throw e;
+ }
+ }
+
@Override
public PreservationMetadata createPreservationMetadata(PreservationMetadata.PreservationMetadataType type,
String aipId, List fileDirectoryPath, String fileId, ContentPayload payload, String username,
diff --git a/roda-core/roda-core/src/main/java/org/roda/core/model/LiteRODAObjectFactory.java b/roda-core/roda-core/src/main/java/org/roda/core/model/LiteRODAObjectFactory.java
index 7b3adab350..906fe14ea8 100644
--- a/roda-core/roda-core/src/main/java/org/roda/core/model/LiteRODAObjectFactory.java
+++ b/roda-core/roda-core/src/main/java/org/roda/core/model/LiteRODAObjectFactory.java
@@ -42,6 +42,7 @@
import org.roda.core.data.v2.ip.metadata.OtherMetadata;
import org.roda.core.data.v2.ip.metadata.PreservationMetadata;
import org.roda.core.data.v2.ip.metadata.PreservationMetadata.PreservationMetadataType;
+import org.roda.core.data.v2.ip.metadata.TechnicalMetadata;
import org.roda.core.data.v2.jobs.Job;
import org.roda.core.data.v2.jobs.Report;
import org.roda.core.data.v2.log.LogEntry;
@@ -162,6 +163,8 @@ public static Optional get(T object) {
ret = getOtherMetadata(object);
} else if (object instanceof PreservationMetadata) {
ret = getPreservationMetadata(object);
+ } else if (object instanceof TechnicalMetadata) {
+ ret = getTechnicalMetadata(object);
} else if (object instanceof IndexedPreservationEvent) {
ret = getIndexedPreservationEvent(object);
} else if (object instanceof DIPFile) {
@@ -215,6 +218,10 @@ public static Optional get(Class obj
if (ids.size() == 2 || ids.size() == 3) {
ret = create(objectClass, ids.size(), ids);
}
+ } else if (objectClass == TechnicalMetadata.class) {
+ if (ids.size() >= 3) {
+ ret = create(objectClass, ids.size(), ids);
+ }
} else if (objectClass == OtherMetadata.class) {
if (ids.size() == 2 || ids.size() == 3) {
ret = create(objectClass, ids.size(), ids);
@@ -265,6 +272,16 @@ private static Optional getDescriptiveM
return ret;
}
+ private static Optional getTechnicalMetadata(T object) {
+ Optional ret;
+ TechnicalMetadata o = (TechnicalMetadata) object;
+ List list = new ArrayList<>();
+ list.add(o.getAipId());
+ list.add(o.getRepresentationId());
+ list.add(o.getId());
+ return get(TechnicalMetadata.class, list, false);
+ }
+
private static Optional getOtherMetadata(T object) {
Optional ret;
diff --git a/roda-core/roda-core/src/main/java/org/roda/core/model/ModelService.java b/roda-core/roda-core/src/main/java/org/roda/core/model/ModelService.java
index f488a91b51..1ef761900e 100644
--- a/roda-core/roda-core/src/main/java/org/roda/core/model/ModelService.java
+++ b/roda-core/roda-core/src/main/java/org/roda/core/model/ModelService.java
@@ -164,6 +164,9 @@ Binary retrieveDescriptiveMetadataBinary(String aipId, String descriptiveMetadat
Binary retrieveDescriptiveMetadataBinary(String aipId, String representationId, String descriptiveMetadataId)
throws RequestNotValidException, GenericException, NotFoundException, AuthorizationDeniedException;
+ Binary retrieveTechnicalMetadataBinary(String aipId, String representationId, List fileDirectoryPath, String fileId)
+ throws RequestNotValidException, GenericException, NotFoundException, AuthorizationDeniedException ;
+
DescriptiveMetadata retrieveDescriptiveMetadata(String aipId, String descriptiveMetadataId)
throws RequestNotValidException, GenericException, NotFoundException, AuthorizationDeniedException;
@@ -381,6 +384,10 @@ PreservationMetadata createPreservationMetadata(PreservationMetadata.Preservatio
void createTechnicalMetadata(String aipId, String representationId, String metadataType, String fileId,
ContentPayload payload, String createdBy, boolean notify) throws AuthorizationDeniedException,
RequestNotValidException, AlreadyExistsException, NotFoundException, GenericException;
+
+ void updateTechnicalMetadata(String aipId, String representationId, String metadataType, String fileId,
+ ContentPayload payload, String createdBy, boolean notify) throws AuthorizationDeniedException,
+ RequestNotValidException, AlreadyExistsException, NotFoundException, GenericException;
public PreservationMetadata createPreservationMetadata(PreservationMetadataType type, String aipId,
List fileDirectoryPath, String fileId, ContentPayload payload, String username, boolean notify)
diff --git a/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/ingest/EARKSIP2ToAIPPluginUtils.java b/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/ingest/EARKSIP2ToAIPPluginUtils.java
index 3e056fbb67..a2082b3903 100644
--- a/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/ingest/EARKSIP2ToAIPPluginUtils.java
+++ b/roda-core/roda-core/src/main/java/org/roda/core/plugins/base/ingest/EARKSIP2ToAIPPluginUtils.java
@@ -9,6 +9,8 @@
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -307,7 +309,7 @@ private static void processIPRepresentationInformation(ModelService model, IPRep
// Either we're not updating or the retrieve failed
if (representation == null) {
representation = model.createRepresentation(aipId, sr.getObjectID(), isOriginal, representationType, notify,
- username);
+ username, isOriginal ? Collections.emptyList() : List.of(sr.getStatus().asString()));
if (reportItem != null && update) {
reportItem.getSipInformation().addRepresentationData(aipId, IdUtils.getRepresentationId(representation));
}
diff --git a/roda-core/roda-core/src/main/java/org/roda/core/repository/transaction/TransactionalStoragePathRepository.java b/roda-core/roda-core/src/main/java/org/roda/core/repository/transaction/TransactionalStoragePathRepository.java
index f98ebb5dbb..0c4291af74 100644
--- a/roda-core/roda-core/src/main/java/org/roda/core/repository/transaction/TransactionalStoragePathRepository.java
+++ b/roda-core/roda-core/src/main/java/org/roda/core/repository/transaction/TransactionalStoragePathRepository.java
@@ -45,7 +45,7 @@ List findByTransactionLogAndOperationType(
@Param("transactionLog") TransactionLog transactionLog, @Param("operationType") OperationType operationType,
@Param("operationState") OperationState operationState);
- @Query("SELECT o FROM TransactionalStoragePathOperationLog o WHERE o.transactionLog = :transactionLog AND o.storagePath LIKE CONCAT(:storagePath, '/%') AND o.operationType <> 'READ'")
+ @Query("SELECT o FROM TransactionalStoragePathOperationLog o WHERE o.transactionLog = :transactionLog AND (o.storagePath = :storagePath OR o.storagePath LIKE CONCAT(:storagePath, '/%')) AND o.operationType <> 'READ'")
List findModificationsUnderStoragePath(
@Param("transactionLog") TransactionLog transactionLog, @Param("storagePath") String storagePath);
}
diff --git a/roda-core/roda-core/src/main/java/org/roda/core/transaction/TransactionalModelOperationRegistry.java b/roda-core/roda-core/src/main/java/org/roda/core/transaction/TransactionalModelOperationRegistry.java
index 7981a59832..5fdc249b8d 100644
--- a/roda-core/roda-core/src/main/java/org/roda/core/transaction/TransactionalModelOperationRegistry.java
+++ b/roda-core/roda-core/src/main/java/org/roda/core/transaction/TransactionalModelOperationRegistry.java
@@ -33,6 +33,7 @@
import org.roda.core.data.v2.ip.TransferredResource;
import org.roda.core.data.v2.ip.metadata.DescriptiveMetadata;
import org.roda.core.data.v2.ip.metadata.PreservationMetadata;
+import org.roda.core.data.v2.ip.metadata.TechnicalMetadata;
import org.roda.core.data.v2.jobs.Job;
import org.roda.core.data.v2.jobs.Report;
import org.roda.core.data.v2.log.LogEntry;
@@ -113,6 +114,21 @@ public List registerOperationForDescriptiveMetad
return operationLogs;
}
+ public List registerOperationForTechnicalMetadata(String aipID,
+ String representationId, List fileDirectoryPath, String fileId, OperationType operation) {
+ List operationLogs = new ArrayList<>();
+ operationLogs.add(registerOperationForRelatedAIP(aipID, operation));
+ List list = new ArrayList<>();
+ list.add(aipID);
+ list.addAll(fileDirectoryPath);
+ if (representationId != null) {
+ list.add(representationId);
+ }
+ list.add(fileId);
+ operationLogs.add(registerOperation(TechnicalMetadata.class, list, operation));
+ return operationLogs;
+ }
+
public List registerOperationForRepresentation(String aipID, String representationId,
OperationType operation) {
List operationLogs = new ArrayList<>();
@@ -511,7 +527,6 @@ public void releaseLock(Class objectClass, String id
"[transactionId:" + transaction.getId() + "] Object class is not lockable: " + objectClass.getName());
}
-
Optional liteRODAObject = LiteRODAObjectFactory.get(objectClass, id);
if (liteRODAObject.isPresent()) {
String lite = liteRODAObject.get().getInfo();
diff --git a/roda-core/roda-core/src/main/resources/config/roda-permissions.properties b/roda-core/roda-core/src/main/resources/config/roda-permissions.properties
index 826a491ea7..29a39e09fc 100644
--- a/roda-core/roda-core/src/main/resources/config/roda-permissions.properties
+++ b/roda-core/roda-core/src/main/resources/config/roda-permissions.properties
@@ -88,6 +88,7 @@ core.permissions.org.roda.wui.api.v2.controller.FilesController.retrievePreserva
core.permissions.org.roda.wui.api.v2.controller.FilesController.retrieveTechnicalMetadataInfos=READ
core.permissions.org.roda.wui.api.v2.controller.FilesController.retrieveFileTechnicalMetadataHTML=READ
core.permissions.org.roda.wui.api.v2.controller.FilesController.retrieveTechnicalMetadataFile=READ
+core.permissions.org.roda.wui.api.v2.controller.FilesController.getOtherMetadata = READ
# Preservation events permissions
core.permissions.org.roda.wui.api.v2.controller.PreservationEventController.downloadPreservationEvent = READ
diff --git a/roda-core/roda-core/src/main/resources/config/roda-roles.properties b/roda-core/roda-core/src/main/resources/config/roda-roles.properties
index c740bad3c2..33564cc43e 100644
--- a/roda-core/roda-core/src/main/resources/config/roda-roles.properties
+++ b/roda-core/roda-core/src/main/resources/config/roda-roles.properties
@@ -130,6 +130,7 @@ core.roles.org.roda.wui.api.v2.controller.FilesController.retrievePreservationMe
core.roles.org.roda.wui.api.v2.controller.FilesController.retrieveTechnicalMetadataInfos=preservation_metadata.read
core.roles.org.roda.wui.api.v2.controller.FilesController.retrieveFileTechnicalMetadataHTML=preservation_metadata.read
core.roles.org.roda.wui.api.v2.controller.FilesController.retrieveTechnicalMetadataFile=preservation_metadata.read
+core.roles.org.roda.wui.api.v2.controller.FilesController.getOtherMetadata = preservation_metadata.read
# Metrics roles
core.roles.org.roda.wui.api.v2.controller.MetricsController.getMetrics = job.manage
@@ -252,6 +253,10 @@ core.roles.org.roda.wui.api.v2.controller.DIPController.deleteIndexedDIPs = aip.
core.roles.org.roda.wui.api.v2.controller.DIPController.downloadBinary = aip.read
core.roles.org.roda.wui.api.v2.controller.DIPController.updatePermissions = aip.update
+# DIPFile roles
+core.roles.org.roda.wui.api.v2.controller.DIPFileController.previewBinary = aip.read
+core.roles.org.roda.wui.api.v2.controller.DIPFileController.downloadBinary = aip.read
+
# Configuration roles
core.roles.org.roda.wui.api.v2.controller.ConfigurationController.retrievePluginsInfo = job.read
core.roles.org.roda.wui.api.v2.controller.ConfigurationController.retrieveReindexPluginObjectClasses = job.read
diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/controller/DIPController.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/controller/DIPController.java
index b9774ed312..887a3238b0 100644
--- a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/controller/DIPController.java
+++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/controller/DIPController.java
@@ -107,10 +107,8 @@ public ResponseEntity downloadBinary(
public ResponseEntity process(RequestContext requestContext,
RequestControllerAssistant controllerAssistant) throws RODAException, RESTException {
- IndexedDIP dip = indexService.retrieve(IndexedDIP.class, dipUUID, new ArrayList<>());
-
+ IndexedDIP dip = requestContext.getIndexService().retrieve(IndexedDIP.class, dipUUID, new ArrayList<>());
controllerAssistant.checkObjectPermissions(requestContext.getUser(), dip);
-
controllerAssistant.setParameters(RodaConstants.CONTROLLER_DIP_UUID_PARAM, dipUUID);
return ApiUtils.okResponse(dipService.createStreamResponse(requestContext, dip.getUUID()));
diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/controller/DIPFileController.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/controller/DIPFileController.java
index 5f963975b5..a069081f60 100644
--- a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/controller/DIPFileController.java
+++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/controller/DIPFileController.java
@@ -11,6 +11,7 @@
import java.util.List;
import org.roda.core.data.common.RodaConstants;
+import org.roda.core.data.exceptions.RODAException;
import org.roda.core.data.v2.generics.LongResponse;
import org.roda.core.data.v2.index.CountRequest;
import org.roda.core.data.v2.index.FindRequest;
@@ -18,18 +19,32 @@
import org.roda.core.data.v2.index.SuggestRequest;
import org.roda.core.data.v2.ip.DIPFile;
import org.roda.core.model.utils.UserUtility;
+import org.roda.wui.api.v2.exceptions.RESTException;
+import org.roda.wui.api.v2.exceptions.model.ErrorResponseMessage;
+import org.roda.wui.api.v2.services.DIPFileService;
import org.roda.wui.api.v2.services.IndexService;
import org.roda.wui.api.v2.utils.ApiUtils;
import org.roda.wui.client.services.DIPFileRestService;
+import org.roda.wui.common.RequestControllerAssistant;
import org.roda.wui.common.model.RequestContext;
import org.roda.wui.common.utils.RequestUtils;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
import jakarta.servlet.http.HttpServletRequest;
/**
@@ -44,6 +59,12 @@ public class DIPFileController implements DIPFileRestService, Exportable {
@Autowired
IndexService indexService;
+ @Autowired
+ DIPFileService dipFileService;
+
+ @Autowired
+ RequestHandler requestHandler;
+
@Override
public DIPFile findByUuid(String uuid, String localeString) {
return indexService.retrieve(DIPFile.class, uuid, new ArrayList<>());
@@ -75,4 +96,41 @@ public ResponseEntity exportToCSV(String findRequestStrin
// delegate
return ApiUtils.okResponse(indexService.exportToCSV(findRequestString, DIPFile.class));
}
+
+ @GetMapping(path = "{uuid}/preview", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
+ @Operation(summary = "DIP file View", description = "View DIP file binary", responses = {
+ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = StreamingResponseBody.class))),
+ @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))),
+ @ApiResponse(responseCode = "404", description = "DIP file not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))})
+ public ResponseEntity previewBinary(
+ @Parameter(description = "The UUID of the existing DIP file", required = true) @PathVariable(name = "uuid") String dipFileUUID,
+ @RequestHeader HttpHeaders headers) {
+ return requestHandler.processRequest(new RequestHandler.RequestProcessor>() {
+ @Override
+ public ResponseEntity process(RequestContext requestContext,
+ RequestControllerAssistant controllerAssistant) throws RODAException, RESTException {
+ List dipPermissionFields = new ArrayList<>(RodaConstants.DIPFILE_FIELDS_TO_RETURN);
+ DIPFile dipFile = requestContext.getIndexService().retrieve(DIPFile.class, dipFileUUID, dipPermissionFields);
+ return ApiUtils.rangeResponse(headers, dipFileService.retrieveDIPFileRangeStream(requestContext, dipFile));
+ }
+ });
+ }
+
+ @GetMapping(path = "{uuid}/download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
+ @Operation(summary = "DIP file Preview", description = "Preview the DIP file binary", responses = {
+ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = StreamingResponseBody.class))),
+ @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))),
+ @ApiResponse(responseCode = "404", description = "DIP file not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))})
+ public ResponseEntity downloadBinary(@PathVariable(name = "uuid") String dipFileUUID) {
+
+ return requestHandler.processRequest(new RequestHandler.RequestProcessor>() {
+ @Override
+ public ResponseEntity process(RequestContext requestContext,
+ RequestControllerAssistant controllerAssistant) throws RODAException, RESTException {
+ List fileFields = new ArrayList<>(RodaConstants.DIPFILE_FIELDS_TO_RETURN);
+ DIPFile dipFile = requestContext.getIndexService().retrieve(DIPFile.class, dipFileUUID, fileFields);
+ return ApiUtils.okResponse(dipFileService.retrieveDIPFileStreamResponse(requestContext, dipFile));
+ }
+ });
+ }
}
diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/controller/FilesController.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/controller/FilesController.java
index c019240193..aca6421f5b 100644
--- a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/controller/FilesController.java
+++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/controller/FilesController.java
@@ -34,6 +34,7 @@
import org.roda.core.data.v2.ip.IndexedAIP;
import org.roda.core.data.v2.ip.IndexedFile;
import org.roda.core.data.v2.ip.IndexedRepresentation;
+import org.roda.core.data.v2.ip.metadata.OtherMetadata;
import org.roda.core.data.v2.ip.metadata.TechnicalMetadataInfos;
import org.roda.core.data.v2.jobs.Job;
import org.roda.core.model.utils.UserUtility;
@@ -413,8 +414,7 @@ public List process(RequestContext requestContext, RequestControllerAssi
@Override
public ResponseEntity exportToCSV(String findRequestString) {
// delegate
- return ApiUtils
- .okResponse(indexService.exportToCSV(findRequestString, IndexedFile.class));
+ return ApiUtils.okResponse(indexService.exportToCSV(findRequestString, IndexedFile.class));
}
@GetMapping(path = "/{uuid}/metadata/technical/{typeId}/html", produces = MediaType.TEXT_HTML_VALUE)
@@ -483,4 +483,32 @@ public ResponseEntity process(RequestContext requestConte
}
});
}
+
+ @RequestMapping(method = RequestMethod.GET, path = "/{fileUUID}/other_metadata/{metadata_type}/{metadata_file_suffix}", produces = MediaType.APPLICATION_JSON_VALUE)
+ @Operation(summary = "Gets other metadata (JSON info or ZIP file).\nOptional query params of **start** and **limit** defined the returned query", responses = {
+ @ApiResponse(responseCode = "200", description = "Other metadata file", content = @Content(schema = @Schema(implementation = OtherMetadata.class))),
+ @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))),
+ @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))),
+ @ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class)))})
+ ResponseEntity getOtherMetadata(
+ @Parameter(description = "The UUID of the existing File", required = true) @PathVariable(name = "fileUUID") String fileUUID,
+ @Parameter(description = "The type of the other metadata", required = true) @PathVariable(name = "metadata_type") String metadataType,
+ @Parameter(description = "The file suffix of the other metadata", required = true) @PathVariable(name = "metadata_file_suffix") String metadataFileSuffix) {
+ return requestHandler.processRequest(new RequestHandler.RequestProcessor>() {
+ @Override
+ public ResponseEntity process(RequestContext requestContext,
+ RequestControllerAssistant controllerAssistant) throws RODAException, RESTException, IOException {
+ controllerAssistant.setParameters(RodaConstants.CONTROLLER_FILE_ID_PARAM, fileUUID);
+ // check object permissions
+ IndexedFile indexedFile = requestContext.getIndexService().retrieve(IndexedFile.class, fileUUID,
+ RodaConstants.FILE_FIELDS_TO_RETURN);
+ controllerAssistant.checkObjectPermissions(requestContext.getUser(), indexedFile);
+
+ // delegate
+ StreamResponse streamResponse = filesService.retrieveOtherMetadata(requestContext, indexedFile, metadataType,
+ metadataFileSuffix);
+ return ApiUtils.okResponse(streamResponse);
+ }
+ });
+ }
}
diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/services/DIPFileService.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/services/DIPFileService.java
new file mode 100644
index 0000000000..1da4450c13
--- /dev/null
+++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/services/DIPFileService.java
@@ -0,0 +1,60 @@
+package org.roda.wui.api.v2.services;
+
+import org.roda.core.data.exceptions.AuthorizationDeniedException;
+import org.roda.core.data.exceptions.GenericException;
+import org.roda.core.data.exceptions.NotFoundException;
+import org.roda.core.data.exceptions.RequestNotValidException;
+import org.roda.core.data.v2.ConsumesOutputStream;
+import org.roda.core.data.v2.LiteRODAObject;
+import org.roda.core.data.v2.StreamResponse;
+import org.roda.core.data.v2.ip.DIPFile;
+import org.roda.core.model.LiteRODAObjectFactory;
+import org.roda.core.model.ModelService;
+import org.roda.core.storage.DirectResourceAccess;
+import org.roda.core.storage.RangeConsumesOutputStream;
+import org.roda.wui.common.model.RequestContext;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ *
+ * @author Eduardo Teixeira
+ */
+@Service
+public class DIPFileService {
+ public RangeConsumesOutputStream retrieveDIPFileRangeStream(RequestContext requestContext, DIPFile dipfile)
+ throws RequestNotValidException {
+ ModelService model = requestContext.getModelService();
+ if (!dipfile.isDirectory()) {
+ final RangeConsumesOutputStream stream;
+ try {
+ DirectResourceAccess directDIPFileAccess = model.getDirectAccess(dipfile);
+ stream = new RangeConsumesOutputStream(directDIPFileAccess.getPath());
+ return stream;
+ } catch (RequestNotValidException | GenericException | AuthorizationDeniedException | NotFoundException e) {
+ throw new RuntimeException(e);
+ }
+
+ } else
+ throw new RequestNotValidException("Range stream for directory unsupported");
+ }
+
+ public StreamResponse retrieveDIPFileStreamResponse(RequestContext requestContext, DIPFile dipFile)
+ throws GenericException, RequestNotValidException, NotFoundException, AuthorizationDeniedException {
+ ModelService model = requestContext.getModelService();
+
+ final ConsumesOutputStream stream;
+ List idPaths = new ArrayList<>();
+ idPaths.add(dipFile.getDipId());
+ idPaths.addAll(dipFile.getPath());
+ idPaths.add(dipFile.getId());
+
+ Optional rodaDIPobj = LiteRODAObjectFactory.get(DIPFile.class, idPaths.toArray(String[]::new));
+ stream = model.exportObjectToStream(rodaDIPobj.get());
+ return new StreamResponse(stream);
+
+ }
+}
diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/services/FilesService.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/services/FilesService.java
index cc38198891..7a808073ed 100644
--- a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/services/FilesService.java
+++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/services/FilesService.java
@@ -247,7 +247,13 @@ public RangeConsumesOutputStream retrieveAIPRepresentationRangeStream(RequestCon
public StreamResponse retrieveAIPRepresentationFile(RequestContext requestContext, IndexedFile indexedFile)
throws GenericException, RequestNotValidException, NotFoundException, AuthorizationDeniedException {
ModelService model = requestContext.getModelService();
- Optional liteFile = LiteRODAObjectFactory.get(File.class, indexedFile.getId());
+ List ids = new ArrayList<>();
+ ids.add(indexedFile.getAipId());
+ ids.add(indexedFile.getRepresentationId());
+ ids.addAll(indexedFile.getPath());
+ ids.add(indexedFile.getId());
+ Optional liteFile = LiteRODAObjectFactory.get(File.class, ids.toArray(String[]::new));
+
if (liteFile.isEmpty()) {
throw new RequestNotValidException("Couldn't retrieve file with id: " + indexedFile.getId());
}
@@ -386,18 +392,18 @@ public StreamResponse retrieveFileTechnicalMetadataHTML(RequestContext requestCo
NotFoundException, GenericException, TechnicalMetadataNotFoundException {
ModelService model = requestContext.getModelService();
Representation representation = model.retrieveRepresentation(file.getAipId(), file.getRepresentationId());
- String techMDURN = URNUtils.createRodaTechnicalMetadataURN(file.getId(),
+ String techMDURN = URNUtils.createRodaTechnicalMetadataURN(IdUtils.createTechnicalMetadataFileId(file.getId(), file.getPath()),
RODAInstanceUtils.getLocalInstanceIdentifier(), type.toLowerCase());
Binary metadataBinary;
if (versionID != null) {
BinaryVersion binaryVersion = model.getBinaryVersion(representation, versionID,
List.of(RodaConstants.STORAGE_DIRECTORY_METADATA, RodaConstants.STORAGE_DIRECTORY_TECHNICAL, type,
- techMDURN + RodaConstants.REPRESENTATION_INFORMATION_FILE_EXTENSION));
+ techMDURN));
metadataBinary = binaryVersion.getBinary();
} else {
metadataBinary = model.getBinary(representation, RodaConstants.STORAGE_DIRECTORY_METADATA,
RodaConstants.STORAGE_DIRECTORY_TECHNICAL, type,
- techMDURN + RodaConstants.REPRESENTATION_INFORMATION_FILE_EXTENSION);
+ techMDURN);
}
String filename = metadataBinary.getStoragePath().getName() + HTML_EXT;
String htmlDescriptive = HTMLUtils.technicalMetadataToHtml(metadataBinary, type, versionID,
@@ -421,18 +427,18 @@ public StreamResponse retrieveFileTechnicalMetadata(RequestContext requestContex
StreamResponse ret;
ModelService model = requestContext.getModelService();
Representation representation = model.retrieveRepresentation(file.getAipId(), file.getRepresentationId());
- String techMDURN = URNUtils.createRodaTechnicalMetadataURN(file.getId(),
+ String techMDURN = URNUtils.createRodaTechnicalMetadataURN(IdUtils.createTechnicalMetadataFileId(file.getId(), file.getPath()),
RODAInstanceUtils.getLocalInstanceIdentifier(), type.toLowerCase());
Binary metadataBinary;
if (versionID != null) {
BinaryVersion binaryVersion = model.getBinaryVersion(representation, versionID,
List.of(RodaConstants.STORAGE_DIRECTORY_METADATA, RodaConstants.STORAGE_DIRECTORY_TECHNICAL, type,
- techMDURN + RodaConstants.REPRESENTATION_INFORMATION_FILE_EXTENSION));
+ techMDURN));
metadataBinary = binaryVersion.getBinary();
} else {
metadataBinary = model.getBinary(representation, RodaConstants.STORAGE_DIRECTORY_METADATA,
RodaConstants.STORAGE_DIRECTORY_TECHNICAL, type,
- techMDURN + RodaConstants.REPRESENTATION_INFORMATION_FILE_EXTENSION);
+ techMDURN);
}
stream = new BinaryConsumesOutputStream(metadataBinary, RodaConstants.MEDIA_TYPE_TEXT_XML);
@@ -441,4 +447,15 @@ public StreamResponse retrieveFileTechnicalMetadata(RequestContext requestContex
return ret;
}
+ public StreamResponse retrieveOtherMetadata(RequestContext requestContext, IndexedFile file, String metadataType,
+ String metadataSuffix)
+ throws AuthorizationDeniedException, RequestNotValidException, NotFoundException, GenericException {
+ final ConsumesOutputStream stream;
+ ModelService model = requestContext.getModelService();
+ Binary otherMetadataBinary = model.retrieveOtherMetadataBinary(file.getAipId(), file.getRepresentationId(),
+ file.getPath(), file.getId(), metadataSuffix, metadataType);
+ stream = new BinaryConsumesOutputStream(otherMetadataBinary, RodaConstants.MEDIA_TYPE_TEXT_HTML);
+ return new StreamResponse(stream);
+ }
+
}
diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/utils/ApiUtils.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/utils/ApiUtils.java
index e6b50f8010..aab0c6a4c1 100644
--- a/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/utils/ApiUtils.java
+++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/api/v2/utils/ApiUtils.java
@@ -7,11 +7,12 @@
*/
package org.roda.wui.api.v2.utils;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Date;
import java.util.concurrent.TimeUnit;
-import org.roda.core.RodaCoreFactory;
import org.roda.core.data.exceptions.AuthorizationDeniedException;
import org.roda.core.data.exceptions.GenericException;
import org.roda.core.data.exceptions.NotFoundException;
@@ -22,7 +23,6 @@
import org.roda.core.data.v2.StreamResponse;
import org.roda.core.data.v2.common.Pair;
import org.roda.core.model.ModelService;
-import org.roda.core.storage.BinaryConsumesOutputStream;
import org.roda.core.storage.RangeConsumesOutputStream;
import org.roda.wui.common.model.RequestContext;
import org.springframework.http.CacheControl;
@@ -48,8 +48,8 @@ public static ResponseEntity okResponse(StreamResponse st
StreamingResponseBody responseStream = outputStream -> streamResponse.getStream().consumeOutputStream(outputStream);
responseHeaders.add("Content-Type", streamResponse.getStream().getMediaType());
- responseHeaders.add(HttpHeaders.CONTENT_DISPOSITION,
- "attachment; filename=\"" + streamResponse.getStream().getFileName() + "\"");
+ responseHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\""
+ + URLEncoder.encode(streamResponse.getStream().getFileName(), StandardCharsets.UTF_8) + "\"");
responseHeaders.add("Content-Length", String.valueOf(streamResponse.getStream().getSize()));
Date lastModifiedDate = streamResponse.getStream().getLastModified();
@@ -71,8 +71,8 @@ public static ResponseEntity rangeResponse(HttpHeaders he
if (headers.getRange().isEmpty()) {
responseStream = consumesOutputStream::consumeOutputStream;
responseHeaders.add("Content-Type", consumesOutputStream.getMediaType());
- responseHeaders.add(HttpHeaders.CONTENT_DISPOSITION,
- "attachment; filename=\"" + consumesOutputStream.getFileName() + "\"");
+ responseHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\""
+ + URLEncoder.encode(consumesOutputStream.getFileName(), StandardCharsets.UTF_8) + "\"");
responseHeaders.add("Content-Length", String.valueOf(consumesOutputStream.getSize()));
return ResponseEntity.ok().headers(responseHeaders).body(responseStream);
@@ -86,7 +86,7 @@ public static ResponseEntity rangeResponse(HttpHeaders he
responseHeaders.add(HttpHeaders.CONTENT_TYPE, consumesOutputStream.getMediaType());
responseHeaders.add(HttpHeaders.CONTENT_LENGTH, contentLength);
responseHeaders.add(HttpHeaders.CONTENT_DISPOSITION,
- "inline; filename=\"" + consumesOutputStream.getFileName() + "\"");
+ "inline; filename=\"" + URLEncoder.encode(consumesOutputStream.getFileName(), StandardCharsets.UTF_8) + "\"");
responseHeaders.add(HttpHeaders.ACCEPT_RANGES, "bytes");
responseHeaders.add(HttpHeaders.CONTENT_RANGE,
"bytes" + " " + start + "-" + end + "/" + consumesOutputStream.getSize());
@@ -105,26 +105,26 @@ public static ResponseEntity rangeResponse(HttpHeaders he
}
public static StreamResponse download(RequestContext requestContext, IsRODAObject object, String... pathPartials)
- throws GenericException, RequestNotValidException, NotFoundException, AuthorizationDeniedException {
+ throws GenericException, RequestNotValidException, NotFoundException, AuthorizationDeniedException {
return download(requestContext, object, null, false, pathPartials);
}
public static StreamResponse download(RequestContext requestContext, LiteRODAObject lite, String... pathPartials)
- throws GenericException, RequestNotValidException, NotFoundException, AuthorizationDeniedException {
- return download(requestContext,lite, null, false, pathPartials);
+ throws GenericException, RequestNotValidException, NotFoundException, AuthorizationDeniedException {
+ return download(requestContext, lite, null, false, pathPartials);
}
- public static StreamResponse download(RequestContext requestContext, IsRODAObject object, String fileName, boolean addTopDirectory,
- String... pathPartials)
- throws GenericException, RequestNotValidException, NotFoundException, AuthorizationDeniedException {
+ public static StreamResponse download(RequestContext requestContext, IsRODAObject object, String fileName,
+ boolean addTopDirectory, String... pathPartials)
+ throws GenericException, RequestNotValidException, NotFoundException, AuthorizationDeniedException {
ModelService model = requestContext.getModelService();
ConsumesOutputStream download = model.exportObjectToStream(object, fileName, addTopDirectory, pathPartials);
return new StreamResponse(download);
}
- public static StreamResponse download(RequestContext requestContext, LiteRODAObject lite, String fileName, boolean addTopDirectory,
- String... pathPartials)
- throws GenericException, RequestNotValidException, NotFoundException, AuthorizationDeniedException {
+ public static StreamResponse download(RequestContext requestContext, LiteRODAObject lite, String fileName,
+ boolean addTopDirectory, String... pathPartials)
+ throws GenericException, RequestNotValidException, NotFoundException, AuthorizationDeniedException {
ModelService model = requestContext.getModelService();
ConsumesOutputStream download = model.exportObjectToStream(lite, fileName, addTopDirectory, pathPartials);
return new StreamResponse(download);
@@ -136,8 +136,8 @@ public static StreamResponse download(RequestContext requestContext, LiteRODAObj
* values are provided.
*/
public static Pair processPagingParams(String start, String limit) {
- Integer startInteger;
- Integer limitInteger;
+ int startInteger;
+ int limitInteger;
try {
startInteger = Integer.parseInt(start);
if (startInteger < 0) {
diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/BrowseDIP.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/BrowseDIP.java
index 0462cb705c..1ca05ab09f 100644
--- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/BrowseDIP.java
+++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/BrowseDIP.java
@@ -36,7 +36,10 @@
import org.roda.core.data.v2.ip.IndexedRepresentation;
import org.roda.core.data.v2.ip.RepresentationLink;
import org.roda.wui.client.browse.tabs.BrowseDIPTabs;
+import org.roda.wui.client.common.ActionsToolbar;
import org.roda.wui.client.common.BrowseDIPActionsToolbar;
+import org.roda.wui.client.common.BrowseDIPFileActionsToolbar;
+import org.roda.wui.client.common.BrowseObjectActionsToolbar;
import org.roda.wui.client.common.NavigationToolbar;
import org.roda.wui.client.common.NoAsyncCallback;
import org.roda.wui.client.common.UserLogin;
@@ -269,6 +272,8 @@ private void applyWhenIndexedFile(Services services, String historyDipUUID, Stri
.fileResource(s -> s.retrieveIndexedFileViaRequest(request));
CompletableFuture indexedAIPCompletableFuture = services
.aipResource(s -> s.findByUuid(request.getAipId(), LocaleInfo.getCurrentLocale().getLocaleName()));
+ CompletableFuture indexedRepresentationCompletableFuture = services
+ .representationResource(s -> s.retrieveIndexedRepresentationViaRequest(request));
CompletableFuture showEmbeddedDIPFuture = services
.configurationsResource(ConfigurationRestService::retrieveShowEmbeddedDIP).exceptionally(throwable1 -> false);
@@ -279,11 +284,13 @@ private void applyWhenIndexedFile(Services services, String historyDipUUID, Stri
indexedFileCompletableFuture, showEmbeddedDIPFuture).thenApply(v -> {
BrowseDIPResponse response = new BrowseDIPResponse();
IndexedAIP indexedAIP = indexedAIPCompletableFuture.join();
+ IndexedRepresentation indexedRepresentation = indexedRepresentationCompletableFuture.join();
IndexedFile indexedFile = indexedFileCompletableFuture.join();
IndexResult dipFileIndexResult = retrieveDIPFileCompletableFuture.join();
response.setIndexedAIP(indexedAIP);
response.setPermissions(indexedAIP.getPermissions());
+ response.setIndexedRepresentation(indexedRepresentation);
response.setIndexedFile(indexedFile);
response.setReferred(indexedFile);
response.setDip(indexedDIP);
@@ -331,8 +338,8 @@ private void errorRedirect(AsyncCallback callback) {
FlowPanel container;
@UiField
NavigationToolbar navigationToolbar;
- @UiField
- BrowseDIPActionsToolbar objectToolbar;
+ @UiField(provided = true)
+ ActionsToolbar objectToolbar;
@UiField
BrowseDIPTabs browseTab;
@@ -351,6 +358,17 @@ public BrowseDIP(Viewers viewers, BrowseDIPResponse response, Services services)
IndexedDIP dip = response.getDip();
DIPFile dipFile = response.getDipFile();
+ if (dipFile != null) {
+ BrowseObjectActionsToolbar toolbar = new BrowseDIPFileActionsToolbar();
+ toolbar.setObjectAndBuild(dipFile, response.getPermissions(), handler);
+ objectToolbar = toolbar;
+
+ } else {
+ BrowseObjectActionsToolbar toolbar = new BrowseDIPActionsToolbar();
+ toolbar.setObjectAndBuild(dip, dip.getPermissions(), handler);
+ objectToolbar = toolbar;
+ }
+
initWidget(uiBinder.createAndBindUi(this));
navigationToolbar.withObject(dipFile != null ? dipFile : dip);
@@ -381,8 +399,6 @@ public BrowseDIP(Viewers viewers, BrowseDIPResponse response, Services services)
navigationToolbar.withAlternativeStyle(true);
}
- objectToolbar.setObjectAndBuild(dip, dip.getPermissions(), handler);
-
browseTab.init(viewers, response, handler);
keyboardFocus.setFocus(true);
diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/BrowseDIP.ui.xml b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/BrowseDIP.ui.xml
index a8b31cd583..d76caf14d4 100644
--- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/BrowseDIP.ui.xml
+++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/BrowseDIP.ui.xml
@@ -10,7 +10,7 @@
-
+
diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/DipFilePreview.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/DipFilePreview.java
index 1e2fb501ac..06e60546f8 100644
--- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/DipFilePreview.java
+++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/DipFilePreview.java
@@ -19,7 +19,6 @@
import org.roda.wui.common.client.tools.RestUtils;
import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.Widget;
import config.i18n.client.ClientMessages;
@@ -32,15 +31,10 @@ public class DipFilePreview extends BitstreamPreview {
private static final ClientMessages messages = GWT.create(ClientMessages.class);
public DipFilePreview(Viewers viewers, DIPFile dipFile) {
- super(viewers, RestUtils.createDipFileDownloadUri(dipFile.getUUID(), CONTENT_DISPOSITION_INLINE), NO_FORMAT,
+ super(viewers, RestUtils.createDipFilePreviewUri(dipFile.getUUID(), CONTENT_DISPOSITION_INLINE), NO_FORMAT,
dipFile.getId(), dipFile.getSize(), dipFile.isDirectory(), dipFile);
}
- public DipFilePreview(Viewers viewers, DIPFile dipFile, Command onPreviewFailure) {
- super(viewers, RestUtils.createDipFileDownloadUri(dipFile.getUUID(), CONTENT_DISPOSITION_INLINE), NO_FORMAT,
- dipFile.getId(), dipFile.getSize(), dipFile.isDirectory(), onPreviewFailure, dipFile);
- }
-
@Override
protected Widget directoryPreview() {
final Filter filter = new Filter(
diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/IndexedFilePreview.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/IndexedFilePreview.java
index b16b9e3843..171fd97f20 100644
--- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/IndexedFilePreview.java
+++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/IndexedFilePreview.java
@@ -40,7 +40,7 @@ public class IndexedFilePreview extends BitstreamPreview {
public IndexedFilePreview(Viewers viewers, IndexedFile file, boolean isAvailable, boolean justActive, AIPState state,
Permissions permissions, Command onPreviewFailure) {
- super(viewers, RestUtils.createRepresentationFileDownloadUri(file.getUUID(), CONTENT_DISPOSITION_INLINE),
+ super(viewers, RestUtils.createRepresentationFilePreviewUri(file.getUUID(), CONTENT_DISPOSITION_INLINE),
file.getFileFormat(), file.getOriginalName() != null ? file.getOriginalName() : file.getId(), file.getSize(),
file.isDirectory(), isAvailable, onPreviewFailure, file, justActive, state, permissions);
}
diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/tabs/BrowseDIPTabs.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/tabs/BrowseDIPTabs.java
index ed937ca52f..f204043980 100644
--- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/tabs/BrowseDIPTabs.java
+++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/tabs/BrowseDIPTabs.java
@@ -47,7 +47,7 @@ public void init(Viewers viewers, BrowseDIPResponse browseDIPResponse,
DIPFile dipFile = browseDIPResponse.getDipFile();
// DIPFile preview
- createAndAddTab(SafeHtmlUtils.fromSafeConstant(messages.descriptiveMetadataTab()), new TabContentBuilder() {
+ createAndAddTab(SafeHtmlUtils.fromSafeConstant(messages.viewTab()), new TabContentBuilder() {
@Override
public Widget buildTabWidget() {
if (dipFile != null) {
diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/common/BrowseDIPFileActionsToolbar.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/common/BrowseDIPFileActionsToolbar.java
new file mode 100644
index 0000000000..666a3122a1
--- /dev/null
+++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/common/BrowseDIPFileActionsToolbar.java
@@ -0,0 +1,36 @@
+package org.roda.wui.client.common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.roda.core.data.common.RodaConstants;
+import org.roda.core.data.v2.ip.DIPFile;
+import org.roda.wui.client.common.actions.DisseminationFileActions;
+import org.roda.wui.client.common.actions.model.ActionableObject;
+import org.roda.wui.client.common.actions.widgets.ActionableWidgetBuilder;
+import org.roda.wui.common.client.tools.ConfigurationManager;
+
+/**
+ *
+ * @author Eduardo Teixeira
+ */
+public class BrowseDIPFileActionsToolbar extends BrowseObjectActionsToolbar {
+ public void buildIcon() {
+ setIcon(ConfigurationManager.getString(RodaConstants.UI_ICONS_CLASS, DIPFile.class.getSimpleName()));
+ }
+
+ public void buildTags() {
+ // do nothing
+ }
+
+ public void buildActions() {
+ this.actions.clear();
+ // AIP actions
+ DisseminationFileActions dipFileActions;
+ dipFileActions = DisseminationFileActions.get(actionPermissions);
+ this.actions.add(new ActionableWidgetBuilder(dipFileActions).withActionCallback(actionCallback)
+ .buildGroupedListWithObjects(new ActionableObject<>(object), new ArrayList<>(),
+ List.of(DisseminationFileActions.DisseminationFileAction.DOWNLOAD)));
+
+ }
+}
diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/common/client/tools/RestUtils.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/common/client/tools/RestUtils.java
index 69c9ac3925..7221fbc2fc 100644
--- a/roda-ui/roda-wui/src/main/java/org/roda/wui/common/client/tools/RestUtils.java
+++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/common/client/tools/RestUtils.java
@@ -84,11 +84,7 @@ public static SafeUri createRepresentationOtherMetadataDownloadUri(String aipId,
return UriUtils.fromSafeConstant(b.toString());
}
- public static SafeUri createRepresentationFileDownloadUri(String fileUuid) {
- return createRepresentationFileDownloadUri(fileUuid, false);
- }
-
- public static SafeUri createRepresentationFileDownloadUri(String fileUuid, boolean contentDispositionInline) {
+ public static SafeUri createRepresentationFilePreviewUri(String fileUuid, boolean contentDispositionInline) {
// api/v2/files/{file_uuid}/preview
String b = RodaConstants.API_REST_V2_FILES + URL.encodeQueryString(fileUuid)
+ RodaConstants.API_REST_V2_PREVIEW_HANDLER;
@@ -96,6 +92,14 @@ public static SafeUri createRepresentationFileDownloadUri(String fileUuid, boole
return UriUtils.fromSafeConstant(b);
}
+ public static SafeUri createRepresentationFileDownloadUri(String fileUuid){
+ // api/v2/files/{file_uuid}/download
+ StringBuilder b = new StringBuilder();
+ b.append(RodaConstants.API_REST_V2_FILES).append(URL.encodeQueryString(fileUuid)).append(RodaConstants.API_REST_V2_DOWNLOAD_HANDLER);
+
+ return UriUtils.fromSafeConstant(b.toString());
+ }
+
public static SafeUri createDipDownloadUri(String dipUUID) {
// api/v2/dips/{uuid}/download
StringBuilder b = new StringBuilder();
@@ -105,23 +109,22 @@ public static SafeUri createDipDownloadUri(String dipUUID) {
return UriUtils.fromSafeConstant(b.toString());
}
- public static SafeUri createDipFileDownloadUri(String dipFileUUID) {
- return createDipFileDownloadUri(dipFileUUID, false);
- }
-
- public static SafeUri createDipFileDownloadUri(String dipFileUUID, boolean contentDispositionInline) {
-
- // api/v1/dipfiles/{file_uuid}?acceptFormat=bin&inline={inline}
+ public static SafeUri createDipFilePreviewUri(String dipFileUUID, boolean contentDispositionInline) {
+ // api/v2/dip-files/{file_uuid}/preview?inline={inline}
StringBuilder b = new StringBuilder();
// base uri
- b.append(RodaConstants.API_REST_V1_DIPFILES).append(URL.encodeQueryString(dipFileUUID));
- // accept format attribute
- b.append(RodaConstants.API_QUERY_START).append(RodaConstants.API_QUERY_KEY_ACCEPT_FORMAT)
- .append(RodaConstants.API_QUERY_ASSIGN_SYMBOL).append(RodaConstants.API_QUERY_VALUE_ACCEPT_FORMAT_BIN);
-
- b.append(RodaConstants.API_QUERY_SEP).append(RodaConstants.API_QUERY_KEY_INLINE)
- .append(RodaConstants.API_QUERY_ASSIGN_SYMBOL).append(contentDispositionInline);
+ b.append(RodaConstants.API_REST_V2_DIPFILES).append(URL.encodeQueryString(dipFileUUID))
+ .append(RodaConstants.API_REST_V2_PREVIEW_HANDLER).append(RodaConstants.API_QUERY_START)
+ .append(RodaConstants.API_QUERY_KEY_INLINE).append(RodaConstants.API_QUERY_ASSIGN_SYMBOL)
+ .append(contentDispositionInline);
+ return UriUtils.fromSafeConstant(b.toString());
+ }
+ public static SafeUri createDipFileDownloadUri(String dipFileUUID){
+ // api/v2/dip-files/{file_uuid}/download
+ StringBuilder b = new StringBuilder();
+ b.append(RodaConstants.API_REST_V2_DIPFILES).append(URL.encodeQueryString(dipFileUUID))
+ .append(RodaConstants.API_REST_V2_DOWNLOAD_HANDLER);
return UriUtils.fromSafeConstant(b.toString());
}
diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/filter/OnOffFilter.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/filter/OnOffFilter.java
index 3d958437db..b6d5819fbf 100644
--- a/roda-ui/roda-wui/src/main/java/org/roda/wui/filter/OnOffFilter.java
+++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/filter/OnOffFilter.java
@@ -14,6 +14,12 @@
import java.util.Iterator;
import java.util.List;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.lang3.StringUtils;
+import org.roda.core.RodaCoreFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
@@ -22,12 +28,6 @@
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.lang3.StringUtils;
-import org.roda.core.RodaCoreFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
/**
* A filter that can be turned on/off using RODA configuration file.
*/
@@ -116,13 +116,14 @@ private boolean isConfigAvailable() {
*/
private void initInnerFilter() throws ServletException {
final Configuration rodaConfig = RodaCoreFactory.getRodaConfiguration();
- if (rodaConfig == null) {
+ final String innerFilterClass = this.webXmlFilterConfig.getInitParameter(PARAM_INNER_FILTER_CLASS);
+ final String configPrefix = this.webXmlFilterConfig.getInitParameter(PARAM_CONFIG_PREFIX);
+ final String configKey = configPrefix + ".enabled";
+ if (rodaConfig == null || !rodaConfig.containsKey(configKey)) {
LOGGER.info("RODA configuration not available yet. Delaying init of {}.",
this.webXmlFilterConfig.getInitParameter(PARAM_INNER_FILTER_CLASS));
} else {
- final String innerFilterClass = this.webXmlFilterConfig.getInitParameter(PARAM_INNER_FILTER_CLASS);
- final String configPrefix = this.webXmlFilterConfig.getInitParameter(PARAM_CONFIG_PREFIX);
- if (rodaConfig.getBoolean(configPrefix + ".enabled", false)) {
+ if (rodaConfig.getBoolean(configKey, false)) {
try {
this.innerFilter = (Filter) Class.forName(innerFilterClass).newInstance();
this.innerFilter.init(getFilterConfig());
@@ -134,8 +135,8 @@ private void initInnerFilter() throws ServletException {
} else {
this.isOn = false;
}
+ LOGGER.info("{} is {}", getFilterConfig().getFilterName(), (this.isOn ? "ON" : "OFF"));
}
- LOGGER.info("{} is {}", getFilterConfig().getFilterName(), (this.isOn ? "ON" : "OFF"));
}
/**