diff --git a/config/alfresco/public-rest-context.xml b/config/alfresco/public-rest-context.xml index 1d24675c4a..8f88ff7558 100644 --- a/config/alfresco/public-rest-context.xml +++ b/config/alfresco/public-rest-context.xml @@ -157,8 +157,10 @@ + + diff --git a/source/java/org/alfresco/rest/api/impl/NodesImpl.java b/source/java/org/alfresco/rest/api/impl/NodesImpl.java index 9b25589d90..fd5ebd7c20 100644 --- a/source/java/org/alfresco/rest/api/impl/NodesImpl.java +++ b/source/java/org/alfresco/rest/api/impl/NodesImpl.java @@ -124,6 +124,7 @@ import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.lock.LockService; import org.alfresco.service.cmr.lock.LockStatus; +import org.alfresco.service.cmr.lock.NodeLockedException; import org.alfresco.service.cmr.model.FileExistsException; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileInfo; @@ -131,6 +132,7 @@ import org.alfresco.service.cmr.model.FileNotFoundException; import org.alfresco.service.cmr.repository.AssociationExistsException; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentData; +import org.alfresco.service.cmr.repository.ContentIOException; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException; @@ -2376,45 +2378,61 @@ public class NodesImpl implements Nodes private void writeContent(NodeRef nodeRef, String fileName, InputStream stream, boolean guessEncoding) { - ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true); - - String mimeType = mimetypeService.guessMimetype(fileName); - if ((mimeType != null) && (! mimeType.equals(MimetypeMap.MIMETYPE_BINARY))) + try { - // quick/weak guess based on file extension - writer.setMimetype(mimeType); - } - else - { - // stronger guess based on file stream - writer.guessMimetype(fileName); - } + ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true); - InputStream is = null; - - if (guessEncoding) - { - is = new BufferedInputStream(stream); - is.mark(1024); - writer.setEncoding(guessEncoding(is, mimeType, false)); - try + String mimeType = mimetypeService.guessMimetype(fileName); + if ((mimeType != null) && (!mimeType.equals(MimetypeMap.MIMETYPE_BINARY))) { - is.reset(); + // quick/weak guess based on file extension + writer.setMimetype(mimeType); + } else + { + // stronger guess based on file stream + writer.guessMimetype(fileName); } - catch (IOException ioe) + + InputStream is = null; + + if (guessEncoding) { - if (logger.isWarnEnabled()) + is = new BufferedInputStream(stream); + is.mark(1024); + writer.setEncoding(guessEncoding(is, mimeType, false)); + try { - logger.warn("Failed to reset stream after trying to guess encoding: " + ioe.getMessage()); + is.reset(); + } catch (IOException ioe) + { + if (logger.isWarnEnabled()) + { + logger.warn("Failed to reset stream after trying to guess encoding: " + ioe.getMessage()); + } } + } else + { + is = stream; } - } - else - { - is = stream; - } - writer.putContent(is); + writer.putContent(is); + } + catch (ContentQuotaException cqe) + { + throw new InsufficientStorageException(); + } + catch (ContentLimitViolationException clv) + { + throw new RequestEntityTooLargeException(clv.getMessage()); + } + catch (ContentIOException cioe) + { + if (cioe.getCause() instanceof NodeLockedException) + { + throw (NodeLockedException)cioe.getCause(); + } + throw cioe; + } } private String guessEncoding(InputStream in, String mimeType, boolean close) @@ -2660,14 +2678,6 @@ public class NodesImpl implements Nodes { throw new PermissionDeniedException(ade.getMessage()); } - catch (ContentQuotaException cqe) - { - throw new InsufficientStorageException(); - } - catch (ContentLimitViolationException clv) - { - throw new RequestEntityTooLargeException(clv.getMessage()); - } catch (Exception ex) { /* diff --git a/source/test-java/org/alfresco/rest/api/tests/AbstractBaseApiTest.java b/source/test-java/org/alfresco/rest/api/tests/AbstractBaseApiTest.java index 2a36ef37ab..6668ca99a9 100644 --- a/source/test-java/org/alfresco/rest/api/tests/AbstractBaseApiTest.java +++ b/source/test-java/org/alfresco/rest/api/tests/AbstractBaseApiTest.java @@ -764,16 +764,29 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi // create empty file HttpResponse response = post(getNodeChildrenUrl(parentFolderId), toJsonAsStringNonNull(d1), params, null, "alfresco", expectedStatus); + if (expectedStatus != 201) + { + return null; + } return RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class); } - protected Document updateTextFile(String contentId, String textContent, Map params) throws IOException, Exception + protected Document updateTextFile(String contentId, String textContent, Map params) throws Exception + { + return updateTextFile(contentId, textContent, params, 200); + } + + protected Document updateTextFile(String contentId, String textContent, Map params, int expectedStatus) throws Exception { ByteArrayInputStream inputStream = new ByteArrayInputStream(textContent.getBytes()); File txtFile = TempFileProvider.createTempFile(inputStream, getClass().getSimpleName(), ".txt"); BinaryPayload payload = new BinaryPayload(txtFile); - HttpResponse response = putBinary(getNodeContentUrl(contentId), payload, null, params, 200); + HttpResponse response = putBinary(getNodeContentUrl(contentId), payload, null, params, expectedStatus); + if (expectedStatus != 200) + { + return null; + } return RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class); } diff --git a/source/test-java/org/alfresco/rest/api/tests/NodeApiTest.java b/source/test-java/org/alfresco/rest/api/tests/NodeApiTest.java index 3d2f1dc30f..4788275f4d 100644 --- a/source/test-java/org/alfresco/rest/api/tests/NodeApiTest.java +++ b/source/test-java/org/alfresco/rest/api/tests/NodeApiTest.java @@ -3631,6 +3631,8 @@ public class NodeApiTest extends AbstractSingleNetworkSiteTest // Test delete on a folder which contains a locked node - NodeLockedException deleteNode(folderId, true, HttpStatus.SC_CONFLICT); + updateTextFile(d1Id, "Updated text", null, 409); + // Test lock children // create folder String folderAName = "folder" + RUNID + "_A"; @@ -3683,6 +3685,9 @@ public class NodeApiTest extends AbstractSingleNetworkSiteTest assertNotNull(child.getProperties().get("cm:lockType")); assertNotNull(child.getProperties().get("cm:lockOwner")); assertTrue(child.getIsLocked()); + + // note: these can be updated by the owner since the lock type is "ALLOW_OWNER_CHANGES" + updateTextFile(child.getId(), "Updated text", null, 200); } // Lock body properties - boundary values