mirror of
https://github.com/sismics/docs.git
synced 2024-12-22 19:33:47 +01:00
Closes #14: Soft delete on DocumentTag + audit log ordering
This commit is contained in:
parent
86cae53789
commit
08e4f6ddae
@ -55,31 +55,50 @@ public class TagDao {
|
||||
/**
|
||||
* Update tags on a document.
|
||||
*
|
||||
* @param documentId
|
||||
* @param tagIdSet
|
||||
* @param documentId Document ID
|
||||
* @param tagIdSet Set of tag ID
|
||||
*/
|
||||
public void updateTagList(String documentId, Set<String> tagIdSet) {
|
||||
// Delete old tag links
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
Query q = em.createQuery("delete DocumentTag dt where dt.documentId = :documentId");
|
||||
q.setParameter("documentId", documentId);
|
||||
q.executeUpdate();
|
||||
|
||||
// Create new tag links
|
||||
for (String tagId : tagIdSet) {
|
||||
DocumentTag documentTag = new DocumentTag();
|
||||
documentTag.setId(UUID.randomUUID().toString());
|
||||
documentTag.setDocumentId(documentId);
|
||||
documentTag.setTagId(tagId);
|
||||
em.persist(documentTag);
|
||||
// Get current tag links
|
||||
Query q = em.createQuery("select dt from DocumentTag dt where dt.documentId = :documentId and dt.deleteDate is null");
|
||||
q.setParameter("documentId", documentId);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<DocumentTag> documentTagList = q.getResultList();
|
||||
|
||||
// Deleting tags no longer linked
|
||||
for (DocumentTag documentTag : documentTagList) {
|
||||
if (!tagIdSet.contains(documentTag.getTagId())) {
|
||||
documentTag.setDeleteDate(new Date());
|
||||
}
|
||||
}
|
||||
|
||||
// Adding new tag links
|
||||
for (String tagId : tagIdSet) {
|
||||
boolean found = false;
|
||||
for (DocumentTag documentTag : documentTagList) {
|
||||
if (documentTag.getTagId().equals(tagId)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
DocumentTag documentTag = new DocumentTag();
|
||||
documentTag.setId(UUID.randomUUID().toString());
|
||||
documentTag.setDocumentId(documentId);
|
||||
documentTag.setTagId(tagId);
|
||||
em.persist(documentTag);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns tag list on a document.
|
||||
* @param documentId
|
||||
* @return
|
||||
*
|
||||
* @param documentId Document ID
|
||||
* @return List of tags
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<TagDto> getByDocumentId(String documentId, String userId) {
|
||||
@ -87,7 +106,7 @@ public class TagDao {
|
||||
StringBuilder sb = new StringBuilder("select t.TAG_ID_C, t.TAG_NAME_C, t.TAG_COLOR_C from T_DOCUMENT_TAG dt ");
|
||||
sb.append(" join T_TAG t on t.TAG_ID_C = dt.DOT_IDTAG_C ");
|
||||
sb.append(" where dt.DOT_IDDOCUMENT_C = :documentId and t.TAG_DELETEDATE_D is null ");
|
||||
sb.append(" and t.TAG_IDUSER_C = :userId ");
|
||||
sb.append(" and t.TAG_IDUSER_C = :userId and dt.DOT_DELETEDATE_D is null ");
|
||||
sb.append(" order by t.TAG_NAME_C ");
|
||||
|
||||
// Perform the query
|
||||
@ -111,15 +130,16 @@ public class TagDao {
|
||||
|
||||
/**
|
||||
* Returns stats on tags.
|
||||
* @param documentId
|
||||
* @return
|
||||
*
|
||||
* @param documentId Document ID
|
||||
* @return Stats by tag
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<TagStatDto> getStats(String userId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
StringBuilder sb = new StringBuilder("select t.TAG_ID_C, t.TAG_NAME_C, t.TAG_COLOR_C, count(d.DOC_ID_C) ");
|
||||
sb.append(" from T_TAG t ");
|
||||
sb.append(" left join T_DOCUMENT_TAG dt on t.TAG_ID_C = dt.DOT_IDTAG_C ");
|
||||
sb.append(" left join T_DOCUMENT_TAG dt on t.TAG_ID_C = dt.DOT_IDTAG_C and dt.DOT_DELETEDATE_D is null ");
|
||||
sb.append(" left join T_DOCUMENT d on d.DOC_ID_C = dt.DOT_IDDOCUMENT_C and d.DOC_DELETEDATE_D is null and d.DOC_IDUSER_C = :userId ");
|
||||
sb.append(" where t.TAG_IDUSER_C = :userId and t.TAG_DELETEDATE_D is null ");
|
||||
sb.append(" group by t.TAG_ID_C ");
|
||||
@ -168,6 +188,7 @@ public class TagDao {
|
||||
|
||||
/**
|
||||
* Returns a tag by name.
|
||||
*
|
||||
* @param userId User ID
|
||||
* @param name Name
|
||||
* @return Tag
|
||||
@ -186,6 +207,7 @@ public class TagDao {
|
||||
|
||||
/**
|
||||
* Returns a tag by ID.
|
||||
*
|
||||
* @param userId User ID
|
||||
* @param tagId Tag ID
|
||||
* @return Tag
|
||||
@ -216,8 +238,7 @@ public class TagDao {
|
||||
Tag tagDb = (Tag) q.getSingleResult();
|
||||
|
||||
// Delete the tag
|
||||
Date dateNow = new Date();
|
||||
tagDb.setDeleteDate(dateNow);
|
||||
tagDb.setDeleteDate(new Date());
|
||||
|
||||
// Delete linked data
|
||||
q = em.createQuery("delete DocumentTag dt where dt.tagId = :tagId");
|
||||
|
@ -6,7 +6,9 @@ import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Link between a document and a tag.
|
||||
@ -40,6 +42,12 @@ public class DocumentTag implements Serializable {
|
||||
@Column(name = "DOT_IDTAG_C", length = 36)
|
||||
private String tagId;
|
||||
|
||||
/**
|
||||
* Deletion date.
|
||||
*/
|
||||
@Column(name = "DOT_DELETEDATE_D")
|
||||
private Date deleteDate;
|
||||
|
||||
/**
|
||||
* Getter of id.
|
||||
*
|
||||
@ -94,44 +102,24 @@ public class DocumentTag implements Serializable {
|
||||
this.tagId = tagId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((documentId == null) ? 0 : documentId.hashCode());
|
||||
result = prime * result + ((tagId == null) ? 0 : tagId.hashCode());
|
||||
return result;
|
||||
/**
|
||||
* Getter of deleteDate.
|
||||
*
|
||||
* @return the deleteDate
|
||||
*/
|
||||
public Date getDeleteDate() {
|
||||
return deleteDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
DocumentTag other = (DocumentTag) obj;
|
||||
if (documentId == null) {
|
||||
if (other.documentId != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!documentId.equals(other.documentId)) {
|
||||
return false;
|
||||
}
|
||||
if (tagId == null) {
|
||||
if (other.tagId != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!tagId.equals(other.tagId)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
/**
|
||||
* Setter of deleteDate.
|
||||
*
|
||||
* @param deleteDate deleteDate
|
||||
*/
|
||||
public void setDeleteDate(Date deleteDate) {
|
||||
this.deleteDate = deleteDate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper(this)
|
||||
|
@ -3,4 +3,5 @@ alter table T_AUTHENTICATION_TOKEN add column AUT_IP_C varchar(45);
|
||||
alter table T_AUTHENTICATION_TOKEN add column AUT_UA_C varchar(1000);
|
||||
create cached table T_AUDIT_LOG ( LOG_ID_C varchar(36) not null, LOG_IDENTITY_C varchar(36) not null, LOG_CLASSENTITY_C varchar(50) not null, LOG_TYPE_C varchar(50) not null, LOG_MESSAGE_C varchar(1000), LOG_CREATEDATE_D datetime, primary key (LOG_ID_C) );
|
||||
create index IDX_LOG_COMPOSITE on T_AUDIT_LOG (LOG_IDENTITY_C, LOG_CLASSENTITY_C);
|
||||
alter table T_DOCUMENT_TAG add column DOT_DELETEDATE_D datetime;
|
||||
update T_CONFIG set CFG_VALUE_C='10' where CFG_ID_C='DB_VERSION';
|
@ -47,7 +47,7 @@ public class AuditLogResource extends BaseResource {
|
||||
|
||||
// On a document or a user?
|
||||
PaginatedList<AuditLogDto> paginatedList = PaginatedLists.create(20, 0);
|
||||
SortCriteria sortCriteria = new SortCriteria(1, true);
|
||||
SortCriteria sortCriteria = new SortCriteria(1, false);
|
||||
AuditLogCriteria criteria = new AuditLogCriteria();
|
||||
if (documentId == null) {
|
||||
// Search logs for a user
|
||||
|
@ -75,12 +75,61 @@ public class TestTagResource extends BaseJerseyTest {
|
||||
documentResource = resource().path("/document");
|
||||
documentResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
||||
postParams = new MultivaluedMapImpl();
|
||||
postParams.add("title", "My super document 1");
|
||||
postParams.add("title", "My super document 2");
|
||||
postParams.add("tags", tag4Id);
|
||||
postParams.add("language", "eng");
|
||||
response = documentResource.put(ClientResponse.class, postParams);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
json = response.getEntity(JSONObject.class);
|
||||
String document2Id = json.getString("id");
|
||||
|
||||
// Check tags on a document
|
||||
documentResource = resource().path("/document/" + document2Id);
|
||||
documentResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
||||
response = documentResource.get(ClientResponse.class);
|
||||
json = response.getEntity(JSONObject.class);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
JSONArray tags = json.getJSONArray("tags");
|
||||
Assert.assertEquals(1, tags.length());
|
||||
Assert.assertEquals(tag4Id, tags.getJSONObject(0).getString("id"));
|
||||
|
||||
// Update tags on a document
|
||||
documentResource = resource().path("/document/" + document2Id);
|
||||
documentResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
||||
postParams = new MultivaluedMapImpl();
|
||||
postParams.add("tags", tag3Id);
|
||||
postParams.add("tags", tag4Id);
|
||||
response = documentResource.post(ClientResponse.class, postParams);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
|
||||
// Check tags on a document
|
||||
documentResource = resource().path("/document/" + document2Id);
|
||||
documentResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
||||
response = documentResource.get(ClientResponse.class);
|
||||
json = response.getEntity(JSONObject.class);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
tags = json.getJSONArray("tags");
|
||||
Assert.assertEquals(2, tags.length());
|
||||
Assert.assertEquals(tag3Id, tags.getJSONObject(0).getString("id"));
|
||||
Assert.assertEquals(tag4Id, tags.getJSONObject(1).getString("id"));
|
||||
|
||||
// Update tags on a document
|
||||
documentResource = resource().path("/document/" + document2Id);
|
||||
documentResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
||||
postParams = new MultivaluedMapImpl();
|
||||
postParams.add("tags", tag4Id);
|
||||
response = documentResource.post(ClientResponse.class, postParams);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
|
||||
// Check tags on a document
|
||||
documentResource = resource().path("/document/" + document2Id);
|
||||
documentResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
||||
response = documentResource.get(ClientResponse.class);
|
||||
json = response.getEntity(JSONObject.class);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
tags = json.getJSONArray("tags");
|
||||
Assert.assertEquals(1, tags.length());
|
||||
Assert.assertEquals(tag4Id, tags.getJSONObject(0).getString("id"));
|
||||
|
||||
// Get tag stats
|
||||
tagResource = resource().path("/tag/stats");
|
||||
@ -99,7 +148,7 @@ public class TestTagResource extends BaseJerseyTest {
|
||||
response = tagResource.get(ClientResponse.class);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
json = response.getEntity(JSONObject.class);
|
||||
JSONArray tags = json.getJSONArray("tags");
|
||||
tags = json.getJSONArray("tags");
|
||||
Assert.assertTrue(tags.length() > 0);
|
||||
Assert.assertEquals("Tag4", tags.getJSONObject(1).getString("name"));
|
||||
Assert.assertEquals("#00ff00", tags.getJSONObject(1).getString("color"));
|
||||
|
Loading…
Reference in New Issue
Block a user