Merge branch 'RED-8848-bp' into 'release/2.349.x'

RED-8848: When cloning a dossier template some flags are not set correctly

See merge request redactmanager/persistence-service!503
This commit is contained in:
Maverick Studer 2024-05-24 14:27:46 +02:00
commit bba2f35fa0
6 changed files with 346 additions and 67 deletions

View File

@ -6,14 +6,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
@ -23,6 +15,13 @@ import com.iqser.red.service.persistence.management.v1.processor.utils.JSONDownl
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DossierTemplateStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DownloadFileType;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@ -123,5 +122,26 @@ public class DossierTemplateEntity {
private DossierTemplateStatus dossierTemplateStatus;
public static DossierTemplateEntity copyDossierTemplateEntityWithoutChildEntities(DossierTemplateEntity dossierTemplateEntity) {
DossierTemplateEntity dossierTemplateCopy = new DossierTemplateEntity();
dossierTemplateCopy.name = dossierTemplateEntity.name;
dossierTemplateCopy.description = dossierTemplateEntity.description;
dossierTemplateCopy.dateAdded = dossierTemplateEntity.dateAdded;
dossierTemplateCopy.dateModified = dossierTemplateEntity.dateModified;
dossierTemplateCopy.createdBy = dossierTemplateEntity.createdBy;
dossierTemplateCopy.modifiedBy = dossierTemplateEntity.modifiedBy;
dossierTemplateCopy.validFrom = dossierTemplateEntity.validFrom;
dossierTemplateCopy.validTo = dossierTemplateEntity.validTo;
dossierTemplateCopy.softDeleteTime = dossierTemplateEntity.softDeleteTime;
dossierTemplateCopy.keepImageMetadata = dossierTemplateEntity.keepImageMetadata;
dossierTemplateCopy.keepHiddenText = dossierTemplateEntity.keepHiddenText;
dossierTemplateCopy.keepOverlappingObjects = dossierTemplateEntity.keepOverlappingObjects;
dossierTemplateCopy.applyDictionaryUpdatesToAllDossiersByDefault = dossierTemplateEntity.applyDictionaryUpdatesToAllDossiersByDefault;
dossierTemplateCopy.ocrByDefault = dossierTemplateEntity.ocrByDefault;
dossierTemplateCopy.removeWatermark = dossierTemplateEntity.removeWatermark;
dossierTemplateCopy.downloadFileTypes = dossierTemplateEntity.downloadFileTypes;
return dossierTemplateCopy;
}
}

View File

