diff --git a/config/alfresco/public-rest-context.xml b/config/alfresco/public-rest-context.xml index a2d7488a76..7e41d59118 100644 --- a/config/alfresco/public-rest-context.xml +++ b/config/alfresco/public-rest-context.xml @@ -442,10 +442,24 @@ + + + + application/pdf + image/jpeg + image/gif + image/png + image/tiff + image/bmp + + + + + diff --git a/source/java/org/alfresco/rest/api/impl/NodesImpl.java b/source/java/org/alfresco/rest/api/impl/NodesImpl.java index 46f15b9fd5..b9ef1d8737 100644 --- a/source/java/org/alfresco/rest/api/impl/NodesImpl.java +++ b/source/java/org/alfresco/rest/api/impl/NodesImpl.java @@ -109,6 +109,10 @@ import java.util.Set; /** * Centralises access to file/folder/node services and maps between representations. + * + * Note: + * This class was originally used for returning some basic node info when listing Favourites. + * It has now been re-purposed and extended to implement the new File Folder (RESTful) API. * * @author steveglover * @author janv @@ -147,6 +151,12 @@ public class NodesImpl implements Nodes private Set defaultIgnoreTypes; private Set ignoreTypeQNames; + private Set nonAttachContentTypes = Collections.EMPTY_SET; // pre-configured whitelist, eg. images & pdf + + public void setNonAttachContentTypes(Set nonAttachWhiteList) { + this.nonAttachContentTypes = nonAttachWhiteList; + } + public void init() { this.namespaceService = sr.getNamespaceService(); @@ -1161,14 +1171,36 @@ public class NodesImpl implements Nodes throw new InvalidArgumentException("NodeId of content is expected: "+nodeRef); } - ContentData cd = (ContentData)nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT); + Map nodeProps = nodeService.getProperties(nodeRef); + ContentData cd = (ContentData)nodeProps.get(ContentModel.PROP_CONTENT); + String name = (String)nodeProps.get(ContentModel.PROP_NAME); + org.alfresco.rest.framework.resource.content.ContentInfo ci = null; if (cd != null) { ci = new org.alfresco.rest.framework.resource.content.ContentInfoImpl(cd.getMimetype(), cd.getEncoding(), cd.getSize(), cd.getLocale()); } - // TODO attachment header - update (or extend ?) REST fwk - return new NodeBinaryResource(nodeRef, ContentModel.PROP_CONTENT, ci); + // By default set attachment header (with filename) unless attachment=false *and* content type is pre-configured as non-attach + boolean attach = true; + String attachment = parameters.getParameter("attachment"); + if (attachment != null) + { + Boolean a = new Boolean(attachment); + if ((a != null) && (a == false)) + { + if (nonAttachContentTypes.contains(cd.getMimetype())) + { + attach = false; + } + else + { + logger.warn("Ignored attachment=false for "+fileNodeId+" since "+cd.getMimetype()+" is not in the whitelist for non-attach content types"); + } + } + } + String attachFileName = (attach ? name : null); + + return new NodeBinaryResource(nodeRef, ContentModel.PROP_CONTENT, ci, attachFileName); } @Override diff --git a/source/java/org/alfresco/rest/framework/resource/content/NodeBinaryResource.java b/source/java/org/alfresco/rest/framework/resource/content/NodeBinaryResource.java index 0ca740493a..4cda2ce902 100755 --- a/source/java/org/alfresco/rest/framework/resource/content/NodeBinaryResource.java +++ b/source/java/org/alfresco/rest/framework/resource/content/NodeBinaryResource.java @@ -39,13 +39,16 @@ public class NodeBinaryResource implements BinaryResource final NodeRef nodeRef; final QName propertyQName; final ContentInfo contentInfo; + final String attachFileName; - public NodeBinaryResource(NodeRef nodeRef, QName propertyQName, ContentInfo contentInfo) + public NodeBinaryResource(NodeRef nodeRef, QName propertyQName, ContentInfo contentInfo, String attachFileName) { super(); + this.nodeRef = nodeRef; this.propertyQName = propertyQName; this.contentInfo = contentInfo; + this.attachFileName = attachFileName; } public NodeRef getNodeRef() @@ -61,4 +64,8 @@ public class NodeBinaryResource implements BinaryResource public ContentInfo getContentInfo() { return this.contentInfo; } + + public String getAttachFileName() { + return this.attachFileName; + } } diff --git a/source/java/org/alfresco/rest/framework/webscripts/AbstractResourceWebScript.java b/source/java/org/alfresco/rest/framework/webscripts/AbstractResourceWebScript.java index 274e5d3b29..88652b18ae 100644 --- a/source/java/org/alfresco/rest/framework/webscripts/AbstractResourceWebScript.java +++ b/source/java/org/alfresco/rest/framework/webscripts/AbstractResourceWebScript.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Remote API - * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited - * %% - * This file is part of the Alfresco software. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - * #L% - */ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ package org.alfresco.rest.framework.webscripts; import java.io.IOException; @@ -48,6 +48,7 @@ import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.JsonGenerator; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; +import org.springframework.extensions.surf.util.URLEncoder; import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.WebScriptException; import org.springframework.extensions.webscripts.WebScriptRequest; @@ -64,6 +65,7 @@ import org.springframework.http.HttpMethod; * 5) Renders the response * * @author Gethin James + * @author janv */ // TODO for requests that pass in input streams e.g. binary content for workflow, this is going to need a way to re-read the input stream a la // code in RepositoryContainer due to retrying transaction logic @@ -77,6 +79,8 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements private ContentStreamer streamer; protected ResourceWebScriptHelper helper; + public final static String HDR_NAME_CONTENT_DISPOSITION = "Content-Disposition"; + @SuppressWarnings("rawtypes") @Override public void execute(final Api api, final WebScriptRequest req, final WebScriptResponse res) throws IOException @@ -97,6 +101,17 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements { respons.put("toSerialize", result); respons.put("contentInfo", contentInfo); + + if (result instanceof NodeBinaryResource) + { + String attachFileName = ((NodeBinaryResource)result).getAttachFileName(); + if ((attachFileName != null) && (attachFileName.length() > 0)) + { + String headerValue = "attachment; filename=\"" + attachFileName + "\"; filename*=UTF-8''" + URLEncoder.encode(attachFileName); + res.setHeader(HDR_NAME_CONTENT_DISPOSITION, headerValue); + } + } + if (params.getStatus().getRedirect()) { res.setStatus(params.getStatus().getCode());