mirror of
https://github.com/sismics/docs.git
synced 2024-12-22 19:33:47 +01:00
#67: relations between documents (server-side)
This commit is contained in:
parent
ca8c525de0
commit
0525754337
@ -184,6 +184,11 @@ public class DocumentDao {
|
||||
q.setParameter("dateNow", dateNow);
|
||||
q.executeUpdate();
|
||||
|
||||
q = em.createQuery("update Relation r set r.deleteDate = :dateNow where (r.fromDocumentId = :documentId or r.toDocumentId = :documentId) and r.deleteDate is not null");
|
||||
q.setParameter("documentId", id);
|
||||
q.setParameter("dateNow", dateNow);
|
||||
q.executeUpdate();
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(documentDb, AuditLogType.DELETE, userId);
|
||||
}
|
||||
|
@ -0,0 +1,97 @@
|
||||
package com.sismics.docs.core.dao.jpa;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import com.sismics.docs.core.dao.jpa.dto.RelationDto;
|
||||
import com.sismics.docs.core.model.jpa.Relation;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
/**
|
||||
* Relation DAO.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class RelationDao {
|
||||
/**
|
||||
* Get all relations from/to a document.
|
||||
*
|
||||
* @param documentId Document ID
|
||||
* @return List of relations
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<RelationDto> getByDocumentId(String documentId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
StringBuilder sb = new StringBuilder("select d.DOC_ID_C, d.DOC_TITLE_C ");
|
||||
sb.append(" from T_RELATION r ");
|
||||
sb.append(" join T_DOCUMENT d on d.DOC_ID_C = r.REL_IDDOCFROM_C and r.REL_IDDOCFROM_C != :documentId or d.DOC_ID_C = r.REL_IDDOCTO_C and r.REL_IDDOCTO_C != :documentId ");
|
||||
sb.append(" where (r.REL_IDDOCFROM_C = :documentId or r.REL_IDDOCTO_C = :documentId) ");
|
||||
sb.append(" and r.REL_DELETEDATE_D is null ");
|
||||
sb.append(" order by d.DOC_TITLE_C ");
|
||||
|
||||
// Perform the query
|
||||
Query q = em.createNativeQuery(sb.toString());
|
||||
q.setParameter("documentId", documentId);
|
||||
List<Object[]> l = q.getResultList();
|
||||
|
||||
// Assemble results
|
||||
List<RelationDto> relationDtoList = new ArrayList<RelationDto>();
|
||||
for (Object[] o : l) {
|
||||
int i = 0;
|
||||
RelationDto relationDto = new RelationDto();
|
||||
relationDto.setId((String) o[i++]);
|
||||
relationDto.setTitle((String) o[i++]);
|
||||
relationDtoList.add(relationDto);
|
||||
}
|
||||
return relationDtoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update relations on a document.
|
||||
*
|
||||
* @param documentId Document ID
|
||||
* @param documentIdSet Set of document ID
|
||||
*/
|
||||
public void updateRelationList(String documentId, Set<String> documentIdSet) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Get current relations from this document
|
||||
Query q = em.createQuery("select r from Relation r where r.fromDocumentId = :documentId and r.deleteDate is null");
|
||||
q.setParameter("documentId", documentId);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Relation> relationList = q.getResultList();
|
||||
|
||||
// Deleting relations no longer there
|
||||
for (Relation relation : relationList) {
|
||||
if (!documentIdSet.contains(relation.getToDocumentId())) {
|
||||
relation.setDeleteDate(new Date());
|
||||
}
|
||||
}
|
||||
|
||||
// Adding new relations
|
||||
for (String targetDocId : documentIdSet) {
|
||||
boolean found = false;
|
||||
for (Relation relation : relationList) {
|
||||
if (relation.getToDocumentId().equals(targetDocId)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
Relation relation = new Relation();
|
||||
relation.setId(UUID.randomUUID().toString());
|
||||
relation.setFromDocumentId(documentId);
|
||||
relation.setToDocumentId(targetDocId);
|
||||
em.persist(relation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
package com.sismics.docs.core.dao.jpa.dto;
|
||||
|
||||
/**
|
||||
* Tag DTO.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class RelationDto {
|
||||
/**
|
||||
* Document ID.
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Document title.
|
||||
*/
|
||||
private String title;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
}
|
@ -26,74 +26,34 @@ public class TagDto {
|
||||
*/
|
||||
private String parentId;
|
||||
|
||||
/**
|
||||
* Getter of id.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter of id.
|
||||
*
|
||||
* @param id id
|
||||
*/
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter of name.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter of name.
|
||||
*
|
||||
* @param name name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter of color.
|
||||
*
|
||||
* @return the color
|
||||
*/
|
||||
public String getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter of color.
|
||||
*
|
||||
* @param color color
|
||||
*/
|
||||
public void setColor(String color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter of parentId.
|
||||
*
|
||||
* @return the parentId
|
||||
*/
|
||||
public String getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter of parentId.
|
||||
*
|
||||
* @param color parentId
|
||||
*/
|
||||
public void setParentId(String parentId) {
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
@ -43,12 +43,14 @@ import com.sismics.docs.core.dao.jpa.AclDao;
|
||||
import com.sismics.docs.core.dao.jpa.ContributorDao;
|
||||
import com.sismics.docs.core.dao.jpa.DocumentDao;
|
||||
import com.sismics.docs.core.dao.jpa.FileDao;
|
||||
import com.sismics.docs.core.dao.jpa.RelationDao;
|
||||
import com.sismics.docs.core.dao.jpa.TagDao;
|
||||
import com.sismics.docs.core.dao.jpa.UserDao;
|
||||
import com.sismics.docs.core.dao.jpa.criteria.DocumentCriteria;
|
||||
import com.sismics.docs.core.dao.jpa.dto.AclDto;
|
||||
import com.sismics.docs.core.dao.jpa.dto.ContributorDto;
|
||||
import com.sismics.docs.core.dao.jpa.dto.DocumentDto;
|
||||
import com.sismics.docs.core.dao.jpa.dto.RelationDto;
|
||||
import com.sismics.docs.core.dao.jpa.dto.TagDto;
|
||||
import com.sismics.docs.core.event.DocumentCreatedAsyncEvent;
|
||||
import com.sismics.docs.core.event.DocumentDeletedAsyncEvent;
|
||||
@ -172,6 +174,17 @@ public class DocumentResource extends BaseResource {
|
||||
}
|
||||
document.add("contributors", contributorList);
|
||||
|
||||
// Add relations
|
||||
RelationDao relationDao = new RelationDao();
|
||||
List<RelationDto> relationDtoList = relationDao.getByDocumentId(documentId);
|
||||
JsonArrayBuilder relationList = Json.createArrayBuilder();
|
||||
for (RelationDto relationDto : relationDtoList) {
|
||||
relationList.add(Json.createObjectBuilder()
|
||||
.add("id", relationDto.getId())
|
||||
.add("title", relationDto.getTitle()));
|
||||
}
|
||||
document.add("relations", relationList);
|
||||
|
||||
return Response.ok().entity(document.build()).build();
|
||||
}
|
||||
|
||||
@ -430,6 +443,7 @@ public class DocumentResource extends BaseResource {
|
||||
@FormParam("coverage") String coverage,
|
||||
@FormParam("rights") String rights,
|
||||
@FormParam("tags") List<String> tagList,
|
||||
@FormParam("relations") List<String> relationList,
|
||||
@FormParam("language") String language,
|
||||
@FormParam("create_date") String createDateStr) {
|
||||
if (!authenticate()) {
|
||||
@ -493,6 +507,9 @@ public class DocumentResource extends BaseResource {
|
||||
// Update tags
|
||||
updateTagList(documentId, tagList);
|
||||
|
||||
// Update relations
|
||||
updateRelationList(documentId, relationList);
|
||||
|
||||
// Raise a document created event
|
||||
DocumentCreatedAsyncEvent documentCreatedAsyncEvent = new DocumentCreatedAsyncEvent();
|
||||
documentCreatedAsyncEvent.setUserId(principal.getId());
|
||||
@ -526,6 +543,7 @@ public class DocumentResource extends BaseResource {
|
||||
@FormParam("coverage") String coverage,
|
||||
@FormParam("rights") String rights,
|
||||
@FormParam("tags") List<String> tagList,
|
||||
@FormParam("relations") List<String> relationList,
|
||||
@FormParam("language") String language,
|
||||
@FormParam("create_date") String createDateStr) {
|
||||
if (!authenticate()) {
|
||||
@ -600,6 +618,9 @@ public class DocumentResource extends BaseResource {
|
||||
// Update tags
|
||||
updateTagList(id, tagList);
|
||||
|
||||
// Update relations
|
||||
updateRelationList(id, relationList);
|
||||
|
||||
// Raise a document updated event
|
||||
DocumentUpdatedAsyncEvent documentUpdatedAsyncEvent = new DocumentUpdatedAsyncEvent();
|
||||
documentUpdatedAsyncEvent.setUserId(principal.getId());
|
||||
@ -636,6 +657,27 @@ public class DocumentResource extends BaseResource {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update relations list on a document.
|
||||
*
|
||||
* @param documentId Document ID
|
||||
* @param relationList Relation ID list
|
||||
*/
|
||||
private void updateRelationList(String documentId, List<String> relationList) {
|
||||
if (relationList != null) {
|
||||
DocumentDao documentDao = new DocumentDao();
|
||||
RelationDao relationDao = new RelationDao();
|
||||
Set<String> documentIdSet = new HashSet<>();
|
||||
for (String targetDocId : relationList) {
|
||||
Document document = documentDao.getDocument(targetDocId, PermType.READ, principal.getId());
|
||||
if (document != null && !documentId.equals(targetDocId)) {
|
||||
documentIdSet.add(targetDocId);
|
||||
}
|
||||
}
|
||||
relationDao.updateRelationList(documentId, documentIdSet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a document.
|
||||
*
|
||||
|
@ -76,6 +76,16 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
String document1Id = json.getString("id");
|
||||
Assert.assertNotNull(document1Id);
|
||||
|
||||
// Create a document with document1
|
||||
json = target().path("/document").request()
|
||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, document1Token)
|
||||
.put(Entity.form(new Form()
|
||||
.param("title", "My super title document 2")
|
||||
.param("language", "eng")
|
||||
.param("relations", document1Id)), JsonObject.class);
|
||||
String document2Id = json.getString("id");
|
||||
Assert.assertNotNull(document2Id);
|
||||
|
||||
// Add a file
|
||||
String file1Id = null;
|
||||
try (InputStream is = Resources.getResource("file/Einstein-Roosevelt-letter.png").openStream()) {
|
||||
@ -100,13 +110,13 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
// List all documents
|
||||
json = target().path("/document/list")
|
||||
.queryParam("sort_column", 3)
|
||||
.queryParam("asc", false)
|
||||
.queryParam("asc", true)
|
||||
.request()
|
||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, document1Token)
|
||||
.get(JsonObject.class);
|
||||
JsonArray documents = json.getJsonArray("documents");
|
||||
JsonArray tags = documents.getJsonObject(0).getJsonArray("tags");
|
||||
Assert.assertTrue(documents.size() == 1);
|
||||
Assert.assertTrue(documents.size() == 2);
|
||||
Assert.assertEquals(document1Id, documents.getJsonObject(0).getString("id"));
|
||||
Assert.assertEquals("eng", documents.getJsonObject(0).getString("language"));
|
||||
Assert.assertEquals(1, documents.getJsonObject(0).getInt("file_count"));
|
||||
@ -130,8 +140,8 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
json = target().path("/document").request()
|
||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, document3Token)
|
||||
.put(Entity.form(new Form()
|
||||
.param("title", "My super title document 1")
|
||||
.param("description", "My super description for document 1")
|
||||
.param("title", "My super title document 3")
|
||||
.param("description", "My super description for document 3")
|
||||
.param("language", "eng")
|
||||
.param("create_date", Long.toString(create3Date))), JsonObject.class);
|
||||
String document3Id = json.getString("id");
|
||||
@ -165,8 +175,8 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
|
||||
// Search documents
|
||||
Assert.assertEquals(1, searchDocuments("full:uranium full:einstein", document1Token));
|
||||
Assert.assertEquals(1, searchDocuments("full:title", document1Token));
|
||||
Assert.assertEquals(1, searchDocuments("title", document1Token));
|
||||
Assert.assertEquals(2, searchDocuments("full:title", document1Token));
|
||||
Assert.assertEquals(2, searchDocuments("title", document1Token));
|
||||
Assert.assertEquals(1, searchDocuments("super description", document1Token));
|
||||
Assert.assertEquals(1, searchDocuments("subject", document1Token));
|
||||
Assert.assertEquals(1, searchDocuments("identifier", document1Token));
|
||||
@ -177,15 +187,15 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
Assert.assertEquals(1, searchDocuments("greenland", document1Token));
|
||||
Assert.assertEquals(1, searchDocuments("public domain", document1Token));
|
||||
Assert.assertEquals(0, searchDocuments("by:document3", document1Token));
|
||||
Assert.assertEquals(1, searchDocuments("by:document1", document1Token));
|
||||
Assert.assertEquals(2, searchDocuments("by:document1", document1Token));
|
||||
Assert.assertEquals(0, searchDocuments("by:nobody", document1Token));
|
||||
Assert.assertEquals(1, searchDocuments("at:" + DateTimeFormat.forPattern("yyyy").print(new Date().getTime()), document1Token));
|
||||
Assert.assertEquals(1, searchDocuments("at:" + DateTimeFormat.forPattern("yyyy-MM").print(new Date().getTime()), document1Token));
|
||||
Assert.assertEquals(1, searchDocuments("at:" + DateTimeFormat.forPattern("yyyy-MM-dd").print(new Date().getTime()), document1Token));
|
||||
Assert.assertEquals(1, searchDocuments("after:2010 before:2040-08", document1Token));
|
||||
Assert.assertEquals(2, searchDocuments("at:" + DateTimeFormat.forPattern("yyyy").print(new Date().getTime()), document1Token));
|
||||
Assert.assertEquals(2, searchDocuments("at:" + DateTimeFormat.forPattern("yyyy-MM").print(new Date().getTime()), document1Token));
|
||||
Assert.assertEquals(2, searchDocuments("at:" + DateTimeFormat.forPattern("yyyy-MM-dd").print(new Date().getTime()), document1Token));
|
||||
Assert.assertEquals(2, searchDocuments("after:2010 before:2040-08", document1Token));
|
||||
Assert.assertEquals(1, searchDocuments("tag:super", document1Token));
|
||||
Assert.assertEquals(1, searchDocuments("shared:yes", document1Token));
|
||||
Assert.assertEquals(1, searchDocuments("lang:eng", document1Token));
|
||||
Assert.assertEquals(2, searchDocuments("lang:eng", document1Token));
|
||||
Assert.assertEquals(1, searchDocuments("after:2010 before:2040-08 tag:super shared:yes lang:eng title description full:uranium", document1Token));
|
||||
|
||||
// Search documents (nothing)
|
||||
@ -199,7 +209,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
Assert.assertEquals(0, searchDocuments("tag:Nop", document1Token));
|
||||
Assert.assertEquals(0, searchDocuments("lang:fra", document1Token));
|
||||
|
||||
// Get a document
|
||||
// Get document 1
|
||||
json = target().path("/document/" + document1Id).request()
|
||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, document1Token)
|
||||
.get(JsonObject.class);
|
||||
@ -225,6 +235,20 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
JsonArray contributors = json.getJsonArray("contributors");
|
||||
Assert.assertEquals(1, contributors.size());
|
||||
Assert.assertEquals("document1", contributors.getJsonObject(0).getString("username"));
|
||||
JsonArray relations = json.getJsonArray("relations");
|
||||
Assert.assertEquals(1, relations.size());
|
||||
Assert.assertEquals(document2Id, relations.getJsonObject(0).getString("id"));
|
||||
Assert.assertEquals("My super title document 2", relations.getJsonObject(0).getString("title"));
|
||||
|
||||
// Get document 2
|
||||
json = target().path("/document/" + document2Id).request()
|
||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, document1Token)
|
||||
.get(JsonObject.class);
|
||||
Assert.assertEquals(document2Id, json.getString("id"));
|
||||
relations = json.getJsonArray("relations");
|
||||
Assert.assertEquals(1, relations.size());
|
||||
Assert.assertEquals(document1Id, relations.getJsonObject(0).getString("id"));
|
||||
Assert.assertEquals("My super title document 1", relations.getJsonObject(0).getString("title"));
|
||||
|
||||
// Export a document in PDF format
|
||||
Response response = target().path("/document/" + document1Id).request()
|
||||
@ -241,7 +265,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
String tag2Id = json.getString("id");
|
||||
Assert.assertNotNull(tag1Id);
|
||||
|
||||
// Update a document
|
||||
// Update document 1
|
||||
json = target().path("/document/" + document1Id).request()
|
||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, document1Token)
|
||||
.post(Entity.form(new Form()
|
||||
@ -258,14 +282,24 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
.param("tags", tag2Id)), JsonObject.class);
|
||||
Assert.assertEquals(document1Id, json.getString("id"));
|
||||
|
||||
// Update document 2
|
||||
json = target().path("/document/" + document2Id).request()
|
||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, document1Token)
|
||||
.post(Entity.form(new Form()
|
||||
.param("title", "My super title document 2")
|
||||
.param("lang", "eng")), JsonObject.class);
|
||||
Assert.assertEquals(document2Id, json.getString("id"));
|
||||
|
||||
// Search documents by query
|
||||
json = target().path("/document/list")
|
||||
.queryParam("search", "super")
|
||||
.queryParam("search", "new")
|
||||
.request()
|
||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, document1Token)
|
||||
.get(JsonObject.class);
|
||||
documents = json.getJsonArray("documents");
|
||||
Assert.assertTrue(documents.size() == 1);
|
||||
|
||||
// Get a document
|
||||
// Get document 1
|
||||
json = target().path("/document/" + document1Id).request()
|
||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, document1Token)
|
||||
.get(JsonObject.class);
|
||||
@ -285,6 +319,15 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
contributors = json.getJsonArray("contributors");
|
||||
Assert.assertEquals(1, contributors.size());
|
||||
Assert.assertEquals("document1", contributors.getJsonObject(0).getString("username"));
|
||||
relations = json.getJsonArray("relations");
|
||||
Assert.assertEquals(0, relations.size());
|
||||
|
||||
// Get document 2
|
||||
json = target().path("/document/" + document1Id).request()
|
||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, document1Token)
|
||||
.get(JsonObject.class);
|
||||
relations = json.getJsonArray("relations");
|
||||
Assert.assertEquals(0, relations.size());
|
||||
|
||||
// Deletes a document
|
||||
json = target().path("/document/" + document1Id).request()
|
||||
|
Loading…
Reference in New Issue
Block a user