@ -4,6 +4,7 @@ import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
@ -72,69 +73,64 @@ public class DossierTemplateCloneService {
dossierTemplatePersistenceService.validateDossierTemplate(cloneDossierTemplateRequest.getName(), cloneDossierTemplateRequest.getDescription());
dossierTemplatePersistenceService.validateDossierTemplateNameIsUnique(cloneDossierTemplateRequest.getName());
DossierTemplateEntity clonedDossierTemplate = new DossierTemplateEntity();
Optional<DossierTemplateEntity> dossierTemplate = dossierTemplateRepository.findById(dossierTemplateId);
if (dossierTemplate.isEmpty()) {
throw new NotFoundException(String.format(DossierTemplatePersistenceService.DOSSIER_TEMPLATE_NOT_FOUND_MESSAGE, dossierTemplateId));
dossierTemplateRepository.findById(dossierTemplateId).ifPresentOrElse(dossierTemplate -> {
}
dossierTemplatePersistenceService.validateDossierTemplateForDuplicateRanks(dossierTemplateId);
OffsetDateTime now = OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS);
clonedDossierTemplate.setId(UUID.randomUUID().toString());
clonedDossierTemplate.setName(cloneDossierTemplateRequest.getName());
clonedDossierTemplate.setDescription(cloneDossierTemplateRequest.getDescription() == null || cloneDossierTemplateRequest.getDescription()
.isEmpty() ? dossierTemplate.getDescription() : cloneDossierTemplateRequest.getDescription());
clonedDossierTemplate.setDateAdded(now);
clonedDossierTemplate.setDateModified(now);
clonedDossierTemplate.setCreatedBy(cloneDossierTemplateRequest.getCloningUserId());
clonedDossierTemplate.setModifiedBy(cloneDossierTemplateRequest.getCloningUserId());
clonedDossierTemplate.setValidFrom(cloneDossierTemplateRequest.getValidFrom() == null ? dossierTemplate.getValidFrom() : cloneDossierTemplateRequest.getValidFrom());
clonedDossierTemplate.setValidTo(cloneDossierTemplateRequest.getValidTo() == null ? dossierTemplate.getValidTo() : cloneDossierTemplateRequest.getValidTo());
clonedDossierTemplate.setSoftDeleteTime(dossierTemplate.getSoftDeleteTime());
clonedDossierTemplate.setDownloadFileTypes(cloneDossierTemplateRequest.getDownloadFileTypes() == null || cloneDossierTemplateRequest.getDownloadFileTypes()
.isEmpty() ? dossierTemplate.getDownloadFileTypes() : cloneDossierTemplateRequest.getDownloadFileTypes());
DossierTemplateEntity clonedDossierTemplate = DossierTemplateEntity.copyDossierTemplateEntityWithoutChildEntities(dossierTemplate.get());
dossierTemplatePersistenceService.validateDossierTemplateForDuplicateRanks(dossierTemplateId);
OffsetDateTime now = OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS);
clonedDossierTemplate.setId(UUID.randomUUID().toString());
clonedDossierTemplate.setName(cloneDossierTemplateRequest.getName());
if (cloneDossierTemplateRequest.getDescription() != null && !cloneDossierTemplateRequest.getDescription().isEmpty()) {
clonedDossierTemplate.setDescription(cloneDossierTemplateRequest.getDescription());
}
clonedDossierTemplate.setDateAdded(now);
clonedDossierTemplate.setDateModified(now);
clonedDossierTemplate.setCreatedBy(cloneDossierTemplateRequest.getCloningUserId());
clonedDossierTemplate.setModifiedBy(cloneDossierTemplateRequest.getCloningUserId());
if (cloneDossierTemplateRequest.getValidFrom() != null) {
clonedDossierTemplate.setValidFrom(cloneDossierTemplateRequest.getValidFrom());
}
if (cloneDossierTemplateRequest.getValidTo() != null) {
clonedDossierTemplate.setValidTo(cloneDossierTemplateRequest.getValidTo());
}
clonedDossierTemplate.setKeepImageMetadata(dossierTemplate.isKeepImageMetadata());
clonedDossierTemplate.setKeepHiddenText(dossierTemplate.isKeepHiddenText());
clonedDossierTemplate.setKeepOverlappingObjects(dossierTemplate.isKeepOverlappingObjects());
clonedDossierTemplate.setApplyDictionaryUpdatesToAllDossiersByDefault(dossierTemplate.isApplyDictionaryUpdatesToAllDossiersByDefault());
//set rules
cloneRules(dossierTemplate.getId(), clonedDossierTemplate.getId());
//set legal basis
cloneLegalBasisMapping(dossierTemplate.getId(), clonedDossierTemplate.getId());
//set rules
cloneRules(dossierTemplateId, clonedDossierTemplate.getId());
//set legal basis
cloneLegalBasisMapping(dossierTemplateId, clonedDossierTemplate.getId());
clonedDossierTemplate.setDossierTemplateStatus(DossierTemplateStatus.valueOf(dossierTemplatePersistenceService.computeDossierTemplateStatus(clonedDossierTemplate)
.name()));
clonedDossierTemplate.setOcrByDefault(cloneDossierTemplateRequest.isOcrByDefault());
clonedDossierTemplate.setRemoveWatermark(cloneDossierTemplateRequest.isRemoveWatermark());
dossierTemplatePersistenceService.insertDossierTemplate(clonedDossierTemplate);
//set dictionaries
cloneDictionariesWithEntries(dossierTemplate.getId(), clonedDossierTemplate.getId());
dossierTemplatePersistenceService.insertDossierTemplate(clonedDossierTemplate);
//set dossier attributes
cloneDossierAttributesConfig(dossierTemplate.getId(), clonedDossierTemplate.getId());
//set dictionaries
cloneDictionariesWithEntries(dossierTemplateId, clonedDossierTemplate.getId());
//set file attributes
cloneFileAttributesGeneralConfig(dossierTemplate.getId(), clonedDossierTemplate.getId());
cloneFileAttributesConfig(dossierTemplate.getId(), clonedDossierTemplate.getId());
//set dossier attributes
cloneDossierAttributesConfig(dossierTemplateId, clonedDossierTemplate.getId());
//set report templates
cloneReportTemplates(dossierTemplate, clonedDossierTemplate.getId());
//set file attributes
cloneFileAttributesGeneralConfig(dossierTemplateId, clonedDossierTemplate.getId());
cloneFileAttributesConfig(dossierTemplateId, clonedDossierTemplate.getId());
//set colors
cloneColors(dossierTemplate.getId(), clonedDossierTemplate.getId());
//set report templates
cloneReportTemplates(dossierTemplateId, clonedDossierTemplate.getId());
//set dossier status
cloneDossierStates(dossierTemplate.getId(), clonedDossierTemplate.getId());
//set colors
cloneColors(dossierTemplateId, clonedDossierTemplate.getId());
// set the watermark configurations
cloneWatermarks(dossierTemplate.getId(), clonedDossierTemplate.getId());
//set dossier status
cloneDossierStates(dossierTemplateId, clonedDossierTemplate.getId());
}, () -> {
throw new NotFoundException(String.format(DossierTemplatePersistenceService.DOSSIER_TEMPLATE_NOT_FOUND_MESSAGE, dossierTemplateId));
});
// set the watermark configurations
cloneWatermarks(dossierTemplateId, clonedDossierTemplate.getId());
return clonedDossierTemplate;
}
@ -241,9 +237,9 @@ public class DossierTemplateCloneService {
@SneakyThrows
private void cloneReportTemplates(DossierTemplateEntity dossierTemplate, String clonedDossierTemplateId) {
private void cloneReportTemplates(String dossierTemplateId, String clonedDossierTemplateId) {
var reportTemplates = reportTemplatePersistenceService.findByDossierTemplateId(dossierTemplate.getId());
var reportTemplates = reportTemplatePersistenceService.findByDossierTemplateId(dossierTemplateId);
for (ReportTemplateEntity rte : reportTemplates) {
if (storageService.objectExists(TenantContext.getTenantId(), rte.getStorageId())) {
var storedReportTemplate = fileManagementStorageService.getObject(TenantContext.getTenantId(), rte.getStorageId());

View File

@ -174,7 +174,7 @@ public class DossierTemplateCloneAndExportWithDuplicateRanksTest {
@SneakyThrows
public void testCloneDossierTemplateWithDuplicateRanks() {
CloneDossierTemplateRequest cdtr = CloneDossierTemplateRequest.builder().name(dossierTemplateName).cloningUserId("user").ocrByDefault(true).removeWatermark(false).build();
CloneDossierTemplateRequest cdtr = CloneDossierTemplateRequest.builder().name(dossierTemplateName).cloningUserId("user").build();
DossierTemplateEntity dossierTemplateEntity = new DossierTemplateEntity();
dossierTemplateEntity.setId(dossierTemplateId);
when(dossierTemplateRepository.existsByName(cdtr.getName())).thenReturn(false);

View File

@ -0,0 +1,272 @@
package com.iqser.red.service.peristence.v1.server.integration.tests;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.when;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.time.OffsetDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.util.ReflectionTestUtils;
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.ColorsEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.FileAttributesGeneralConfigurationEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.LegalBasisEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.RuleSetEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierTemplateEntity;
import com.iqser.red.service.persistence.management.v1.processor.service.ColorsService;
import com.iqser.red.service.persistence.management.v1.processor.service.DossierTemplateCloneService;
import com.iqser.red.service.persistence.management.v1.processor.service.FileManagementStorageService;
import com.iqser.red.service.persistence.management.v1.processor.service.WatermarkService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DictionaryPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierAttributeConfigPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierStatusPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierTemplatePersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.EntryPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileAttributeConfigPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.LegalBasisMappingPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ReportTemplatePersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.RulesPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierTemplateRepository;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.TypeRepository;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.CloneDossierTemplateRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DossierTemplateStatus;
import com.iqser.red.storage.commons.service.StorageService;
import lombok.SneakyThrows;
@ExtendWith(SpringExtension.class)
public class DossierTemplateCloneServiceTest {
@MockBean
private DossierTemplateRepository dossierTemplateRepository;
@MockBean
private LegalBasisMappingPersistenceService legalBasisMappingPersistenceService;
@MockBean
private RulesPersistenceService rulesPersistenceService;
@MockBean
private DossierAttributeConfigPersistenceService dossierAttributeConfigPersistenceService;
@MockBean
private DictionaryPersistenceService dictionaryPersistenceService;
@MockBean
private EntryPersistenceService entryPersistenceService;
@MockBean
private FileAttributeConfigPersistenceService fileAttributeConfigPersistenceService;
@MockBean
private ReportTemplatePersistenceService reportTemplatePersistenceService;
@MockBean
private ColorsService colorsService;
@MockBean
private StorageService storageService;
@MockBean
private DossierStatusPersistenceService dossierStatusPersistenceService;
@MockBean
private WatermarkService watermarkService;
@MockBean
private FileManagementStorageService fileManagementStorageService;
@MockBean
private TypeRepository typeRepository;
private DossierTemplateCloneService dossierTemplateCloneService;
private DossierTemplatePersistenceService dossierTemplatePersistenceService;
private DossierTemplateEntity dummyTemplate;
@BeforeEach
@SneakyThrows
public void setUp() {
dossierTemplatePersistenceService = new DossierTemplatePersistenceService(dictionaryPersistenceService,
dossierTemplateRepository,
legalBasisMappingPersistenceService,
rulesPersistenceService,
typeRepository);
ReflectionTestUtils.setField(dossierTemplatePersistenceService, "applicationType", "RedactManager");
dossierTemplateCloneService = new DossierTemplateCloneService(dossierTemplateRepository,
legalBasisMappingPersistenceService,
rulesPersistenceService,
dossierTemplatePersistenceService,
dossierAttributeConfigPersistenceService,
dictionaryPersistenceService,
entryPersistenceService,
fileAttributeConfigPersistenceService,
reportTemplatePersistenceService,
colorsService,
storageService,
dossierStatusPersistenceService,
watermarkService,
fileManagementStorageService);
dummyTemplate = new DossierTemplateEntity();
setNonDefaultValues(dummyTemplate);
dummyTemplate.setId("dummy-id");
dummyTemplate.setName("dummy-name");
dummyTemplate.setDescription("dummy-description");
dummyTemplate.setDateAdded(OffsetDateTime.now());
dummyTemplate.setDateModified(OffsetDateTime.now());
dummyTemplate.setCreatedBy("dummy-user");
dummyTemplate.setModifiedBy("dummy-user");
dummyTemplate.setValidFrom(OffsetDateTime.now().minusYears(6));
dummyTemplate.setValidTo(OffsetDateTime.now().plusYears(2));
dummyTemplate.setDossierTemplateStatus(DossierTemplateStatus.INACTIVE);
when(dossierTemplateRepository.findById(anyString())).thenReturn(Optional.of(dummyTemplate));
}
@SneakyThrows
private void setNonDefaultValues(Object obj) {
Class<?> clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
Class<?> type = field.getType();
setBasicFieldToOtherValue(obj, field.getName(), type);
}
}
public static void setBasicFieldToOtherValue(Object obj, String fieldName, Class<?> type) throws Exception {
String suffix = Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
String setterName = "set" + suffix;
String getterName = "get" + suffix;
String alternativeGetterName = "is" + suffix;
var getterMethod = findGetterMethod(obj.getClass(), getterName);
var alternativeGetterMethod = findGetterMethod(obj.getClass(), alternativeGetterName);
Object value;
if (getterMethod != null) {
value = getterMethod.invoke(obj);
} else if (alternativeGetterMethod != null) {
value = alternativeGetterMethod.invoke(obj);
} else {
return;
}
if (type.equals(Boolean.class) || type.equals(boolean.class)) {
value = !(Boolean) value;
} else if (type.equals(Integer.class) || type.equals(int.class)) {
value = (Integer) value + 1;
} else if (type.equals(Long.class) || type.equals(long.class)) {
value = (Long) value + 1;
} else if (type.equals(Float.class) || type.equals(float.class)) {
value = (Float) value + 1;
} else if (type.equals(Double.class) || type.equals(double.class)) {
value = (Double) value + 1;
} else if (type.equals(String.class)) {
value = "Modified:" + value;
} else {
return;
}
var setterMethod = findSetterMethod(obj.getClass(), setterName, type);
if (setterMethod != null) {
setterMethod.invoke(obj, value);
}
}
private static Method findSetterMethod(Class<?> clazz, String setterName, Class<?> parameterType) {
var methods = clazz.getMethods();
for (var method : methods) {
if (method.getName().equals(setterName) && method.getParameterCount() == 1) {
if (method.getParameterTypes()[0].isAssignableFrom(parameterType)) {
return method;
}
}
}
return null;
}
private static Method findGetterMethod(Class<?> clazz, String getterName) {
var methods = clazz.getMethods();
for (var method : methods) {
if (method.getName().equals(getterName) && method.getParameterCount() == 0) {
return method;
}
}
return null;
}
@Test
public void testCloneDossierTemplate() {
CloneDossierTemplateRequest request = new CloneDossierTemplateRequest();
request.setName("cloned-name");
request.setDescription("cloned-description");
request.setCloningUserId("cloning-user");
OffsetDateTime validFrom = OffsetDateTime.now();
dummyTemplate.setValidFrom(validFrom);
OffsetDateTime validTo = OffsetDateTime.now().plusYears(4);
dummyTemplate.setValidTo(validTo);
when(rulesPersistenceService.getRules(anyString(), any())).thenReturn(new RuleSetEntity());
when(legalBasisMappingPersistenceService.getLegalBasisMapping(anyString())).thenReturn(List.of(LegalBasisEntity.builder()
.name("dummy-name")
.description("dummy-description")
.reason("dummy-reason")
.build()));
when(dictionaryPersistenceService.getAllTypesForDossierTemplate(anyString(), anyBoolean())).thenReturn(Collections.emptyList());
when(dossierAttributeConfigPersistenceService.getDossierAttributes(anyString())).thenReturn(Collections.emptyList());
when(fileAttributeConfigPersistenceService.getFileAttributesGeneralConfiguration(anyString())).thenReturn(new FileAttributesGeneralConfigurationEntity());
when(fileAttributeConfigPersistenceService.getFileAttributes(anyString())).thenReturn(Collections.emptyList());
when(reportTemplatePersistenceService.findByDossierTemplateId(anyString())).thenReturn(Collections.emptyList());
when(watermarkService.getWatermarksForDossierTemplateId(anyString())).thenReturn(Collections.emptyList());
when(dossierStatusPersistenceService.getAllDossierStatusForTemplate(anyString())).thenReturn(Collections.emptyList());
when(colorsService.getColors(anyString())).thenReturn(new ColorsEntity());
DossierTemplateEntity clonedTemplate = dossierTemplateCloneService.cloneDossierTemplate("dummy-id", request);
assertNotNull(clonedTemplate);
assertEquals("cloned-name", clonedTemplate.getName());
assertEquals("cloned-description", clonedTemplate.getDescription());
assertEquals("cloning-user", clonedTemplate.getCreatedBy());
assertEquals("cloning-user", clonedTemplate.getModifiedBy());
assertEquals(validFrom, clonedTemplate.getValidFrom());
assertEquals(validTo, clonedTemplate.getValidTo());
assertEquals(DossierTemplateStatus.ACTIVE, clonedTemplate.getDossierTemplateStatus());
assertThat(clonedTemplate).usingRecursiveComparison()
.ignoringFields("id", "name", "description", "dateAdded", "dateModified", "createdBy", "modifiedBy", "validFrom", "validTo", "cloningUser", "dossierTemplateStatus")
.isEqualTo(dummyTemplate);
}
}

View File

@ -338,13 +338,9 @@ public class DossierTemplateTest extends AbstractPersistenceServerServiceTest {
CloneDossierTemplateRequest cdtr = CloneDossierTemplateRequest.builder()
.name("Clone of " + dossierTemplate.getName())
.cloningUserId("user")
.ocrByDefault(true)
.removeWatermark(false)
.build();
var clonedDT = dossierTemplateClient.cloneDossierTemplate(dossierTemplate.getId(), cdtr);
assertThat(clonedDT.getName()).isEqualTo("Clone of " + dossierTemplate.getName());
assertThat(clonedDT.isRemoveWatermark()).isFalse();
assertThat(clonedDT.isOcrByDefault()).isTrue();
var loadedTemplate = dossierTemplateClient.getDossierTemplate(clonedDT.getId());
assertThat(loadedTemplate.getId()).isEqualTo(clonedDT.getId());

View File

@ -1,8 +1,6 @@
package com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate;
import java.time.OffsetDateTime;
import java.util.HashSet;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.Builder;
@ -20,8 +18,5 @@ public class CloneDossierTemplateRequest {
private OffsetDateTime validFrom;
private OffsetDateTime validTo;
private String cloningUserId;
private Set<DownloadFileType> downloadFileTypes = new HashSet<>();
private boolean ocrByDefault;
private boolean removeWatermark;
}