Skip to content
Snippets Groups Projects
Commit fa44838d authored by srosse's avatar srosse
Browse files

OMA-14: improve ForumWebService with rename of attachments

parent 0d13418a
No related branches found
No related tags found
No related merge requests found
...@@ -533,6 +533,26 @@ public class VFSManager extends BasicManager { ...@@ -533,6 +533,26 @@ public class VFSManager extends BasicManager {
return successful; return successful;
} }
/**
*
* @param container
* @param filename
* @return
*/
public static String rename(VFSContainer container, String filename) {
String newName = filename;
VFSItem newFile = container.resolve(newName);
for(int count=0; newFile != null && count < 999 ; ) {
count++;
newName = appendNumberAtTheEndOfFilename(filename, count);
newFile = container.resolve(newName);
}
if(newFile == null) {
return newName;
}
return null;
}
/** /**
* Check if the file exist or not * Check if the file exist or not
* @param item * @param item
......
...@@ -25,6 +25,7 @@ import static org.olat.restapi.security.RestSecurityHelper.getIdentity; ...@@ -25,6 +25,7 @@ import static org.olat.restapi.security.RestSecurityHelper.getIdentity;
import static org.olat.restapi.security.RestSecurityHelper.isAdmin; import static org.olat.restapi.security.RestSecurityHelper.isAdmin;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -52,6 +53,7 @@ import javax.ws.rs.core.Response.Status; ...@@ -52,6 +53,7 @@ import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.StreamingOutput; import javax.ws.rs.core.StreamingOutput;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.apache.commons.io.IOUtils;
import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurity;
import org.olat.basesecurity.BaseSecurityManager; import org.olat.basesecurity.BaseSecurityManager;
import org.olat.core.id.Identity; import org.olat.core.id.Identity;
...@@ -63,6 +65,7 @@ import org.olat.core.util.vfs.LocalFileImpl; ...@@ -63,6 +65,7 @@ import org.olat.core.util.vfs.LocalFileImpl;
import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSContainer;
import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSItem;
import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSLeaf;
import org.olat.core.util.vfs.VFSManager;
import org.olat.core.util.vfs.restapi.SystemItemFilter; import org.olat.core.util.vfs.restapi.SystemItemFilter;
import org.olat.core.util.vfs.restapi.VFSStreamingOutput; import org.olat.core.util.vfs.restapi.VFSStreamingOutput;
import org.olat.modules.fo.Forum; import org.olat.modules.fo.Forum;
...@@ -464,16 +467,23 @@ public class ForumWebService { ...@@ -464,16 +467,23 @@ public class ForumWebService {
VFSLeaf attachment = null; VFSLeaf attachment = null;
if(item == null) { if(item == null) {
attachment = container.createChildLeaf(filename); attachment = container.createChildLeaf(filename);
} else if (item instanceof VFSLeaf) {
attachment = (VFSLeaf)item;
} else { } else {
return Response.serverError().status(Status.CONFLICT).build(); filename = VFSManager.rename(container, filename);
if(filename == null) {
return Response.serverError().status(Status.NOT_ACCEPTABLE).build();
}
attachment = container.createChildLeaf(filename);
} }
OutputStream out = attachment.getOutputStream(false); OutputStream out = attachment.getOutputStream(false);
FileUtils.copy(file, out); try {
FileUtils.closeSafely(out); IOUtils.copy(file, out);
FileUtils.closeSafely(file); } catch (IOException e) {
return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
} finally {
FileUtils.closeSafely(out);
FileUtils.closeSafely(file);
}
return Response.ok().build(); return Response.ok().build();
} }
......
...@@ -26,9 +26,12 @@ import static org.junit.Assert.assertFalse; ...@@ -26,9 +26,12 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List; import java.util.List;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
...@@ -36,7 +39,12 @@ import javax.ws.rs.core.UriBuilder; ...@@ -36,7 +39,12 @@ import javax.ws.rs.core.UriBuilder;
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpClient;
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.PutMethod; import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference; import org.codehaus.jackson.type.TypeReference;
import org.junit.Before; import org.junit.Before;
...@@ -48,6 +56,7 @@ import org.olat.modules.fo.ForumManager; ...@@ -48,6 +56,7 @@ import org.olat.modules.fo.ForumManager;
import org.olat.modules.fo.Message; import org.olat.modules.fo.Message;
import org.olat.modules.fo.restapi.MessageVO; import org.olat.modules.fo.restapi.MessageVO;
import org.olat.modules.fo.restapi.MessageVOes; import org.olat.modules.fo.restapi.MessageVOes;
import org.olat.restapi.support.vo.FileVO;
import org.olat.test.JunitTestHelper; import org.olat.test.JunitTestHelper;
import org.olat.test.OlatJerseyTestCase; import org.olat.test.OlatJerseyTestCase;
...@@ -220,6 +229,113 @@ public class ForumTest extends OlatJerseyTestCase { ...@@ -220,6 +229,113 @@ public class ForumTest extends OlatJerseyTestCase {
assertTrue(saved); assertTrue(saved);
} }
@Test
public void testGetAttachment() throws IOException, URISyntaxException {
HttpClient c = loginWithCookie("administrator", "olat");
URI uri = getForumUriBuilder().path("posts").path(m1.getKey().toString()).path("attachments").build();
GetMethod method = createGet(uri, MediaType.APPLICATION_JSON, true);
int code = c.executeMethod(method);
assertEquals(200, code);
InputStream body = method.getResponseBodyAsStream();
List<FileVO> files = parseFileArray(body);
assertNotNull(files);
}
@Test
public void testUploadAttachment() throws IOException, URISyntaxException {
HttpClient c = loginWithCookie(id1.getName(), "A6B7C8");
URI uri = getForumUriBuilder().path("posts").path(m1.getKey().toString())
.queryParam("authorKey", id1.getKey())
.queryParam("title", "New message with attachment ")
.queryParam("body", "A very interesting response in Thread-1 with an attachment").build();
PutMethod method = createPut(uri, MediaType.APPLICATION_JSON, true);
int code = c.executeMethod(method);
assertEquals(200, code);
InputStream body = method.getResponseBodyAsStream();
MessageVO message = parse(body, MessageVO.class);
assertNotNull(message);
//attachment
URL portraitUrl = RepositoryEntriesTest.class.getResource("portrait.jpg");
assertNotNull(portraitUrl);
File portrait = new File(portraitUrl.toURI());
//upload portrait
URI attachUri = getForumUriBuilder().path("posts").path(m1.getKey().toString()).path("attachments").build();
PostMethod attachMethod = createPost(attachUri, MediaType.APPLICATION_JSON, true);
attachMethod.addRequestHeader("Content-Type", MediaType.MULTIPART_FORM_DATA);
Part[] parts = {
new FilePart("file", portrait),
new StringPart("filename","portrait.jpg")
};
attachMethod.setRequestEntity(new MultipartRequestEntity(parts, attachMethod.getParams()));
int attachCode = c.executeMethod(attachMethod);
assertEquals(200, attachCode);
attachMethod.releaseConnection();
}
@Test
public void testUploadAttachmentAndRename() throws IOException, URISyntaxException {
HttpClient c = loginWithCookie(id1.getName(), "A6B7C8");
URI uri = getForumUriBuilder().path("posts").path(m1.getKey().toString())
.queryParam("authorKey", id1.getKey())
.queryParam("title", "New message with attachment ")
.queryParam("body", "A very interesting response in Thread-1 with an attachment").build();
PutMethod method = createPut(uri, MediaType.APPLICATION_JSON, true);
int code = c.executeMethod(method);
assertEquals(200, code);
InputStream body = method.getResponseBodyAsStream();
MessageVO message = parse(body, MessageVO.class);
assertNotNull(message);
//attachment
URL portraitUrl = RepositoryEntriesTest.class.getResource("portrait.jpg");
assertNotNull(portraitUrl);
File portrait = new File(portraitUrl.toURI());
//upload portrait
URI attachUri = getForumUriBuilder().path("posts").path(m1.getKey().toString()).path("attachments").build();
PostMethod attachMethod = createPost(attachUri, MediaType.APPLICATION_JSON, true);
attachMethod.addRequestHeader("Content-Type", MediaType.MULTIPART_FORM_DATA);
Part[] parts = {
new FilePart("file", portrait),
new StringPart("filename","portrait.jpg")
};
attachMethod.setRequestEntity(new MultipartRequestEntity(parts, attachMethod.getParams()));
int attachCode = c.executeMethod(attachMethod);
assertEquals(200, attachCode);
attachMethod.releaseConnection();
//upload portrait a second time
URI attach2Uri = getForumUriBuilder().path("posts").path(m1.getKey().toString()).path("attachments").build();
PostMethod attach2Method = createPost(attach2Uri, MediaType.APPLICATION_JSON, true);
attach2Method.addRequestHeader("Content-Type", MediaType.MULTIPART_FORM_DATA);
Part[] parts2 = {
new FilePart("file", portrait),
new StringPart("filename","portrait.jpg")
};
attach2Method.setRequestEntity(new MultipartRequestEntity(parts2, attach2Method.getParams()));
int attach2Code = c.executeMethod(attach2Method);
assertEquals(200, attach2Code);
attach2Method.releaseConnection();
// load the attachments
URI loadUri = getForumUriBuilder().path("posts").path(m1.getKey().toString()).path("attachments").build();
GetMethod loadMethod = createGet(loadUri, MediaType.APPLICATION_JSON, true);
int loadCode = c.executeMethod(loadMethod);
assertEquals(200, loadCode);
InputStream loadBody = loadMethod.getResponseBodyAsStream();
List<FileVO> files = parseFileArray(loadBody);
assertNotNull(files);
assertEquals(2, files.size());
loadMethod.releaseConnection();
}
private UriBuilder getForumUriBuilder() { private UriBuilder getForumUriBuilder() {
return UriBuilder.fromUri(getContextURI()).path("repo").path("forums").path(forum.getKey().toString()); return UriBuilder.fromUri(getContextURI()).path("repo").path("forums").path(forum.getKey().toString());
} }
......
...@@ -55,6 +55,7 @@ import org.olat.restapi.security.RestApiLoginFilter; ...@@ -55,6 +55,7 @@ import org.olat.restapi.security.RestApiLoginFilter;
import org.olat.restapi.security.RestSecurityHelper; import org.olat.restapi.security.RestSecurityHelper;
import org.olat.restapi.support.OlatRestApplication; import org.olat.restapi.support.OlatRestApplication;
import org.olat.restapi.support.vo.ErrorVO; import org.olat.restapi.support.vo.ErrorVO;
import org.olat.restapi.support.vo.FileVO;
import org.olat.restapi.support.vo.LinkVO; import org.olat.restapi.support.vo.LinkVO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -381,4 +382,14 @@ public abstract class OlatJerseyTestCase extends OlatTestCase { ...@@ -381,4 +382,14 @@ public abstract class OlatJerseyTestCase extends OlatTestCase {
return null; return null;
} }
} }
protected List<FileVO> parseFileArray(InputStream body) {
try {
ObjectMapper mapper = new ObjectMapper(jsonFactory);
return mapper.readValue(body, new TypeReference<List<FileVO>>(){/* */});
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment