mirror of
https://github.com/sismics/docs.git
synced 2024-11-22 14:07:55 +01:00
Add parameter to return the files when searching for a document (#582)
This commit is contained in:
parent
0b7c42e814
commit
64ec0f63ca
@ -8,6 +8,8 @@ import com.sismics.util.context.ThreadLocalContext;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.TypedQuery;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@ -172,22 +174,33 @@ public class FileDao {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get files by document ID or all orphan files of an user.
|
||||
* Get files by document ID or all orphan files of a user.
|
||||
*
|
||||
* @param userId User ID
|
||||
* @param documentId Document ID
|
||||
* @return List of files
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<File> getByDocumentId(String userId, String documentId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
if (documentId == null) {
|
||||
Query q = em.createQuery("select f from File f where f.documentId is null and f.deleteDate is null and f.latestVersion = true and f.userId = :userId order by f.createDate asc");
|
||||
TypedQuery<File> q = em.createQuery("select f from File f where f.documentId is null and f.deleteDate is null and f.latestVersion = true and f.userId = :userId order by f.createDate asc", File.class);
|
||||
q.setParameter("userId", userId);
|
||||
return q.getResultList();
|
||||
} else {
|
||||
return getByDocumentsIds(Collections.singleton(documentId));
|
||||
}
|
||||
Query q = em.createQuery("select f from File f where f.documentId = :documentId and f.latestVersion = true and f.deleteDate is null order by f.order asc");
|
||||
q.setParameter("documentId", documentId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get files by documents IDs.
|
||||
*
|
||||
* @param documentIds Documents IDs
|
||||
* @return List of files
|
||||
*/
|
||||
public List<File> getByDocumentsIds(Iterable<String> documentIds) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
TypedQuery<File> q = em.createQuery("select f from File f where f.documentId in :documentIds and f.latestVersion = true and f.deleteDate is null order by f.order asc", File.class);
|
||||
q.setParameter("documentIds", documentIds);
|
||||
return q.getResultList();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,40 @@
|
||||
package com.sismics.rest.util;
|
||||
|
||||
import com.sismics.docs.core.model.jpa.File;
|
||||
import com.sismics.docs.core.util.DirectoryUtil;
|
||||
import com.sismics.docs.core.util.FileUtil;
|
||||
import com.sismics.rest.exception.ServerException;
|
||||
import com.sismics.util.JsonUtil;
|
||||
|
||||
import javax.json.Json;
|
||||
import javax.json.JsonObjectBuilder;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
||||
/**
|
||||
* Rest utilities.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class RestUtil {
|
||||
/**
|
||||
* Transform a File into its JSON representation
|
||||
* @param fileDb a file
|
||||
* @return the JSON
|
||||
*/
|
||||
public static JsonObjectBuilder fileToJsonObjectBuilder(File fileDb) {
|
||||
try {
|
||||
return Json.createObjectBuilder()
|
||||
.add("id", fileDb.getId())
|
||||
.add("processing", FileUtil.isProcessingFile(fileDb.getId()))
|
||||
.add("name", JsonUtil.nullable(fileDb.getName()))
|
||||
.add("version", fileDb.getVersion())
|
||||
.add("mimetype", fileDb.getMimeType())
|
||||
.add("document_id", JsonUtil.nullable(fileDb.getDocumentId()))
|
||||
.add("create_date", fileDb.getCreateDate().getTime())
|
||||
.add("size", Files.size(DirectoryUtil.getStorageDirectory().resolve(fileDb.getId())));
|
||||
} catch (IOException e) {
|
||||
throw new ServerException("FileError", "Unable to get the size of " + fileDb.getId(), e);
|
||||
}
|
||||
}
|
||||
}
|
@ -27,11 +27,13 @@ import com.sismics.rest.exception.ClientException;
|
||||
import com.sismics.rest.exception.ForbiddenClientException;
|
||||
import com.sismics.rest.exception.ServerException;
|
||||
import com.sismics.rest.util.AclUtil;
|
||||
import com.sismics.rest.util.RestUtil;
|
||||
import com.sismics.rest.util.ValidationUtil;
|
||||
import com.sismics.util.EmailUtil;
|
||||
import com.sismics.util.JsonUtil;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
import com.sismics.util.mime.MimeType;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
|
||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||
@ -73,6 +75,7 @@ public class DocumentResource extends BaseResource {
|
||||
* @apiGroup Document
|
||||
* @apiParam {String} id Document ID
|
||||
* @apiParam {String} share Share ID
|
||||
* @apiParam {Booleans} files If true includes files information
|
||||
* @apiSuccess {String} id ID
|
||||
* @apiSuccess {String} title Title
|
||||
* @apiSuccess {String} description Description
|
||||
@ -119,6 +122,12 @@ public class DocumentResource extends BaseResource {
|
||||
* @apiSuccess {String} route_step.name Route step name
|
||||
* @apiSuccess {String="APPROVE", "VALIDATE"} route_step.type Route step type
|
||||
* @apiSuccess {Boolean} route_step.transitionable True if the route step is actionable by the current user
|
||||
* @apiSuccess {Object[]} files List of files
|
||||
* @apiSuccess {String} files.id ID
|
||||
* @apiSuccess {String} files.name File name
|
||||
* @apiSuccess {String} files.version Zero-based version number
|
||||
* @apiSuccess {String} files.mimetype MIME type
|
||||
* @apiSuccess {String} files.create_date Create date (timestamp)
|
||||
* @apiError (client) NotFound Document not found
|
||||
* @apiPermission none
|
||||
* @apiVersion 1.5.0
|
||||
@ -131,7 +140,8 @@ public class DocumentResource extends BaseResource {
|
||||
@Path("{id: [a-z0-9\\-]+}")
|
||||
public Response get(
|
||||
@PathParam("id") String documentId,
|
||||
@QueryParam("share") String shareId) {
|
||||
@QueryParam("share") String shareId,
|
||||
@QueryParam("files") Boolean files) {
|
||||
authenticate();
|
||||
|
||||
DocumentDao documentDao = new DocumentDao();
|
||||
@ -240,6 +250,19 @@ public class DocumentResource extends BaseResource {
|
||||
// Add custom metadata
|
||||
MetadataUtil.addMetadata(document, documentId);
|
||||
|
||||
// Add files
|
||||
if (Boolean.TRUE == files) {
|
||||
FileDao fileDao = new FileDao();
|
||||
List<File> fileList = fileDao.getByDocumentsIds(Collections.singleton(documentId));
|
||||
|
||||
JsonArrayBuilder filesArrayBuilder = Json.createArrayBuilder();
|
||||
for (File fileDb : fileList) {
|
||||
filesArrayBuilder.add(RestUtil.fileToJsonObjectBuilder(fileDb));
|
||||
}
|
||||
|
||||
document.add("files", filesArrayBuilder);
|
||||
}
|
||||
|
||||
return Response.ok().entity(document.build()).build();
|
||||
}
|
||||
|
||||
@ -327,6 +350,7 @@ public class DocumentResource extends BaseResource {
|
||||
* @apiParam {Number} sort_column Column index to sort on
|
||||
* @apiParam {Boolean} asc If true, sort in ascending order
|
||||
* @apiParam {String} search Search query
|
||||
* @apiParam {Booleans} files If true includes files information
|
||||
* @apiSuccess {Number} total Total number of documents
|
||||
* @apiSuccess {Object[]} documents List of documents
|
||||
* @apiSuccess {String} documents.id ID
|
||||
@ -345,6 +369,12 @@ public class DocumentResource extends BaseResource {
|
||||
* @apiSuccess {String} documents.tags.id ID
|
||||
* @apiSuccess {String} documents.tags.name Name
|
||||
* @apiSuccess {String} documents.tags.color Color
|
||||
* @apiSuccess {Object[]} documents.files List of files
|
||||
* @apiSuccess {String} documents.files.id ID
|
||||
* @apiSuccess {String} documents.files.name File name
|
||||
* @apiSuccess {String} documents.files.version Zero-based version number
|
||||
* @apiSuccess {String} documents.files.mimetype MIME type
|
||||
* @apiSuccess {String} documents.files.create_date Create date (timestamp)
|
||||
* @apiSuccess {String[]} suggestions List of search suggestions
|
||||
* @apiError (client) ForbiddenError Access denied
|
||||
* @apiError (server) SearchError Error searching in documents
|
||||
@ -356,6 +386,7 @@ public class DocumentResource extends BaseResource {
|
||||
* @param sortColumn Sort column
|
||||
* @param asc Sorting
|
||||
* @param search Search query
|
||||
* @param files Files list
|
||||
* @return Response
|
||||
*/
|
||||
@GET
|
||||
@ -365,7 +396,8 @@ public class DocumentResource extends BaseResource {
|
||||
@QueryParam("offset") Integer offset,
|
||||
@QueryParam("sort_column") Integer sortColumn,
|
||||
@QueryParam("asc") Boolean asc,
|
||||
@QueryParam("search") String search) {
|
||||
@QueryParam("search") String search,
|
||||
@QueryParam("files") Boolean files) {
|
||||
if (!authenticate()) {
|
||||
throw new ForbiddenClientException();
|
||||
}
|
||||
@ -385,6 +417,14 @@ public class DocumentResource extends BaseResource {
|
||||
throw new ServerException("SearchError", "Error searching in documents", e);
|
||||
}
|
||||
|
||||
// Find the files of the documents
|
||||
List<File> filesList = null;
|
||||
if (Boolean.TRUE == files) {
|
||||
Iterable<String> documentsIds = CollectionUtils.collect(paginatedList.getResultList(), DocumentDto::getId);
|
||||
FileDao fileDao = new FileDao();
|
||||
filesList = fileDao.getByDocumentsIds(documentsIds);
|
||||
}
|
||||
|
||||
for (DocumentDto documentDto : paginatedList.getResultList()) {
|
||||
// Get tags accessible by the current user on this document
|
||||
List<TagDto> tagDtoList = tagDao.findByCriteria(new TagCriteria()
|
||||
@ -398,7 +438,7 @@ public class DocumentResource extends BaseResource {
|
||||
.add("color", tagDto.getColor()));
|
||||
}
|
||||
|
||||
documents.add(Json.createObjectBuilder()
|
||||
JsonObjectBuilder documentObjectBuilder = Json.createObjectBuilder()
|
||||
.add("id", documentDto.getId())
|
||||
.add("highlight", JsonUtil.nullable(documentDto.getHighlight()))
|
||||
.add("file_id", JsonUtil.nullable(documentDto.getFileId()))
|
||||
@ -411,7 +451,17 @@ public class DocumentResource extends BaseResource {
|
||||
.add("active_route", documentDto.isActiveRoute())
|
||||
.add("current_step_name", JsonUtil.nullable(documentDto.getCurrentStepName()))
|
||||
.add("file_count", documentDto.getFileCount())
|
||||
.add("tags", tags));
|
||||
.add("tags", tags);
|
||||
if (Boolean.TRUE == files) {
|
||||
JsonArrayBuilder filesArrayBuilder = Json.createArrayBuilder();
|
||||
// Find files matching the document
|
||||
Collection<File> filesOfDocument = CollectionUtils.select(filesList, file -> file.getDocumentId().equals(documentDto.getId()));
|
||||
for (File fileDb : filesOfDocument) {
|
||||
filesArrayBuilder.add(RestUtil.fileToJsonObjectBuilder(fileDb));
|
||||
}
|
||||
documentObjectBuilder.add("files", filesArrayBuilder);
|
||||
}
|
||||
documents.add(documentObjectBuilder);
|
||||
}
|
||||
|
||||
JsonArrayBuilder suggestions = Json.createArrayBuilder();
|
||||
|
@ -21,6 +21,7 @@ import com.sismics.docs.core.util.FileUtil;
|
||||
import com.sismics.rest.exception.ClientException;
|
||||
import com.sismics.rest.exception.ForbiddenClientException;
|
||||
import com.sismics.rest.exception.ServerException;
|
||||
import com.sismics.rest.util.RestUtil;
|
||||
import com.sismics.rest.util.ValidationUtil;
|
||||
import com.sismics.util.HttpUtil;
|
||||
import com.sismics.util.JsonUtil;
|
||||
@ -427,27 +428,13 @@ public class FileResource extends BaseResource {
|
||||
}
|
||||
|
||||
FileDao fileDao = new FileDao();
|
||||
List<File> fileList = fileDao.getByDocumentId(principal.getId(), documentId);
|
||||
|
||||
JsonArrayBuilder files = Json.createArrayBuilder();
|
||||
for (File fileDb : fileList) {
|
||||
try {
|
||||
files.add(Json.createObjectBuilder()
|
||||
.add("id", fileDb.getId())
|
||||
.add("processing", FileUtil.isProcessingFile(fileDb.getId()))
|
||||
.add("name", JsonUtil.nullable(fileDb.getName()))
|
||||
.add("version", fileDb.getVersion())
|
||||
.add("mimetype", fileDb.getMimeType())
|
||||
.add("document_id", JsonUtil.nullable(fileDb.getDocumentId()))
|
||||
.add("create_date", fileDb.getCreateDate().getTime())
|
||||
.add("size", Files.size(DirectoryUtil.getStorageDirectory().resolve(fileDb.getId()))));
|
||||
} catch (IOException e) {
|
||||
throw new ServerException("FileError", "Unable to get the size of " + fileDb.getId(), e);
|
||||
}
|
||||
for (File fileDb : fileDao.getByDocumentId(principal.getId(), documentId)) {
|
||||
files.add(RestUtil.fileToJsonObjectBuilder(fileDb));
|
||||
}
|
||||
|
||||
JsonObjectBuilder response = Json.createObjectBuilder()
|
||||
.add("files", files);
|
||||
|
||||
return Response.ok().entity(response.build()).build();
|
||||
}
|
||||
|
||||
|
@ -264,6 +264,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
Assert.assertEquals(document2Id, relations.getJsonObject(0).getString("id"));
|
||||
Assert.assertFalse(relations.getJsonObject(0).getBoolean("source"));
|
||||
Assert.assertEquals("My super title document 2", relations.getJsonObject(0).getString("title"));
|
||||
Assert.assertFalse(json.containsKey("files"));
|
||||
|
||||
// Get document 2
|
||||
json = target().path("/document/" + document2Id).request()
|
||||
@ -275,6 +276,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
Assert.assertEquals(document1Id, relations.getJsonObject(0).getString("id"));
|
||||
Assert.assertTrue(relations.getJsonObject(0).getBoolean("source"));
|
||||
Assert.assertEquals("My super title document 1", relations.getJsonObject(0).getString("title"));
|
||||
Assert.assertFalse(json.containsKey("files"));
|
||||
|
||||
// Create a tag
|
||||
json = target().path("/tag").request()
|
||||
@ -330,6 +332,25 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
.get(JsonObject.class);
|
||||
documents = json.getJsonArray("documents");
|
||||
Assert.assertEquals(1, documents.size());
|
||||
Assert.assertEquals(document1Id, documents.getJsonObject(0).getString("id"));
|
||||
Assert.assertFalse(documents.getJsonObject(0).containsKey("files"));
|
||||
|
||||
// Search documents by query with files
|
||||
json = target().path("/document/list")
|
||||
.queryParam("files", true)
|
||||
.queryParam("search", "new")
|
||||
.request()
|
||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, document1Token)
|
||||
.get(JsonObject.class);
|
||||
documents = json.getJsonArray("documents");
|
||||
Assert.assertEquals(1, documents.size());
|
||||
Assert.assertEquals(1, documents.size());
|
||||
Assert.assertEquals(document1Id, documents.getJsonObject(0).getString("id"));
|
||||
JsonArray files = documents.getJsonObject(0).getJsonArray("files");
|
||||
Assert.assertEquals(1, files.size());
|
||||
Assert.assertEquals(file1Id, files.getJsonObject(0).getString("id"));
|
||||
Assert.assertEquals("Einstein-Roosevelt-letter.png", files.getJsonObject(0).getString("name"));
|
||||
Assert.assertEquals("image/png", files.getJsonObject(0).getString("mimetype"));
|
||||
|
||||
// Get document 1
|
||||
json = target().path("/document/" + document1Id).request()
|
||||
@ -353,6 +374,19 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
Assert.assertEquals("document1", contributors.getJsonObject(0).getString("username"));
|
||||
relations = json.getJsonArray("relations");
|
||||
Assert.assertEquals(0, relations.size());
|
||||
Assert.assertFalse(json.containsKey("files"));
|
||||
|
||||
// Get document 1 with its files
|
||||
json = target().path("/document/" + document1Id)
|
||||
.queryParam("files", true)
|
||||
.request()
|
||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, document1Token)
|
||||
.get(JsonObject.class);
|
||||
files = json.getJsonArray("files");
|
||||
Assert.assertEquals(1, files.size());
|
||||
Assert.assertEquals(file1Id, files.getJsonObject(0).getString("id"));
|
||||
Assert.assertEquals("Einstein-Roosevelt-letter.png", files.getJsonObject(0).getString("name"));
|
||||
Assert.assertEquals("image/png", files.getJsonObject(0).getString("mimetype"));
|
||||
|
||||
// Get document 2
|
||||
json = target().path("/document/" + document1Id).request()
|
||||
|
Loading…
Reference in New Issue
Block a user