mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2)
120084 jkaabimofrad: RA-640, RA-681: made "update node content" API to return the default JSON representation of the file node. Also added a test. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@126380 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -118,8 +118,7 @@ public interface Nodes
|
|||||||
// TODO update REST fwk - to optionally support "attachment" (Content-Disposition) header
|
// TODO update REST fwk - to optionally support "attachment" (Content-Disposition) header
|
||||||
BinaryResource getContent(String fileNodeId, Parameters parameters);
|
BinaryResource getContent(String fileNodeId, Parameters parameters);
|
||||||
|
|
||||||
// TODO update REST fwk - to optionally support return of json
|
Node updateContent(String fileNodeId, BasicContentInfo contentInfo, InputStream stream, Parameters parameters);
|
||||||
void updateContent(String fileNodeId, BasicContentInfo contentInfo, InputStream stream, Parameters parameters);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uploads file content and meta-data into the repository.
|
* Uploads file content and meta-data into the repository.
|
||||||
|
@@ -28,6 +28,7 @@ import org.alfresco.repo.node.getchildren.GetChildrenCannedQuery;
|
|||||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||||
import org.alfresco.rest.antlr.WhereClauseParser;
|
import org.alfresco.rest.antlr.WhereClauseParser;
|
||||||
import org.alfresco.rest.api.Nodes;
|
import org.alfresco.rest.api.Nodes;
|
||||||
|
import org.alfresco.rest.api.model.ContentInfo;
|
||||||
import org.alfresco.rest.api.model.Document;
|
import org.alfresco.rest.api.model.Document;
|
||||||
import org.alfresco.rest.api.model.Folder;
|
import org.alfresco.rest.api.model.Folder;
|
||||||
import org.alfresco.rest.api.model.Node;
|
import org.alfresco.rest.api.model.Node;
|
||||||
@@ -38,7 +39,6 @@ import org.alfresco.rest.framework.core.exceptions.ApiException;
|
|||||||
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
|
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
|
||||||
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
||||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||||
import org.alfresco.rest.framework.core.exceptions.NotFoundException;
|
|
||||||
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
|
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
|
||||||
import org.alfresco.rest.framework.core.exceptions.RequestEntityTooLargeException;
|
import org.alfresco.rest.framework.core.exceptions.RequestEntityTooLargeException;
|
||||||
import org.alfresco.rest.framework.resource.content.BasicContentInfo;
|
import org.alfresco.rest.framework.resource.content.BasicContentInfo;
|
||||||
@@ -86,12 +86,9 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
import org.springframework.extensions.surf.util.Content;
|
import org.springframework.extensions.surf.util.Content;
|
||||||
import org.springframework.extensions.webscripts.servlet.FormData;
|
import org.springframework.extensions.webscripts.servlet.FormData;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.util.AbstractList;
|
import java.util.AbstractList;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -994,10 +991,20 @@ public class NodesImpl implements Nodes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isContent) {
|
if (isContent)
|
||||||
|
{
|
||||||
// add empty file
|
// add empty file
|
||||||
ContentWriter writer = sr.getContentService().getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
|
ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
|
||||||
String mimeType = sr.getMimetypeService().guessMimetype(nodeName);
|
String mimeType;
|
||||||
|
ContentInfo contentInfo = nodeInfo.getContent();
|
||||||
|
if (contentInfo != null && contentInfo.getMimeType() != null)
|
||||||
|
{
|
||||||
|
mimeType = contentInfo.getMimeType();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mimeType = mimetypeService.guessMimetype(nodeName);
|
||||||
|
}
|
||||||
writer.setMimetype(mimeType);
|
writer.setMimetype(mimeType);
|
||||||
writer.putContent("");
|
writer.putContent("");
|
||||||
}
|
}
|
||||||
@@ -1152,34 +1159,34 @@ public class NodesImpl implements Nodes
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateContent(String fileNodeId, BasicContentInfo contentInfo, InputStream stream, Parameters parameters)
|
public Node updateContent(String fileNodeId, BasicContentInfo contentInfo, InputStream stream, Parameters parameters)
|
||||||
{
|
{
|
||||||
final NodeRef nodeRef = validateNode(fileNodeId);
|
final NodeRef nodeRef = validateNode(fileNodeId);
|
||||||
|
|
||||||
if (! nodeMatches(nodeRef, Collections.singleton(ContentModel.TYPE_CONTENT), null))
|
if (!nodeMatches(nodeRef, Collections.singleton(ContentModel.TYPE_CONTENT), null))
|
||||||
{
|
{
|
||||||
throw new InvalidArgumentException("NodeId of content is expected: "+nodeRef);
|
throw new InvalidArgumentException("NodeId of content is expected: " + nodeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentWriter writer = sr.getContentService().getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
|
ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
|
||||||
|
|
||||||
String mimeType = contentInfo.getMimeType();
|
String mimeType = contentInfo.getMimeType();
|
||||||
if (mimeType == null)
|
if (mimeType == null)
|
||||||
{
|
{
|
||||||
String fileName = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
|
String fileName = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
|
||||||
writer.guessMimetype(fileName);
|
writer.guessMimetype(fileName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writer.setMimetype(mimeType);
|
writer.setMimetype(mimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.guessEncoding();
|
writer.guessEncoding();
|
||||||
|
|
||||||
writer.putContent(stream);
|
writer.putContent(stream);
|
||||||
|
|
||||||
// TODO - hmm - we may wish to return json info !!
|
return getFolderOrDocumentFullInfo(nodeRef,
|
||||||
return;
|
getParentNodeRef(nodeRef),
|
||||||
|
nodeService.getType(nodeRef),
|
||||||
|
parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1382,9 +1389,8 @@ public class NodesImpl implements Nodes
|
|||||||
protected void write(NodeRef nodeRef, Content content, String fileName, boolean applyMimeType, boolean guessEncoding)
|
protected void write(NodeRef nodeRef, Content content, String fileName, boolean applyMimeType, boolean guessEncoding)
|
||||||
{
|
{
|
||||||
ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
|
ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
|
||||||
InputStream is;
|
|
||||||
String mimeType = content.getMimetype();
|
String mimeType = content.getMimetype();
|
||||||
// Per RA-637 requirement the mimeType provided by the client takes precedent, however,
|
// Per RA-637 requirement the mimeType provided by the client takes precedence, however,
|
||||||
// if the mimeType is null, then it will be retrieved or guessed.
|
// if the mimeType is null, then it will be retrieved or guessed.
|
||||||
if (mimeType == null || !applyMimeType)
|
if (mimeType == null || !applyMimeType)
|
||||||
{
|
{
|
||||||
@@ -1398,28 +1404,17 @@ public class NodesImpl implements Nodes
|
|||||||
mimeType = mimetypeService.guessMimetype(fileName);
|
mimeType = mimetypeService.guessMimetype(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
writer.setMimetype(mimeType);
|
||||||
|
|
||||||
if (guessEncoding)
|
if (guessEncoding)
|
||||||
{
|
{
|
||||||
is = new BufferedInputStream(content.getInputStream());
|
writer.guessEncoding();
|
||||||
is.mark(1024);
|
|
||||||
|
|
||||||
writer.setEncoding(guessEncoding(is, mimeType));
|
|
||||||
try
|
|
||||||
{
|
|
||||||
is.reset();
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
logger.error("Failed to reset input stream", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writer.setEncoding(content.getEncoding());
|
writer.setEncoding(content.getEncoding());
|
||||||
is = content.getInputStream();
|
|
||||||
}
|
}
|
||||||
writer.setMimetype(mimeType);
|
writer.putContent(content.getInputStream());
|
||||||
writer.putContent(is);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1441,22 +1436,6 @@ public class NodesImpl implements Nodes
|
|||||||
versionService.ensureVersioningEnabled(nodeRef, props);
|
versionService.ensureVersioningEnabled(nodeRef, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Guesses the character encoding of the given inputStream.
|
|
||||||
*/
|
|
||||||
protected String guessEncoding(InputStream in, String mimeType)
|
|
||||||
{
|
|
||||||
String encoding = "UTF-8";
|
|
||||||
|
|
||||||
if (in != null)
|
|
||||||
{
|
|
||||||
Charset charset = mimetypeService.getContentCharsetFinder().getCharset(in, mimeType);
|
|
||||||
encoding = charset.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
return encoding;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts the given node metadata asynchronously.
|
* Extracts the given node metadata asynchronously.
|
||||||
*/
|
*/
|
||||||
|
@@ -45,7 +45,7 @@ import java.io.InputStream;
|
|||||||
@EntityResource(name="nodes", title = "Nodes")
|
@EntityResource(name="nodes", title = "Nodes")
|
||||||
public class NodesEntityResource implements
|
public class NodesEntityResource implements
|
||||||
EntityResourceAction.ReadById<Node>, EntityResourceAction.Delete, EntityResourceAction.Update<Node>,
|
EntityResourceAction.ReadById<Node>, EntityResourceAction.Delete, EntityResourceAction.Update<Node>,
|
||||||
BinaryResourceAction.Read, BinaryResourceAction.Update, InitializingBean
|
BinaryResourceAction.Read, BinaryResourceAction.Update<Node>, InitializingBean
|
||||||
{
|
{
|
||||||
private Nodes nodes;
|
private Nodes nodes;
|
||||||
|
|
||||||
@@ -86,9 +86,9 @@ public class NodesEntityResource implements
|
|||||||
@Override
|
@Override
|
||||||
@WebApiDescription(title = "Upload content", description = "Upload content")
|
@WebApiDescription(title = "Upload content", description = "Upload content")
|
||||||
@BinaryProperties({"content"})
|
@BinaryProperties({"content"})
|
||||||
public void updateProperty(String fileNodeId, BasicContentInfo contentInfo, InputStream stream, Parameters parameters)
|
public Node updateProperty(String fileNodeId, BasicContentInfo contentInfo, InputStream stream, Parameters parameters)
|
||||||
{
|
{
|
||||||
nodes.updateContent(fileNodeId, contentInfo, stream, parameters);
|
return nodes.updateContent(fileNodeId, contentInfo, stream, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -54,7 +54,7 @@ public interface BinaryResourceAction
|
|||||||
/**
|
/**
|
||||||
* HTTP PUT - Updates a binary resource if it exists, error if not
|
* HTTP PUT - Updates a binary resource if it exists, error if not
|
||||||
*/
|
*/
|
||||||
public static interface Update extends ResourceAction
|
public static interface Update<E> extends ResourceAction
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,7 +65,7 @@ public interface BinaryResourceAction
|
|||||||
* @param contentInfo Basic information about the content stream
|
* @param contentInfo Basic information about the content stream
|
||||||
* @param params {@link Parameters}
|
* @param params {@link Parameters}
|
||||||
*/
|
*/
|
||||||
public void updateProperty (String entityId, BasicContentInfo contentInfo, InputStream stream, Parameters params);
|
public E updateProperty (String entityId, BasicContentInfo contentInfo, InputStream stream, Parameters params);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.alfresco.rest.framework.webscripts;
|
package org.alfresco.rest.framework.webscripts;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -6,7 +25,6 @@ import java.util.Locale;
|
|||||||
|
|
||||||
import org.alfresco.repo.content.MimetypeMap;
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
import org.alfresco.repo.web.scripts.BufferedRequest;
|
|
||||||
import org.alfresco.rest.framework.core.ResourceInspector;
|
import org.alfresco.rest.framework.core.ResourceInspector;
|
||||||
import org.alfresco.rest.framework.core.ResourceLocator;
|
import org.alfresco.rest.framework.core.ResourceLocator;
|
||||||
import org.alfresco.rest.framework.core.ResourceMetadata;
|
import org.alfresco.rest.framework.core.ResourceMetadata;
|
||||||
@@ -171,10 +189,8 @@ public class ResourceWebScriptPut extends AbstractResourceWebScript implements P
|
|||||||
{
|
{
|
||||||
throw new DeletedResourceException("(UPDATE) "+resource.getMetaData().getUniqueId());
|
throw new DeletedResourceException("(UPDATE) "+resource.getMetaData().getUniqueId());
|
||||||
}
|
}
|
||||||
BinaryResourceAction.Update binUpdater = (BinaryResourceAction.Update) resource.getResource();
|
BinaryResourceAction.Update<Object> binUpdater = (BinaryResourceAction.Update<Object>) resource.getResource();
|
||||||
binUpdater.updateProperty(params.getEntityId(),params.getContentInfo(), params.getStream(), params);
|
return binUpdater.updateProperty(params.getEntityId(), params.getContentInfo(), params.getStream(), params);
|
||||||
//Don't pass anything to the callback - its just successful
|
|
||||||
return null;
|
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedResourceOperationException("PUT not supported for Actions");
|
throw new UnsupportedResourceOperationException("PUT not supported for Actions");
|
||||||
}
|
}
|
||||||
|
@@ -28,6 +28,7 @@ import org.alfresco.rest.api.tests.RepoService.TestPerson;
|
|||||||
import org.alfresco.rest.api.tests.RepoService.TestSite;
|
import org.alfresco.rest.api.tests.RepoService.TestSite;
|
||||||
import org.alfresco.rest.api.tests.client.HttpResponse;
|
import org.alfresco.rest.api.tests.client.HttpResponse;
|
||||||
import org.alfresco.rest.api.tests.client.PublicApiClient;
|
import org.alfresco.rest.api.tests.client.PublicApiClient;
|
||||||
|
import org.alfresco.rest.api.tests.client.PublicApiHttpClient.BinaryPayload;
|
||||||
import org.alfresco.rest.api.tests.client.RequestContext;
|
import org.alfresco.rest.api.tests.client.RequestContext;
|
||||||
import org.alfresco.service.cmr.site.SiteVisibility;
|
import org.alfresco.service.cmr.site.SiteVisibility;
|
||||||
|
|
||||||
@@ -140,6 +141,27 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected HttpResponse putBinary(String url, int version, String runAsUser, BinaryPayload payload, String queryString, Map<String, String> params,
|
||||||
|
int expectedStatus) throws Exception
|
||||||
|
{
|
||||||
|
publicApiClient.setRequestContext(new RequestContext(runAsUser));
|
||||||
|
if (queryString != null)
|
||||||
|
{
|
||||||
|
url += queryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponse response = publicApiClient.putBinary(getScope(), version, url, null, null, null, payload, params);
|
||||||
|
checkStatus(expectedStatus, response.getStatusCode());
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected HttpResponse putBinary(String url, String runAsUser, BinaryPayload payload, String queryString, Map<String, String> params,
|
||||||
|
int expectedStatus) throws Exception
|
||||||
|
{
|
||||||
|
return putBinary(url, 1, runAsUser, payload, queryString, params, expectedStatus);
|
||||||
|
}
|
||||||
|
|
||||||
protected HttpResponse delete(String url, String runAsUser, String entityId, int expectedStatus) throws Exception
|
protected HttpResponse delete(String url, String runAsUser, String entityId, int expectedStatus) throws Exception
|
||||||
{
|
{
|
||||||
publicApiClient.setRequestContext(new RequestContext(runAsUser));
|
publicApiClient.setRequestContext(new RequestContext(runAsUser));
|
||||||
|
@@ -34,6 +34,7 @@ import org.alfresco.repo.model.Repository;
|
|||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
import org.alfresco.rest.api.Nodes;
|
import org.alfresco.rest.api.Nodes;
|
||||||
|
import org.alfresco.rest.api.tests.client.PublicApiHttpClient.BinaryPayload;
|
||||||
import org.alfresco.rest.api.tests.client.data.ContentInfo;
|
import org.alfresco.rest.api.tests.client.data.ContentInfo;
|
||||||
import org.alfresco.rest.api.tests.client.data.Document;
|
import org.alfresco.rest.api.tests.client.data.Document;
|
||||||
import org.alfresco.rest.api.tests.client.data.Folder;
|
import org.alfresco.rest.api.tests.client.data.Folder;
|
||||||
@@ -62,6 +63,7 @@ import org.alfresco.service.cmr.security.MutableAuthenticationService;
|
|||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.alfresco.service.cmr.security.PersonService;
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.alfresco.service.cmr.site.SiteVisibility;
|
import org.alfresco.service.cmr.site.SiteVisibility;
|
||||||
|
import org.alfresco.util.TempFileProvider;
|
||||||
import org.codehaus.jackson.map.ObjectMapper;
|
import org.codehaus.jackson.map.ObjectMapper;
|
||||||
import org.codehaus.jackson.map.annotate.JsonSerialize;
|
import org.codehaus.jackson.map.annotate.JsonSerialize;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
@@ -69,6 +71,7 @@ import org.junit.Before;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.util.ResourceUtils;
|
import org.springframework.util.ResourceUtils;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -130,7 +133,7 @@ public class NodeApiTest extends AbstractBaseApiTest
|
|||||||
repositoryHelper = applicationContext.getBean("repositoryHelper", Repository.class);
|
repositoryHelper = applicationContext.getBean("repositoryHelper", Repository.class);
|
||||||
jacksonUtil = new JacksonUtil(applicationContext.getBean("jsonHelper", JacksonHelper.class));
|
jacksonUtil = new JacksonUtil(applicationContext.getBean("jsonHelper", JacksonHelper.class));
|
||||||
permissionService = applicationContext.getBean("permissionService", PermissionService.class);
|
permissionService = applicationContext.getBean("permissionService", PermissionService.class);
|
||||||
|
|
||||||
user1 = createUser("user1" + System.currentTimeMillis());
|
user1 = createUser("user1" + System.currentTimeMillis());
|
||||||
user2 = createUser("user2" + System.currentTimeMillis());
|
user2 = createUser("user2" + System.currentTimeMillis());
|
||||||
// We just need to clean the on-premise-users,
|
// We just need to clean the on-premise-users,
|
||||||
@@ -1153,6 +1156,96 @@ public class NodeApiTest extends AbstractBaseApiTest
|
|||||||
put("nodes", user1, fId, toJsonAsStringNonNull(fUpdate), null, 400);
|
put("nodes", user1, fId, toJsonAsStringNonNull(fUpdate), null, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests update file content
|
||||||
|
* <p>PUT:</p>
|
||||||
|
* {@literal <host>:<port>/alfresco/api/-default-/public/alfresco/versions/1/nodes/<nodeId>/content}
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testUpdateFileWithBinaryUpload() throws Exception
|
||||||
|
{
|
||||||
|
AuthenticationUtil.setFullyAuthenticatedUser(user1);
|
||||||
|
|
||||||
|
NodeRef myFilesNodeRef = repositoryHelper.getUserHome(personService.getPerson(user1));
|
||||||
|
|
||||||
|
Folder f1 = new Folder();
|
||||||
|
f1.setName("F1");
|
||||||
|
f1.setNodeType("cm:folder");
|
||||||
|
|
||||||
|
HttpResponse response = post(getChildrenUrl(myFilesNodeRef), user1, toJsonAsStringNonNull(f1), 201);
|
||||||
|
Folder folderResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Folder.class);
|
||||||
|
assertEquals(f1.getName(), folderResp.getName());
|
||||||
|
final String f1_nodeId = folderResp.getId();
|
||||||
|
assertNotNull(f1_nodeId);
|
||||||
|
|
||||||
|
Document doc = new Document();
|
||||||
|
final String docName = "testdoc";
|
||||||
|
doc.setName(docName);
|
||||||
|
doc.setNodeType("cm:content");
|
||||||
|
ContentInfo contentInfo = new ContentInfo();
|
||||||
|
contentInfo.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||||
|
doc.setContent(contentInfo);
|
||||||
|
|
||||||
|
// create an empty file within F1 folder
|
||||||
|
response = post(getChildrenUrl(f1_nodeId), user1, toJsonAsStringNonNull(doc), 201);
|
||||||
|
Document docResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||||
|
assertEquals(docName, docResp.getName());
|
||||||
|
assertNotNull(docResp.getContent());
|
||||||
|
assertEquals(0, docResp.getContent().getSizeInBytes().intValue());
|
||||||
|
assertEquals(MimetypeMap.MIMETYPE_TEXT_PLAIN, docResp.getContent().getMimeType());
|
||||||
|
|
||||||
|
// Update content & Download URL
|
||||||
|
final String url = "nodes/" + docResp.getId() + "/content";
|
||||||
|
|
||||||
|
// Update the empty node's content
|
||||||
|
String content = "The quick brown fox jumps over the lazy dog.";
|
||||||
|
ByteArrayInputStream inputStream = new ByteArrayInputStream(content.getBytes());
|
||||||
|
File file = TempFileProvider.createTempFile(inputStream, getClass().getSimpleName(), ".txt");
|
||||||
|
BinaryPayload payload = new BinaryPayload(file, MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||||
|
|
||||||
|
// Try to update a folder!
|
||||||
|
putBinary("nodes/" + f1_nodeId + "/content", user1, payload, null, null, 400);
|
||||||
|
|
||||||
|
// Try to update a non-existent file
|
||||||
|
putBinary("nodes/" + UUID.randomUUID().toString() + "/content", user1, payload, null, null, 404);
|
||||||
|
|
||||||
|
// Update the empty file
|
||||||
|
response = putBinary(url, user1, payload, null, null, 200);
|
||||||
|
docResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||||
|
assertEquals(docName, docResp.getName());
|
||||||
|
assertNull(docResp.getPath());
|
||||||
|
assertNotNull(docResp.getContent());
|
||||||
|
assertTrue(docResp.getContent().getSizeInBytes().intValue() > 0);
|
||||||
|
assertEquals(MimetypeMap.MIMETYPE_TEXT_PLAIN, docResp.getContent().getMimeType());
|
||||||
|
|
||||||
|
// Download the file
|
||||||
|
response = getSingle(url, user1, null, 200);
|
||||||
|
assertEquals(content, response.getResponse());
|
||||||
|
|
||||||
|
// Update the node's content again. Also, change the mimeType and make the response to return path!
|
||||||
|
file = getResourceFile("quick.pdf");
|
||||||
|
payload = new BinaryPayload(file, MimetypeMap.MIMETYPE_PDF);
|
||||||
|
|
||||||
|
response = putBinary(url + "?select=path", user1, payload, null, null, 200);
|
||||||
|
docResp = jacksonUtil.parseEntry(response.getJsonResponse(), Document.class);
|
||||||
|
assertEquals(docName, docResp.getName());
|
||||||
|
assertNotNull(docResp.getContent());
|
||||||
|
assertTrue(docResp.getContent().getSizeInBytes().intValue() > 0);
|
||||||
|
assertEquals(MimetypeMap.MIMETYPE_PDF, docResp.getContent().getMimeType());
|
||||||
|
PathInfo pathInfo = docResp.getPath();
|
||||||
|
assertNotNull(pathInfo);
|
||||||
|
assertTrue(pathInfo.getIsComplete());
|
||||||
|
List<ElementInfo> pathElements = pathInfo.getElements();
|
||||||
|
assertNotNull(pathElements);
|
||||||
|
assertTrue(pathElements.size() > 0);
|
||||||
|
// check the last element is F1
|
||||||
|
assertEquals(f1.getName(), pathElements.get(pathElements.size() - 1).getName());
|
||||||
|
|
||||||
|
// Download the file
|
||||||
|
response = getSingle(url, user1, null, 200);
|
||||||
|
assertNotNull(content, response.getResponse());
|
||||||
|
}
|
||||||
|
|
||||||
// TODO add test to create multiple folders & empty files (within same parent folder)
|
// TODO add test to create multiple folders & empty files (within same parent folder)
|
||||||
|
|
||||||
// TODO add test for file/folder links - creating, getting, listing, deleting
|
// TODO add test for file/folder links - creating, getting, listing, deleting
|
||||||
|
@@ -8,6 +8,7 @@ import org.apache.commons.httpclient.methods.DeleteMethod;
|
|||||||
import org.apache.commons.httpclient.methods.GetMethod;
|
import org.apache.commons.httpclient.methods.GetMethod;
|
||||||
import org.apache.commons.httpclient.methods.PostMethod;
|
import org.apache.commons.httpclient.methods.PostMethod;
|
||||||
import org.apache.commons.httpclient.methods.PutMethod;
|
import org.apache.commons.httpclient.methods.PutMethod;
|
||||||
|
import org.apache.commons.httpclient.methods.RequestEntity;
|
||||||
import org.apache.commons.httpclient.methods.StringRequestEntity;
|
import org.apache.commons.httpclient.methods.StringRequestEntity;
|
||||||
import org.json.simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
import org.json.simple.parser.JSONParser;
|
import org.json.simple.parser.JSONParser;
|
||||||
@@ -56,16 +57,21 @@ public class HttpResponse
|
|||||||
{
|
{
|
||||||
requestType = "GET";
|
requestType = "GET";
|
||||||
}
|
}
|
||||||
else if(method instanceof PutMethod)
|
else if (method instanceof PutMethod)
|
||||||
{
|
{
|
||||||
requestType = "PUT";
|
requestType = "PUT";
|
||||||
StringRequestEntity requestEntity = (StringRequestEntity)((PutMethod)method).getRequestEntity();
|
RequestEntity requestEntity = ((PutMethod) method).getRequestEntity();
|
||||||
if(requestEntity != null)
|
if (requestEntity instanceof StringRequestEntity)
|
||||||
{
|
{
|
||||||
requestBody = requestEntity.getContent();
|
StringRequestEntity stringRequestEntity = (StringRequestEntity) requestEntity;
|
||||||
}
|
requestBody = stringRequestEntity.getContent();
|
||||||
}
|
}
|
||||||
else if(method instanceof PostMethod)
|
else if (requestEntity != null)
|
||||||
|
{
|
||||||
|
requestBody = requestEntity.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(method instanceof PostMethod)
|
||||||
{
|
{
|
||||||
requestType = "POST";
|
requestType = "POST";
|
||||||
StringRequestEntity requestEntity = (StringRequestEntity)((PostMethod)method).getRequestEntity();
|
StringRequestEntity requestEntity = (StringRequestEntity)((PostMethod)method).getRequestEntity();
|
||||||
|
@@ -14,6 +14,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
|
|
||||||
import org.alfresco.cmis.client.impl.AlfrescoObjectFactoryImpl;
|
import org.alfresco.cmis.client.impl.AlfrescoObjectFactoryImpl;
|
||||||
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
|
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
|
||||||
|
import org.alfresco.rest.api.tests.client.PublicApiHttpClient.BinaryPayload;
|
||||||
import org.alfresco.rest.api.tests.client.data.Activities;
|
import org.alfresco.rest.api.tests.client.data.Activities;
|
||||||
import org.alfresco.rest.api.tests.client.data.Activity;
|
import org.alfresco.rest.api.tests.client.data.Activity;
|
||||||
import org.alfresco.rest.api.tests.client.data.CMISNode;
|
import org.alfresco.rest.api.tests.client.data.CMISNode;
|
||||||
@@ -523,7 +524,18 @@ public class PublicApiClient
|
|||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HttpResponse putBinary(String scope, int version, String entityCollectionName, Object entityId, String relationCollectionName,
|
||||||
|
Object relationshipEntityId, BinaryPayload payload, Map<String, String> params) throws IOException
|
||||||
|
{
|
||||||
|
HttpResponse response = client.putBinary(getRequestContext(), scope, version, entityCollectionName, entityId, relationCollectionName, relationshipEntityId,
|
||||||
|
payload, params);
|
||||||
|
|
||||||
|
logger.debug(response.toString());
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
public HttpResponse delete(String scope, String entityCollectionName, Object entityId, String relationCollectionName, Object relationshipEntityId) throws IOException
|
public HttpResponse delete(String scope, String entityCollectionName, Object entityId, String relationCollectionName, Object relationshipEntityId) throws IOException
|
||||||
{
|
{
|
||||||
HttpResponse response = client.delete(getRequestContext(), scope, entityCollectionName, entityId, relationCollectionName, relationshipEntityId);
|
HttpResponse response = client.delete(getRequestContext(), scope, entityCollectionName, entityId, relationCollectionName, relationshipEntityId);
|
||||||
|
@@ -19,7 +19,12 @@
|
|||||||
|
|
||||||
package org.alfresco.rest.api.tests.client;
|
package org.alfresco.rest.api.tests.client;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
@@ -48,6 +53,7 @@ import org.apache.commons.httpclient.methods.HeadMethod;
|
|||||||
import org.apache.commons.httpclient.methods.OptionsMethod;
|
import org.apache.commons.httpclient.methods.OptionsMethod;
|
||||||
import org.apache.commons.httpclient.methods.PostMethod;
|
import org.apache.commons.httpclient.methods.PostMethod;
|
||||||
import org.apache.commons.httpclient.methods.PutMethod;
|
import org.apache.commons.httpclient.methods.PutMethod;
|
||||||
|
import org.apache.commons.httpclient.methods.RequestEntity;
|
||||||
import org.apache.commons.httpclient.methods.StringRequestEntity;
|
import org.apache.commons.httpclient.methods.StringRequestEntity;
|
||||||
import org.apache.commons.httpclient.methods.TraceMethod;
|
import org.apache.commons.httpclient.methods.TraceMethod;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
@@ -563,6 +569,23 @@ public class PublicApiHttpClient
|
|||||||
return submitRequest(req, rq);
|
return submitRequest(req, rq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HttpResponse putBinary(final RequestContext rq, final String scope, final int version, final String entityCollectionName,
|
||||||
|
final Object entityId, final String relationCollectionName, final Object relationshipEntityId, final BinaryPayload payload,
|
||||||
|
final Map<String, String> params) throws IOException
|
||||||
|
{
|
||||||
|
RestApiEndpoint endpoint = new RestApiEndpoint(rq.getNetworkId(), scope, version, entityCollectionName, entityId, relationCollectionName,
|
||||||
|
relationshipEntityId, params);
|
||||||
|
String url = endpoint.getUrl();
|
||||||
|
|
||||||
|
PutMethod req = new PutMethod(url);
|
||||||
|
if (payload != null)
|
||||||
|
{
|
||||||
|
BinaryRequestEntity requestEntity = new BinaryRequestEntity(payload.getFile(), payload.getMimeType(), payload.getCharset());
|
||||||
|
req.setRequestEntity(requestEntity);
|
||||||
|
}
|
||||||
|
return submitRequest(req, rq);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encapsulates information relating to a rest api end point, generating and
|
* Encapsulates information relating to a rest api end point, generating and
|
||||||
* encoding urls based on the rest api implementation class.
|
* encoding urls based on the rest api implementation class.
|
||||||
@@ -817,4 +840,100 @@ public class PublicApiHttpClient
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jamal Kaabi-Mofrad
|
||||||
|
*/
|
||||||
|
public static class BinaryRequestEntity implements RequestEntity
|
||||||
|
{
|
||||||
|
private final File file;
|
||||||
|
private final String mimeType;
|
||||||
|
private final String charset;
|
||||||
|
|
||||||
|
public BinaryRequestEntity(File file, String mimeType, String charset)
|
||||||
|
{
|
||||||
|
this.file = file;
|
||||||
|
this.mimeType = (mimeType == null) ? "application/octet-stream" : mimeType;
|
||||||
|
this.charset = (charset == null) ? "UTF-8" : charset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRepeatable()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeRequest(OutputStream out) throws IOException
|
||||||
|
{
|
||||||
|
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
byte[] buffer = new byte[8190];
|
||||||
|
while ((len = inputStream.read(buffer)) != -1)
|
||||||
|
{
|
||||||
|
out.write(buffer, 0, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
inputStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getContentLength()
|
||||||
|
{
|
||||||
|
return file.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getContentType()
|
||||||
|
{
|
||||||
|
return mimeType + "; " + charset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jamal Kaabi-Mofrad
|
||||||
|
*/
|
||||||
|
public static class BinaryPayload
|
||||||
|
{
|
||||||
|
private File file;
|
||||||
|
private String mimeType;
|
||||||
|
private String charset;
|
||||||
|
|
||||||
|
public BinaryPayload(File file, String mimeType, String charset)
|
||||||
|
{
|
||||||
|
this.file = file;
|
||||||
|
this.mimeType = mimeType;
|
||||||
|
this.charset = charset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BinaryPayload(File file, String mimeType)
|
||||||
|
{
|
||||||
|
this(file, mimeType, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BinaryPayload(File file)
|
||||||
|
{
|
||||||
|
this(file, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getFile()
|
||||||
|
{
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMimeType()
|
||||||
|
{
|
||||||
|
return mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCharset()
|
||||||
|
{
|
||||||
|
return charset;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,16 +15,16 @@ import org.alfresco.rest.framework.resource.parameters.Parameters;
|
|||||||
import org.alfresco.util.TempFileProvider;
|
import org.alfresco.util.TempFileProvider;
|
||||||
|
|
||||||
@EntityResource(name="flock",title="A resource used for testing binary properties")
|
@EntityResource(name="flock",title="A resource used for testing binary properties")
|
||||||
public class FlockEntityResource implements BinaryResourceAction.Read, BinaryResourceAction.Delete, BinaryResourceAction.Update
|
public class FlockEntityResource implements BinaryResourceAction.Read, BinaryResourceAction.Delete, BinaryResourceAction.Update<Flock>
|
||||||
{
|
{
|
||||||
|
|
||||||
//versions/1/flock/xyz/photo PUT
|
//versions/1/flock/xyz/photo PUT
|
||||||
@Override
|
@Override
|
||||||
@WebApiDescription(title = "Updates a photo")
|
@WebApiDescription(title = "Updates a photo")
|
||||||
@BinaryProperties("photo")
|
@BinaryProperties("photo")
|
||||||
public void updateProperty(String entityId, BasicContentInfo contentInfo, InputStream stream, Parameters params)
|
public Flock updateProperty(String entityId, BasicContentInfo contentInfo, InputStream stream, Parameters params)
|
||||||
{
|
{
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//versions/1/flock/xyz/photo DELETE
|
//versions/1/flock/xyz/photo DELETE
|
||||||
|
@@ -12,15 +12,15 @@ import org.alfresco.rest.framework.resource.content.BinaryResource;
|
|||||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||||
|
|
||||||
@EntityResource(name="flocket",title="A resource used for testing binary properties with lost of properties")
|
@EntityResource(name="flocket",title="A resource used for testing binary properties with lost of properties")
|
||||||
public class FlocketEntityResource implements BinaryResourceAction.Read, BinaryResourceAction.Delete, BinaryResourceAction.Update
|
public class FlocketEntityResource implements BinaryResourceAction.Read, BinaryResourceAction.Delete, BinaryResourceAction.Update<Flocket>
|
||||||
{
|
{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@WebApiDescription(title = "Updates a flocket")
|
@WebApiDescription(title = "Updates a flocket")
|
||||||
@BinaryProperties({"photo","album"})
|
@BinaryProperties({"photo","album"})
|
||||||
public void updateProperty(String entityId, BasicContentInfo contentInfo, InputStream stream, Parameters params)
|
public Flocket updateProperty(String entityId, BasicContentInfo contentInfo, InputStream stream, Parameters params)
|
||||||
{
|
{
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Reference in New Issue
Block a user