diff --git a/remote-api/src/main/java/org/alfresco/rest/api/DeletedNodes.java b/remote-api/src/main/java/org/alfresco/rest/api/DeletedNodes.java index 09609ae77d..b86ad82a3b 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/DeletedNodes.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/DeletedNodes.java @@ -111,7 +111,7 @@ public interface DeletedNodes */ default DirectAccessUrl requestContentDirectUrl(String archivedId, String renditionId, boolean attachment) { - return requestContentDirectUrl(archivedId, renditionId, attachment, null); + return requestContentDirectUrl(archivedId, renditionId, attachment, null, null); } /** @@ -121,8 +121,9 @@ public interface DeletedNodes * @param renditionId The rendition id for which to obtain the direct access {@code URL} * @param attachment {@code true} if an attachment {@code URL} is requested, {@code false} for an embedded {@code URL}, {@code true} by default. * @param validFor The time at which the direct access {@code URL} will expire. + * @param fileName Optional overide for file name * @return A direct access {@code URL} object for the content. */ - DirectAccessUrl requestContentDirectUrl(String archivedId, String renditionId, boolean attachment, Long validFor); + DirectAccessUrl requestContentDirectUrl(String archivedId, String renditionId, boolean attachment, Long validFor, String fileName); } diff --git a/remote-api/src/main/java/org/alfresco/rest/api/DirectAccessUrlHelper.java b/remote-api/src/main/java/org/alfresco/rest/api/DirectAccessUrlHelper.java index 93d49d3c93..028fa504f8 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/DirectAccessUrlHelper.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/DirectAccessUrlHelper.java @@ -63,4 +63,15 @@ public class DirectAccessUrlHelper } return attachment; } + + + public String getFileName(DirectAccessUrlRequest directAccessUrlRequest) + { + String fileName = null; + if (directAccessUrlRequest != null ) + { + fileName = directAccessUrlRequest.getFileName(); + } + return fileName; + } } diff --git a/remote-api/src/main/java/org/alfresco/rest/api/Nodes.java b/remote-api/src/main/java/org/alfresco/rest/api/Nodes.java index a0f527b441..efad25fb42 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/Nodes.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/Nodes.java @@ -301,7 +301,7 @@ public interface Nodes */ default DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment) { - return requestContentDirectUrl(nodeRef, attachment, null); + return requestContentDirectUrl(nodeRef, attachment, null, null); } /** @@ -313,7 +313,7 @@ public interface Nodes */ default DirectAccessUrl requestContentDirectUrl(String nodeId, boolean attachment, Long validFor) { - return requestContentDirectUrl(validateNode(nodeId), attachment, validFor); + return requestContentDirectUrl(validateNode(nodeId), attachment, validFor, null); } /** @@ -321,9 +321,10 @@ public interface Nodes * @param nodeRef The node reference for which to obtain the direct access {@code URL} * @param attachment {@code true} if an attachment {@code URL} is requested, {@code false} for an embedded {@code URL}. * @param validFor The time at which the direct access {@code URL} will expire. + * @param fileName Optional name for the file when downloaded * @return A direct access {@code URL} object for the content. */ - DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor); + DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor, String fileName); /** * Convert from node properties (map of QName to Serializable) retrieved from diff --git a/remote-api/src/main/java/org/alfresco/rest/api/Renditions.java b/remote-api/src/main/java/org/alfresco/rest/api/Renditions.java index ebcece08ef..56dd06482c 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/Renditions.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/Renditions.java @@ -234,7 +234,7 @@ public interface Renditions default DirectAccessUrl requestContentDirectUrl(String nodeId, String versionId, String renditionId, boolean attachment, Long validFor) { NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId); - return requestContentDirectUrl(nodeRef, versionId, renditionId, attachment, validFor); + return requestContentDirectUrl(nodeRef, versionId, renditionId, attachment, validFor, null); } /** @@ -247,7 +247,7 @@ public interface Renditions */ default DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, String versionId, String renditionId, boolean attachment) { - return requestContentDirectUrl(nodeRef, versionId, renditionId, attachment, null); + return requestContentDirectUrl(nodeRef, versionId, renditionId, attachment, null, null); } /** @@ -257,8 +257,9 @@ public interface Renditions * @param renditionId the rendition id * @param attachment {@code true} if an attachment {@code URL} is requested, {@code false} for an embedded {@code URL} * @param validFor the time at which the direct access {@code URL} will expire + * @param fileName optional name for the file when downloaded * @return a direct access {@code URL} object for the content. */ - DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, String versionId, String renditionId, boolean attachment, Long validFor); + DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, String versionId, String renditionId, boolean attachment, Long validFor, String fileName); } diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/DeletedNodesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/DeletedNodesImpl.java index f63de476e2..aa6a7bc2f5 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/DeletedNodesImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/DeletedNodesImpl.java @@ -250,18 +250,18 @@ public class DeletedNodesImpl implements DeletedNodes, RecognizedParamsExtractor * {@inheritDoc} */ @Override - public DirectAccessUrl requestContentDirectUrl(String originalNodeId, String renditionId, boolean attachment, Long validFor) + public DirectAccessUrl requestContentDirectUrl(String originalNodeId, String renditionId, boolean attachment, Long validFor, String fileName) { //First check the node is valid and has been archived. NodeRef validatedNodeRef = nodes.validateNode(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, originalNodeId); if (renditionId != null) { - return renditions.requestContentDirectUrl(validatedNodeRef, null, renditionId, attachment, validFor); + return renditions.requestContentDirectUrl(validatedNodeRef, null, renditionId, attachment, validFor, fileName); } else { - return nodes.requestContentDirectUrl(validatedNodeRef, attachment, validFor); + return nodes.requestContentDirectUrl(validatedNodeRef, attachment, validFor, fileName); } } } diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java index f255e61b63..dc0087982a 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java @@ -3443,9 +3443,9 @@ public class NodesImpl implements Nodes * {@inheritDoc} */ @Override - public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor) + public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor, String fileName) { - DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(nodeRef, ContentModel.PROP_CONTENT, attachment, validFor); + DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(nodeRef, ContentModel.PROP_CONTENT, attachment, validFor, fileName); if (directAccessUrl == null) { throw new DisabledServiceException("Direct access url isn't available."); diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/RenditionsImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/RenditionsImpl.java index 28f4456d1c..dafb14bc81 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/RenditionsImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/RenditionsImpl.java @@ -512,7 +512,7 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware /** * {@inheritDoc} */ - public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, String versionId, String renditionId, boolean attachment, Long validFor) + public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, String versionId, String renditionId, boolean attachment, Long validFor, String fileName) { final NodeRef validatedNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId(), versionId, null); NodeRef renditionNodeRef = getRenditionByName(validatedNodeRef, renditionId, null); @@ -522,7 +522,7 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware throw new NotFoundException("The rendition with id: " + renditionId + " was not found."); } - return nodes.requestContentDirectUrl(renditionNodeRef, attachment, validFor); + return nodes.requestContentDirectUrl(renditionNodeRef, attachment, validFor, fileName); } private BinaryResource getContentImpl(NodeRef nodeRef, String renditionId, Parameters parameters) diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/DirectAccessUrlRequest.java b/remote-api/src/main/java/org/alfresco/rest/api/model/DirectAccessUrlRequest.java index 6dde68adb2..638dbfe9e5 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/model/DirectAccessUrlRequest.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/model/DirectAccessUrlRequest.java @@ -33,6 +33,7 @@ package org.alfresco.rest.api.model; public class DirectAccessUrlRequest { private Boolean attachment; + private String fileName; public Boolean isAttachment() { @@ -43,4 +44,14 @@ public class DirectAccessUrlRequest { this.attachment = attachment; } + + public String getFileName() + { + return fileName; + } + + public void setFileName(String fileName) + { + this.fileName = fileName; + } } diff --git a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeRenditionsRelation.java b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeRenditionsRelation.java index 56d38291a7..9c9d342dcd 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeRenditionsRelation.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeRenditionsRelation.java @@ -137,12 +137,13 @@ public class NodeRenditionsRelation implements RelationshipResourceAction.Readcontent * @param attachment {@code true} if an attachment URL is requested, {@code false} for an embedded {@code URL}. * @param validFor The time at which the direct access {@code URL} will expire. + * @param fileName Optional name for the file when downloaded * @return A direct access {@code URL} object for the content. * @throws UnsupportedOperationException if the store is unable to provide the information. */ @Auditable(parameters = {"nodeRef", "propertyQName", "validFor"}) - DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, QName propertyQName, boolean attachment, Long validFor); + DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, QName propertyQName, boolean attachment, Long validFor, String fileName); /** * Gets a key-value (String-String) collection of storage headers/properties with their respective values for a specific node reference. diff --git a/repository/src/test/java/org/alfresco/repo/content/ContentServiceImplUnitTest.java b/repository/src/test/java/org/alfresco/repo/content/ContentServiceImplUnitTest.java index 3450885101..7221a9f396 100644 --- a/repository/src/test/java/org/alfresco/repo/content/ContentServiceImplUnitTest.java +++ b/repository/src/test/java/org/alfresco/repo/content/ContentServiceImplUnitTest.java @@ -135,7 +135,7 @@ public class ContentServiceImplUnitTest { setupSystemWideDirectAccessConfig(DISABLED); assertThrows(DirectAccessUrlDisabledException.class, () -> { - contentService.requestContentDirectUrl(NODE_REF, PROP_CONTENT_QNAME, true, 20L); + contentService.requestContentDirectUrl(NODE_REF, PROP_CONTENT_QNAME, true, 20L, null); }); verify(mockContentStore, never()).isContentDirectUrlEnabled(); } @@ -146,7 +146,7 @@ public class ContentServiceImplUnitTest setupSystemWideDirectAccessConfig(ENABLED); when(mockContentStore.isContentDirectUrlEnabled()).thenReturn(DISABLED); - DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(NODE_REF, PROP_CONTENT_QNAME,true, 20L); + DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(NODE_REF, PROP_CONTENT_QNAME,true, 20L, null); assertNull(directAccessUrl); verify(mockContentStore, never()).requestContentDirectUrl(anyString(), eq(true), anyString(), anyString(), anyLong()); } @@ -157,7 +157,7 @@ public class ContentServiceImplUnitTest setupSystemWideDirectAccessConfig(ENABLED); when(mockContentStore.isContentDirectUrlEnabled()).thenReturn(ENABLED); - DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(NODE_REF, PROP_CONTENT_QNAME, true, 20L); + DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(NODE_REF, PROP_CONTENT_QNAME, true, 20L, null); assertNull(directAccessUrl); verify(mockContentStore, times(1)).requestContentDirectUrl(anyString(), eq(true), anyString(), anyString(), anyLong()); } diff --git a/repository/src/test/java/org/alfresco/repo/version/ContentServiceImplTest.java b/repository/src/test/java/org/alfresco/repo/version/ContentServiceImplTest.java index 70b232a153..7f6a61c2e7 100644 --- a/repository/src/test/java/org/alfresco/repo/version/ContentServiceImplTest.java +++ b/repository/src/test/java/org/alfresco/repo/version/ContentServiceImplTest.java @@ -164,11 +164,11 @@ public class ContentServiceImplTest extends BaseVersionStoreTest NodeRef nodeRef = this.dbNodeService .createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{test}MyNoContentNode"), TEST_TYPE_QNAME, this.nodeProperties).getChildRef(); - assertNull(contentService.requestContentDirectUrl(nodeRef, QNAME, true, validFor)); + assertNull(contentService.requestContentDirectUrl(nodeRef, QNAME, true, validFor, null)); }); assertThrows("nodeRef is null", IllegalArgumentException.class, () -> { - assertNull(contentService.requestContentDirectUrl(null, null, true, null)); + assertNull(contentService.requestContentDirectUrl(null, null, true, null, null)); }); assertThrows("propertyQName has no content", NullPointerException.class, () -> { @@ -176,13 +176,13 @@ public class ContentServiceImplTest extends BaseVersionStoreTest NodeRef nodeRef = this.dbNodeService .createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{test}MyNoContentNode"), TEST_TYPE_QNAME, this.nodeProperties).getChildRef(); - contentService.requestContentDirectUrl(nodeRef, null, true, validFor); + contentService.requestContentDirectUrl(nodeRef, null, true, validFor, null); }); // Create a node with content NodeRef nodeRef = createNewVersionableNode(); - assertNull(contentService.requestContentDirectUrl(nodeRef, QNAME, true, null)); - assertNull(contentService.requestContentDirectUrl(nodeRef, QNAME, true, validFor)); + assertNull(contentService.requestContentDirectUrl(nodeRef, QNAME, true, null, null)); + assertNull(contentService.requestContentDirectUrl(nodeRef, QNAME, true, validFor, null)); } }