mirror of
https://github.com/sismics/docs.git
synced 2024-11-25 07:07:57 +01:00
Server side tag system
This commit is contained in:
parent
74132103bb
commit
62b6512996
@ -127,6 +127,8 @@ public class DocumentDao {
|
||||
parameterMap.put("search", "%" + criteria.getSearch() + "%");
|
||||
}
|
||||
|
||||
criteriaList.add("d.DOC_DELETEDATE_D is null");
|
||||
|
||||
if (!criteriaList.isEmpty()) {
|
||||
sb.append(" where ");
|
||||
sb.append(Joiner.on(" and ").join(criteriaList));
|
||||
|
@ -0,0 +1,182 @@
|
||||
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.NoResultException;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import com.sismics.docs.core.dao.jpa.dto.TagDto;
|
||||
import com.sismics.docs.core.model.jpa.DocumentTag;
|
||||
import com.sismics.docs.core.model.jpa.Tag;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
/**
|
||||
* Tag DAO.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class TagDao {
|
||||
/**
|
||||
* Gets a tag by its ID.
|
||||
*
|
||||
* @param id Tag ID
|
||||
* @return Tag
|
||||
*/
|
||||
public Tag getById(String id) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
try {
|
||||
return em.find(Tag.class, id);
|
||||
} catch (NoResultException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all tags.
|
||||
*
|
||||
* @return List of tags
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Tag> getByUserId(String userId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
Query q = em.createQuery("select t from Tag t where t.userId = :userId and t.deleteDate is null order by t.id");
|
||||
q.setParameter("userId", userId);
|
||||
return q.getResultList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update tags on a document.
|
||||
*
|
||||
* @param documentId
|
||||
* @param tagIdSet
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns tag list on a document.
|
||||
* @param documentId
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<TagDto> getByDocumentId(String documentId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
StringBuilder sb = new StringBuilder("select t.TAG_ID_C, t.TAG_NAME_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 ");
|
||||
|
||||
// Perform the query
|
||||
Query q = em.createNativeQuery(sb.toString());
|
||||
q.setParameter("documentId", documentId);
|
||||
List<Object[]> l = q.getResultList();
|
||||
|
||||
// Assemble results
|
||||
List<TagDto> tagDtoList = new ArrayList<TagDto>();
|
||||
for (Object[] o : l) {
|
||||
int i = 0;
|
||||
TagDto tagDto = new TagDto();
|
||||
tagDto.setId((String) o[i++]);
|
||||
tagDto.setName((String) o[i++]);
|
||||
tagDtoList.add(tagDto);
|
||||
}
|
||||
return tagDtoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new tag.
|
||||
*
|
||||
* @param tag Tag
|
||||
* @return New ID
|
||||
* @throws Exception
|
||||
*/
|
||||
public String create(Tag tag) {
|
||||
// Create the UUID
|
||||
tag.setId(UUID.randomUUID().toString());
|
||||
|
||||
// Create the tag
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
tag.setCreateDate(new Date());
|
||||
em.persist(tag);
|
||||
|
||||
return tag.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a tag by user ID and name.
|
||||
* @param userId User ID
|
||||
* @param name Name
|
||||
* @return Tag
|
||||
*/
|
||||
public Tag getByUserIdAndName(String userId, String name) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
Query q = em.createQuery("select t from Tag t where t.name = :name and t.userId = :userId and t.deleteDate is null");
|
||||
q.setParameter("userId", userId);
|
||||
q.setParameter("name", name);
|
||||
try {
|
||||
return (Tag) q.getSingleResult();
|
||||
} catch (NoResultException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a tag by user ID and name.
|
||||
* @param userId User ID
|
||||
* @param tagId Tag ID
|
||||
* @return Tag
|
||||
*/
|
||||
public Tag getByUserIdAndTagId(String userId, String tagId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
Query q = em.createQuery("select t from Tag t where t.id = :tagId and t.userId = :userId and t.deleteDate is null");
|
||||
q.setParameter("userId", userId);
|
||||
q.setParameter("tagId", tagId);
|
||||
try {
|
||||
return (Tag) q.getSingleResult();
|
||||
} catch (NoResultException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a tag.
|
||||
*
|
||||
* @param tagId Tag ID
|
||||
*/
|
||||
public void delete(String tagId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Get the tag
|
||||
Query q = em.createQuery("select t from Tag t where t.id = :id and t.deleteDate is null");
|
||||
q.setParameter("id", tagId);
|
||||
Tag tagDb = (Tag) q.getSingleResult();
|
||||
|
||||
// Delete the tag
|
||||
Date dateNow = new Date();
|
||||
tagDb.setDeleteDate(dateNow);
|
||||
|
||||
// Delete linked data
|
||||
q = em.createQuery("delete DocumentTag dt where dt.tagId = :tagId");
|
||||
q.setParameter("tagId", tagId);
|
||||
q.executeUpdate();
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ import javax.persistence.Id;
|
||||
/**
|
||||
* Document DTO.
|
||||
*
|
||||
* @author jtremeaux
|
||||
* @author bgamard
|
||||
*/
|
||||
public class DocumentDto {
|
||||
/**
|
||||
|
@ -0,0 +1,57 @@
|
||||
package com.sismics.docs.core.dao.jpa.dto;
|
||||
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* Tag DTO.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class TagDto {
|
||||
/**
|
||||
* Tag ID.
|
||||
*/
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Name.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package com.sismics.docs.core.model.jpa;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Link between a document and a tag.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "T_DOCUMENT_TAG")
|
||||
public class DocumentTag implements Serializable {
|
||||
/**
|
||||
* Serial version UID.
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Document tag ID.
|
||||
*/
|
||||
@Id
|
||||
@Column(name = "DOT_ID_C", length = 36)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Document ID.
|
||||
*/
|
||||
@Id
|
||||
@Column(name = "DOT_IDDOCUMENT_C", length = 36)
|
||||
private String documentId;
|
||||
|
||||
/**
|
||||
* Tag ID.
|
||||
*/
|
||||
@Id
|
||||
@Column(name = "DOT_IDTAG_C", length = 36)
|
||||
private String tagId;
|
||||
|
||||
/**
|
||||
* Getter of id.
|
||||
*
|
||||
* @return id
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter of id.
|
||||
*
|
||||
* @param id id
|
||||
*/
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter de documentId.
|
||||
*
|
||||
* @return the documentId
|
||||
*/
|
||||
public String getDocumentId() {
|
||||
return documentId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter de documentId.
|
||||
*
|
||||
* @param documentId documentId
|
||||
*/
|
||||
public void setDocumentId(String documentId) {
|
||||
this.documentId = documentId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter de tagId.
|
||||
*
|
||||
* @return the tagId
|
||||
*/
|
||||
public String getTagId() {
|
||||
return tagId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter de tagId.
|
||||
*
|
||||
* @param tagId tagId
|
||||
*/
|
||||
public void setTagId(String tagId) {
|
||||
this.tagId = tagId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper(this)
|
||||
.add("documentId", documentId)
|
||||
.add("tagId", tagId)
|
||||
.toString();
|
||||
}
|
||||
}
|
148
docs-core/src/main/java/com/sismics/docs/core/model/jpa/Tag.java
Normal file
148
docs-core/src/main/java/com/sismics/docs/core/model/jpa/Tag.java
Normal file
@ -0,0 +1,148 @@
|
||||
package com.sismics.docs.core.model.jpa;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Tag.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "T_TAG")
|
||||
public class Tag {
|
||||
/**
|
||||
* Tag ID.
|
||||
*/
|
||||
@Id
|
||||
@Column(name = "TAG_ID_C", length = 36)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Tag name.
|
||||
*/
|
||||
@Column(name = "TAG_NAME_C", nullable = false, length = 36)
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* User ID.
|
||||
*/
|
||||
@Column(name = "TAG_IDUSER_C", nullable = false, length = 36)
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* Creation date.
|
||||
*/
|
||||
@Column(name = "TAG_CREATEDATE_D", nullable = false)
|
||||
private Date createDate;
|
||||
|
||||
/**
|
||||
* Deletion date.
|
||||
*/
|
||||
@Column(name = "TAG_DELETEDATE_D")
|
||||
private Date deleteDate;
|
||||
|
||||
/**
|
||||
* Getter of id.
|
||||
*
|
||||
* @return id
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter of id.
|
||||
*
|
||||
* @param id id
|
||||
*/
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter of userId.
|
||||
*
|
||||
* @return the userId
|
||||
*/
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter of userId.
|
||||
*
|
||||
* @param userId userId
|
||||
*/
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter of name.
|
||||
*
|
||||
* @return name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter of name.
|
||||
*
|
||||
* @param name name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter of createDate.
|
||||
*
|
||||
* @return createDate
|
||||
*/
|
||||
public Date getCreateDate() {
|
||||
return createDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter of createDate.
|
||||
*
|
||||
* @param createDate createDate
|
||||
*/
|
||||
public void setCreateDate(Date createDate) {
|
||||
this.createDate = createDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter of deleteDate.
|
||||
*
|
||||
* @return deleteDate
|
||||
*/
|
||||
public Date getDeleteDate() {
|
||||
return deleteDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter of deleteDate.
|
||||
*
|
||||
* @param deleteDate deleteDate
|
||||
*/
|
||||
public void setDeleteDate(Date deleteDate) {
|
||||
this.deleteDate = deleteDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper(this)
|
||||
.add("id", id)
|
||||
.add("name", name)
|
||||
.toString();
|
||||
}
|
||||
}
|
@ -13,5 +13,7 @@
|
||||
<class>com.sismics.docs.core.model.jpa.User</class>
|
||||
<class>com.sismics.docs.core.model.jpa.RoleBaseFunction</class>
|
||||
<class>com.sismics.docs.core.model.jpa.Document</class>
|
||||
<class>com.sismics.docs.core.model.jpa.Tag</class>
|
||||
<class>com.sismics.docs.core.model.jpa.DocumentTag</class>
|
||||
</persistence-unit>
|
||||
</persistence>
|
@ -8,11 +8,16 @@ create cached table T_DOCUMENT ( DOC_ID_C varchar(36) not null, DOC_IDUSER_C var
|
||||
create memory table T_USER ( USE_ID_C varchar(36) not null, USE_IDLOCALE_C varchar(10) not null, USE_IDROLE_C varchar(36) not null, USE_USERNAME_C varchar(50) not null, USE_PASSWORD_C varchar(60) not null, USE_EMAIL_C varchar(100) not null, USE_THEME_C varchar(100) not null, USE_FIRSTCONNECTION_B bit not null, USE_CREATEDATE_D datetime not null, USE_DELETEDATE_D datetime, primary key (USE_ID_C) );
|
||||
create memory table T_ROLE ( ROL_ID_C varchar(36) not null, ROL_NAME_C varchar(36) not null, ROL_CREATEDATE_D datetime not null, ROL_DELETEDATE_D datetime, primary key (ROL_ID_C) );
|
||||
create memory table T_ROLE_BASE_FUNCTION ( RBF_ID_C varchar(36) not null, RBF_IDROLE_C varchar(36) not null, RBF_IDBASEFUNCTION_C varchar(20) not null, RBF_CREATEDATE_D datetime not null, RBF_DELETEDATE_D datetime, primary key (RBF_ID_C) );
|
||||
create cached table T_TAG ( TAG_ID_C varchar(36) not null, TAG_IDUSER_C varchar(36) not null, TAG_NAME_C varchar(36) not null, TAG_CREATEDATE_D datetime, TAG_DELETEDATE_D datetime, primary key (TAG_ID_C) );
|
||||
create cached table T_DOCUMENT_TAG ( DOT_ID_C varchar(36) not null, DOT_IDDOCUMENT_C varchar(36) not null, DOT_IDTAG_C varchar(36) not null, primary key (DOT_ID_C) );
|
||||
alter table T_AUTHENTICATION_TOKEN add constraint FK_AUT_IDUSER_C foreign key (AUT_IDUSER_C) references T_USER (USE_ID_C) on delete restrict on update restrict;
|
||||
alter table T_DOCUMENT add constraint FK_DOC_IDUSER_C foreign key (DOC_IDUSER_C) references T_USER (USE_ID_C) on delete restrict on update restrict;
|
||||
alter table T_FILE add constraint FK_FIL_IDDOC_C foreign key (FIL_IDDOC_C) references T_DOCUMENT (DOC_ID_C) on delete restrict on update restrict;
|
||||
alter table T_USER add constraint FK_USE_IDLOCALE_C foreign key (USE_IDLOCALE_C) references T_LOCALE (LOC_ID_C) on delete restrict on update restrict;
|
||||
alter table T_USER add constraint FK_USE_IDROLE_C foreign key (USE_IDROLE_C) references T_ROLE (ROL_ID_C) on delete restrict on update restrict;
|
||||
alter table T_TAG add constraint FK_TAG_IDUSER_C foreign key (TAG_IDUSER_C) references T_USER (USE_ID_C) on delete restrict on update restrict;
|
||||
alter table T_DOCUMENT_TAG add constraint FK_DOT_IDDOCUMENT_C foreign key (DOT_IDDOCUMENT_C) references T_DOCUMENT (DOC_ID_C) on delete restrict on update restrict;
|
||||
alter table T_DOCUMENT_TAG add constraint FK_DOT_IDTAG_C foreign key (DOT_IDTAG_C) references T_TAG (TAG_ID_C) on delete restrict on update restrict;
|
||||
alter table T_ROLE_BASE_FUNCTION add constraint FK_RBF_IDROLE_C foreign key (RBF_IDROLE_C) references T_ROLE (ROL_ID_C) on delete restrict on update restrict;
|
||||
alter table T_ROLE_BASE_FUNCTION add constraint FK_RBF_IDBASEFUNCTION_C foreign key (RBF_IDBASEFUNCTION_C) references T_BASE_FUNCTION (BAF_ID_C) on delete restrict on update restrict;
|
||||
insert into T_CONFIG(CFG_ID_C, CFG_VALUE_C) values('DB_VERSION', '0');
|
||||
|
@ -2,7 +2,9 @@ package com.sismics.docs.rest.resource;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.ws.rs.DELETE;
|
||||
@ -22,9 +24,12 @@ import org.codehaus.jettison.json.JSONObject;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.sismics.docs.core.dao.jpa.DocumentDao;
|
||||
import com.sismics.docs.core.dao.jpa.TagDao;
|
||||
import com.sismics.docs.core.dao.jpa.criteria.DocumentCriteria;
|
||||
import com.sismics.docs.core.dao.jpa.dto.DocumentDto;
|
||||
import com.sismics.docs.core.dao.jpa.dto.TagDto;
|
||||
import com.sismics.docs.core.model.jpa.Document;
|
||||
import com.sismics.docs.core.model.jpa.Tag;
|
||||
import com.sismics.docs.core.util.jpa.PaginatedList;
|
||||
import com.sismics.docs.core.util.jpa.PaginatedLists;
|
||||
import com.sismics.docs.core.util.jpa.SortCriteria;
|
||||
@ -69,6 +74,18 @@ public class DocumentResource extends BaseResource {
|
||||
document.put("description", documentDb.getDescription());
|
||||
document.put("create_date", documentDb.getCreateDate().getTime());
|
||||
|
||||
// Get tags
|
||||
TagDao tagDao = new TagDao();
|
||||
List<TagDto> tagDtoList = tagDao.getByDocumentId(id);
|
||||
List<JSONObject> tags = new ArrayList<JSONObject>();
|
||||
for (TagDto tagDto : tagDtoList) {
|
||||
JSONObject tag = new JSONObject();
|
||||
tag.put("id", tagDto.getId());
|
||||
tag.put("name", tagDto.getName());
|
||||
tags.add(tag);
|
||||
}
|
||||
document.put("tags", tags);
|
||||
|
||||
return Response.ok().entity(document).build();
|
||||
}
|
||||
|
||||
@ -132,7 +149,8 @@ public class DocumentResource extends BaseResource {
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response add(
|
||||
@FormParam("title") String title,
|
||||
@FormParam("description") String description) throws JSONException {
|
||||
@FormParam("description") String description,
|
||||
@FormParam("tags[]") List<String> tagList) throws JSONException {
|
||||
if (!authenticate()) {
|
||||
throw new ForbiddenClientException();
|
||||
}
|
||||
@ -149,6 +167,9 @@ public class DocumentResource extends BaseResource {
|
||||
document.setDescription(description);
|
||||
String documentId = documentDao.create(document);
|
||||
|
||||
// Update tags
|
||||
updateTagList(documentId, tagList);
|
||||
|
||||
JSONObject response = new JSONObject();
|
||||
response.put("id", documentId);
|
||||
return Response.ok().entity(response).build();
|
||||
@ -168,7 +189,8 @@ public class DocumentResource extends BaseResource {
|
||||
public Response update(
|
||||
@PathParam("id") String id,
|
||||
@FormParam("title") String title,
|
||||
@FormParam("description") String description) throws JSONException {
|
||||
@FormParam("description") String description,
|
||||
@FormParam("tags[]") List<String> tagList) throws JSONException {
|
||||
if (!authenticate()) {
|
||||
throw new ForbiddenClientException();
|
||||
}
|
||||
@ -194,11 +216,40 @@ public class DocumentResource extends BaseResource {
|
||||
document.setDescription(description);
|
||||
}
|
||||
|
||||
// Update tags
|
||||
updateTagList(id, tagList);
|
||||
|
||||
// Always return ok
|
||||
JSONObject response = new JSONObject();
|
||||
response.put("id", id);
|
||||
return Response.ok().entity(response).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update tags list on a document.
|
||||
*
|
||||
* @param documentId
|
||||
* @param tagList
|
||||
* @throws JSONException
|
||||
*/
|
||||
private void updateTagList(String documentId, List<String> tagList) throws JSONException {
|
||||
if (tagList != null) {
|
||||
TagDao tagDao = new TagDao();
|
||||
Set<String> tagSet = new HashSet<String>();
|
||||
Set<String> tagIdSet = new HashSet<String>();
|
||||
List<Tag> tagDbList = tagDao.getByUserId(principal.getId());
|
||||
for (Tag tagDb : tagDbList) {
|
||||
tagIdSet.add(tagDb.getId());
|
||||
}
|
||||
for (String tagId : tagList) {
|
||||
if (!tagIdSet.contains(tagId)) {
|
||||
throw new ClientException("TagNotFound", MessageFormat.format("Tag not found: {0}", tagId));
|
||||
}
|
||||
tagSet.add(tagId);
|
||||
}
|
||||
tagDao.updateTagList(documentId, tagSet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a document.
|
||||
|
@ -0,0 +1,126 @@
|
||||
package com.sismics.docs.rest.resource;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.FormParam;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.codehaus.jettison.json.JSONException;
|
||||
import org.codehaus.jettison.json.JSONObject;
|
||||
|
||||
import com.sismics.docs.core.dao.jpa.TagDao;
|
||||
import com.sismics.docs.core.model.jpa.Tag;
|
||||
import com.sismics.rest.exception.ClientException;
|
||||
import com.sismics.rest.exception.ForbiddenClientException;
|
||||
import com.sismics.rest.util.ValidationUtil;
|
||||
|
||||
/**
|
||||
* Tag REST resources.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
@Path("/tag")
|
||||
public class TagResource extends BaseResource {
|
||||
/**
|
||||
* Returns the list of all tags.
|
||||
*
|
||||
* @return Response
|
||||
* @throws JSONException
|
||||
*/
|
||||
@GET
|
||||
@Path("/list")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response list() throws JSONException {
|
||||
if (!authenticate()) {
|
||||
throw new ForbiddenClientException();
|
||||
}
|
||||
|
||||
TagDao tagDao = new TagDao();
|
||||
List<Tag> tagList = tagDao.getByUserId(principal.getId());
|
||||
JSONObject response = new JSONObject();
|
||||
List<JSONObject> items = new ArrayList<JSONObject>();
|
||||
for (Tag tag : tagList) {
|
||||
JSONObject item = new JSONObject();
|
||||
item.put("id", tag.getId());
|
||||
items.add(item);
|
||||
}
|
||||
response.put("tags", items);
|
||||
return Response.ok().entity(response).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new tag.
|
||||
*
|
||||
* @param name Name
|
||||
* @return Response
|
||||
* @throws JSONException
|
||||
*/
|
||||
@PUT
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response add(
|
||||
@FormParam("name") String name) throws JSONException {
|
||||
if (!authenticate()) {
|
||||
throw new ForbiddenClientException();
|
||||
}
|
||||
|
||||
// Validate input data
|
||||
name = ValidationUtil.validateLength(name, "title", 1, 36, false);
|
||||
|
||||
// Get the tag
|
||||
TagDao tagDao = new TagDao();
|
||||
Tag tag = tagDao.getByUserIdAndName(principal.getId(), name);
|
||||
if (tag != null) {
|
||||
throw new ClientException("AlreadyExistingTag", MessageFormat.format("Tag already exists: {0}", name));
|
||||
}
|
||||
|
||||
// Create the tag
|
||||
tag = new Tag();
|
||||
tag.setName(name);
|
||||
tag.setUserId(principal.getId());
|
||||
String tagId = tagDao.create(tag);
|
||||
|
||||
JSONObject response = new JSONObject();
|
||||
response.put("id", tagId);
|
||||
return Response.ok().entity(response).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a tag.
|
||||
*
|
||||
* @param name Name
|
||||
* @return Response
|
||||
* @throws JSONException
|
||||
*/
|
||||
@DELETE
|
||||
@Path("{id: [a-z0-9\\-]+}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response delete(
|
||||
@PathParam("id") String tagId) throws JSONException {
|
||||
if (!authenticate()) {
|
||||
throw new ForbiddenClientException();
|
||||
}
|
||||
|
||||
// Get the tag
|
||||
TagDao tagDao = new TagDao();
|
||||
Tag tag = tagDao.getByUserIdAndTagId(principal.getId(), tagId);
|
||||
if (tag == null) {
|
||||
throw new ClientException("TagNotFound", MessageFormat.format("Tag not found: {0}", tagId));
|
||||
}
|
||||
|
||||
// Delete the tag
|
||||
tagDao.delete(tagId);
|
||||
|
||||
JSONObject response = new JSONObject();
|
||||
response.put("status", "ok");
|
||||
return Response.ok().entity(response).build();
|
||||
}
|
||||
}
|
@ -37,6 +37,26 @@ App.controller('DocumentView', function($rootScope, $scope, $state, $stateParams
|
||||
$state.transitionTo('document.view.file', { id: $stateParams.id, fileId: file.id })
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a document.
|
||||
*/
|
||||
$scope.deleteDocument = function(document) {
|
||||
var title = 'Delete document';
|
||||
var msg = 'Do you really want to delete this document?';
|
||||
var btns = [{result:'cancel', label: 'Cancel'}, {result:'ok', label: 'OK', cssClass: 'btn-primary'}];
|
||||
|
||||
$dialog.messageBox(title, msg, btns)
|
||||
.open()
|
||||
.then(function(result) {
|
||||
if (result == 'ok') {
|
||||
Restangular.one('document', document.id).remove().then(function() {
|
||||
$scope.loadDocuments();
|
||||
$state.transitionTo('document.default');
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a file.
|
||||
*/
|
||||
|
@ -1,5 +1,6 @@
|
||||
<div class="text-right">
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-danger" ng-click="deleteDocument(document)"><span class="icon-trash icon-white"></span> Delete</button>
|
||||
<button class="btn btn-primary" ng-click="editDocument(document.id)"><span class="icon-pencil icon-white"></span> Edit</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -30,15 +30,27 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
clientUtil.createUser("document1");
|
||||
String document1Token = clientUtil.login("document1");
|
||||
|
||||
// Create a tag
|
||||
WebResource tagResource = resource().path("/tag");
|
||||
tagResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
||||
MultivaluedMapImpl postParams = new MultivaluedMapImpl();
|
||||
postParams.add("name", "Super tag");
|
||||
ClientResponse response = tagResource.put(ClientResponse.class, postParams);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
String tag1Id = json.optString("id");
|
||||
Assert.assertNotNull(tag1Id);
|
||||
|
||||
// Create a document
|
||||
WebResource documentResource = resource().path("/document");
|
||||
documentResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
||||
MultivaluedMapImpl postParams = new MultivaluedMapImpl();
|
||||
postParams = new MultivaluedMapImpl();
|
||||
postParams.add("title", "My super document 1");
|
||||
postParams.add("description", "My super description for document 1");
|
||||
ClientResponse response = documentResource.put(ClientResponse.class, postParams);
|
||||
postParams.add("tags[]", tag1Id);
|
||||
response = documentResource.put(ClientResponse.class, postParams);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
json = response.getEntity(JSONObject.class);
|
||||
String document1Id = json.optString("id");
|
||||
Assert.assertNotNull(document1Id);
|
||||
|
||||
@ -85,6 +97,20 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
json = response.getEntity(JSONObject.class);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
Assert.assertEquals(document1Id, json.getString("id"));
|
||||
JSONArray tags = json.getJSONArray("tags");
|
||||
Assert.assertEquals(1, tags.length());
|
||||
Assert.assertEquals(tag1Id, tags.getJSONObject(0).getString("id"));
|
||||
|
||||
// Create a tag
|
||||
tagResource = resource().path("/tag");
|
||||
tagResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
||||
postParams = new MultivaluedMapImpl();
|
||||
postParams.add("name", "Super tag 2");
|
||||
response = tagResource.put(ClientResponse.class, postParams);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
json = response.getEntity(JSONObject.class);
|
||||
String tag2Id = json.optString("id");
|
||||
Assert.assertNotNull(tag1Id);
|
||||
|
||||
// Update a document
|
||||
documentResource = resource().path("/document/" + document1Id);
|
||||
@ -92,6 +118,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
postParams = new MultivaluedMapImpl();
|
||||
postParams.add("title", "My new super document 1");
|
||||
postParams.add("description", "My new super description for document 1");
|
||||
postParams.add("tags[]", tag2Id);
|
||||
response = documentResource.post(ClientResponse.class, postParams);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
json = response.getEntity(JSONObject.class);
|
||||
@ -105,6 +132,9 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
Assert.assertTrue(json.getString("title").contains("new"));
|
||||
Assert.assertTrue(json.getString("description").contains("new"));
|
||||
tags = json.getJSONArray("tags");
|
||||
Assert.assertEquals(1, tags.length());
|
||||
Assert.assertEquals(tag2Id, tags.getJSONObject(0).getString("id"));
|
||||
|
||||
// Deletes a document
|
||||
documentResource = resource().path("/document/" + document1Id);
|
||||
|
@ -0,0 +1,71 @@
|
||||
package com.sismics.docs.rest;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.codehaus.jettison.json.JSONArray;
|
||||
import org.codehaus.jettison.json.JSONException;
|
||||
import org.codehaus.jettison.json.JSONObject;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sismics.docs.rest.BaseJerseyTest;
|
||||
import com.sismics.docs.rest.filter.CookieAuthenticationFilter;
|
||||
import com.sun.jersey.api.client.ClientResponse;
|
||||
import com.sun.jersey.api.client.ClientResponse.Status;
|
||||
import com.sun.jersey.api.client.WebResource;
|
||||
import com.sun.jersey.core.util.MultivaluedMapImpl;
|
||||
|
||||
/**
|
||||
* Test the tag resource.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class TestTagResource extends BaseJerseyTest {
|
||||
/**
|
||||
* Test the tag resource.
|
||||
*
|
||||
* @throws JSONException
|
||||
*/
|
||||
@Test
|
||||
public void testTagResource() throws JSONException {
|
||||
// Login tag1
|
||||
clientUtil.createUser("tag1");
|
||||
String tag1Token = clientUtil.login("tag1");
|
||||
|
||||
// Create a tag
|
||||
WebResource tagResource = resource().path("/tag");
|
||||
tagResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
||||
MultivaluedMapImpl postParams = new MultivaluedMapImpl();
|
||||
postParams.add("name", "Tag 3");
|
||||
ClientResponse response = tagResource.put(ClientResponse.class, postParams);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
JSONObject json = response.getEntity(JSONObject.class);
|
||||
String tag3Id = json.optString("id");
|
||||
Assert.assertNotNull(tag3Id);
|
||||
|
||||
// Get all tags
|
||||
tagResource = resource().path("/tag/list");
|
||||
tagResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
||||
response = tagResource.get(ClientResponse.class);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
json = response.getEntity(JSONObject.class);
|
||||
JSONArray tags = json.getJSONArray("tags");
|
||||
Assert.assertTrue(tags.length() > 0);
|
||||
|
||||
// Deletes a tag
|
||||
tagResource = resource().path("/tag/" + tag3Id);
|
||||
tagResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
||||
response = tagResource.delete(ClientResponse.class);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
json = response.getEntity(JSONObject.class);
|
||||
Assert.assertEquals("ok", json.getString("status"));
|
||||
|
||||
// Get all tags
|
||||
tagResource = resource().path("/tag/list");
|
||||
tagResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
||||
response = tagResource.get(ClientResponse.class);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
json = response.getEntity(JSONObject.class);
|
||||
tags = json.getJSONArray("tags");
|
||||
Assert.assertTrue(tags.length() == 0);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user