diff --git a/src/main/java/org/olat/core/util/vfs/restapi/VFSWebservice.java b/src/main/java/org/olat/core/util/vfs/restapi/VFSWebservice.java index 0bca38ee44d5834fa14f213218772b83d2f0862f..b42a4ef6d455775f5e653aa7e3d300fb768f4abe 100644 --- a/src/main/java/org/olat/core/util/vfs/restapi/VFSWebservice.java +++ b/src/main/java/org/olat/core/util/vfs/restapi/VFSWebservice.java @@ -64,6 +64,7 @@ import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSStatus; import org.olat.restapi.support.MultipartReader; import org.olat.restapi.support.vo.File64VO; +import org.olat.restapi.support.vo.FileMetadataVO; import org.olat.restapi.support.vo.FileVO; public class VFSWebservice { @@ -127,6 +128,23 @@ public class VFSWebservice { return get(path, uriInfo, request); } + /** + * This retrieves some metadata of a specific file in a folder + * The metadata are: filename, size, date of last modification, MIME-type and file href for downloading via REST + * @response.representation.200.doc The metadata of the file + * @response.representation.200.qname {http://www.example.com}fileMetadataVO + * @response.representation.200.example {@link org.olat.restapi.support.vo.Examples#SAMPLE_FILE_METADATA} + * @param path the path to the file + * @param uriInfo The uri infos + * @return + */ + @GET + @Path("metadata/{path:.*}") + @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + public Response getFileMetadata(@PathParam("path") List<PathSegment> path, @Context UriInfo uriInfo) { + return getFMetadata(path, uriInfo); + } + /** * Upload a file to the root folder or create a new folder. One of the two sets * of parameters must be set: foldername to create @@ -439,6 +457,24 @@ public class VFSWebservice { return Response.serverError().status(Status.BAD_REQUEST).build(); } + protected Response getFMetadata(List<PathSegment> path, UriInfo uriInfo) { + VFSItem vItem = resolveFile(path); + if(vItem == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } else if (vItem instanceof VFSContainer) { + return Response.serverError().status(Status.NOT_ACCEPTABLE).build(); + } else if (vItem instanceof VFSLeaf) { + VFSLeaf leaf = (VFSLeaf)vItem; + UriBuilder builder = uriInfo.getAbsolutePathBuilder(); + String uri = builder.build().toString(); + String[] uriArray = uri.split("metadata/"); + uri = uriArray[0] + uriArray[1]; + FileMetadataVO metaVo = new FileMetadataVO(uri, leaf); + return Response.ok(metaVo).build(); + } + return Response.serverError().status(Status.BAD_REQUEST).build(); + } + protected VFSContainer resolveContainer(List<PathSegment> path, boolean create) { VFSContainer directory = container; boolean notFound = false; diff --git a/src/main/java/org/olat/restapi/support/vo/Examples.java b/src/main/java/org/olat/restapi/support/vo/Examples.java index 792bf92f9147dc993fcdfe5285bb5477224f9d04..39971c8286174c13ea6deaeaf91f7b5a2fc9265b 100644 --- a/src/main/java/org/olat/restapi/support/vo/Examples.java +++ b/src/main/java/org/olat/restapi/support/vo/Examples.java @@ -63,6 +63,8 @@ public class Examples { public static final FileVO SAMPLE_FILE = new FileVO(); + public static final FileMetadataVO SAMPLE_FILE_METADATA = new FileMetadataVO(); + public static final FolderVO SAMPLE_FOLDERVO = new FolderVO(); public static final FolderVOes SAMPLE_FOLDERVOes = new FolderVOes(); @@ -156,6 +158,12 @@ public class Examples { SAMPLE_FILE.setRel("rel"); SAMPLE_FILE.setSize(8200l); SAMPLE_FILE.setTitle("portrait.jpg"); + + SAMPLE_FILE_METADATA.setFileName("portrait.jpg"); + SAMPLE_FILE_METADATA.setHref("http://www.openolat.org/"); + SAMPLE_FILE_METADATA.setLastModified(8945783984l); + SAMPLE_FILE_METADATA.setMimeType("image/jpg"); + SAMPLE_FILE_METADATA.setSize(37638l); SAMPLE_FOLDERVO.setCourseKey(375397l); SAMPLE_FOLDERVO.setCourseNodeId("438950850389"); diff --git a/src/main/java/org/olat/restapi/support/vo/FileMetadataVO.java b/src/main/java/org/olat/restapi/support/vo/FileMetadataVO.java new file mode 100644 index 0000000000000000000000000000000000000000..3f84fd7452d0a2c3b5945dfbd3e587696be26b70 --- /dev/null +++ b/src/main/java/org/olat/restapi/support/vo/FileMetadataVO.java @@ -0,0 +1,105 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ + +package org.olat.restapi.support.vo; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; + +import org.olat.core.util.WebappHelper; +import org.olat.core.util.vfs.VFSLeaf; + + +/** + * + * <h3>Description:</h3> + * <p> + * Initial Date: 28.02.2014 <br> + * @author Stephan Clemenz, clemenz@vcrp.de, VCRP + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "fileMetadataVO") +public class FileMetadataVO { + + @XmlAttribute(name="fileName", required=true) + private String fileName; + @XmlAttribute(name="size", required=true) + private Long size; + @XmlAttribute(name="lastModified", required=true) + private Long lastModified; + @XmlAttribute(name="mimeType", required=true) + private String mimeType; + @XmlAttribute(name="href", required=true) + private String href; + + public FileMetadataVO() { + //make JAXB happy + } + + public FileMetadataVO(String href, VFSLeaf leaf) { + this.fileName = leaf.getName(); + this.size = leaf.getSize(); + this.lastModified = leaf.getLastModified(); + this.mimeType = WebappHelper.getMimeType(leaf.getName()); + this.href = href; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public Long getSize() { + return size; + } + + public void setSize(Long size) { + this.size = size; + } + + public Long getLastModified() { + return lastModified; + } + + public void setLastModified(Long lastModified) { + this.lastModified = lastModified; + } + + public String getMimeType() { + return mimeType; + } + + public void setMimeType(String mimeType) { + this.mimeType = mimeType; + } + + public String getHref() { + return href; + } + + public void setHref(String href) { + this.href = href; + } +} diff --git a/src/test/java/org/olat/restapi/GroupFoldersTest.java b/src/test/java/org/olat/restapi/GroupFoldersTest.java index a5c52493018c45fe16c4f9d571917c64c0a7def8..1eea4dad39bae54d5b3c164d2c5a385c8753e99e 100644 --- a/src/test/java/org/olat/restapi/GroupFoldersTest.java +++ b/src/test/java/org/olat/restapi/GroupFoldersTest.java @@ -40,6 +40,7 @@ import java.util.List; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriBuilder; +import org.apache.commons.io.IOUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; @@ -50,6 +51,7 @@ import org.apache.http.util.EntityUtils; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.olat.basesecurity.GroupRoles; @@ -71,6 +73,7 @@ import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryService; import org.olat.resource.OLATResource; import org.olat.resource.OLATResourceManager; +import org.olat.restapi.support.vo.FileMetadataVO; import org.olat.restapi.support.vo.FileVO; import org.olat.test.JunitTestHelper; import org.olat.test.OlatJerseyTestCase; @@ -268,7 +271,7 @@ public class GroupFoldersTest extends OlatJerseyTestCase { file = newFolder1.createChildLeaf("portrait.jpg"); OutputStream out = file.getOutputStream(true); InputStream in = GroupFoldersTest.class.getResourceAsStream("portrait.jpg"); - FileUtils.copy(in, out, file.getSize()); + FileUtils.copy(in, out); FileUtils.closeSafely(in); FileUtils.closeSafely(out); } @@ -280,9 +283,44 @@ public class GroupFoldersTest extends OlatJerseyTestCase { HttpResponse response = conn.execute(method); assertEquals(200, response.getStatusLine().getStatusCode()); InputStream body = response.getEntity().getContent(); - assertNotNull(body); - assertTrue(10 > body.available()); - assertEquals(new Long(file.getSize()), new Long(body.available())); + byte[] byteArr = IOUtils.toByteArray(body); + Assert.assertNotNull(byteArr); + Assert.assertEquals(file.getSize(), byteArr.length); + } + + @Test + public void testGetFileMetadata() throws IOException, URISyntaxException { + //create some sub folders and copy file + CollaborationTools collabTools2 = CollaborationToolsFactory.getInstance().getOrCreateCollaborationTools(g2); + String folderRelPath = collabTools2.getFolderRelPath(); + OlatRootFolderImpl folder = new OlatRootFolderImpl(folderRelPath, null); + VFSContainer newFolder1 = folder.createChildContainer("Metadata folder"); + if(newFolder1 == null) { + newFolder1 = (VFSContainer)folder.resolve("Metadata folder"); + } + VFSLeaf file = (VFSLeaf)newFolder1.resolve("portrait.jpg"); + if(file == null) { + file = newFolder1.createChildLeaf("portrait.jpg"); + OutputStream out = file.getOutputStream(true); + InputStream in = GroupFoldersTest.class.getResourceAsStream("portrait.jpg"); + FileUtils.copy(in, out); + FileUtils.closeSafely(in); + FileUtils.closeSafely(out); + } + + // get the file + assertTrue(conn.login("rest-one", "A6B7C8")); + URI request = UriBuilder.fromUri(getContextURI()).path("/groups/" + g2.getKey() + "/folder/metadata/Metadata_folder/portrait.jpg").build(); + HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true); + HttpResponse response = conn.execute(method); + assertEquals(200, response.getStatusLine().getStatusCode()); + FileMetadataVO fileMetadataVO = conn.parse(response, FileMetadataVO.class); + Assert.assertNotNull(fileMetadataVO); + Assert.assertEquals("portrait.jpg", fileMetadataVO.getFileName()); + Assert.assertNotNull(fileMetadataVO.getSize()); + Assert.assertEquals(file.getSize(), fileMetadataVO.getSize().longValue()); + Assert.assertNotNull(fileMetadataVO.getHref()); + Assert.assertNotNull(fileMetadataVO.getLastModified()); } @Test