mirror of
https://github.com/sismics/docs.git
synced 2024-12-22 03:13:48 +01:00
Specify document search parameter as HTTP params (#722)
This commit is contained in:
parent
f9b5a5212d
commit
04c43ebf7b
@ -87,7 +87,7 @@ public class DocumentDao {
|
||||
}
|
||||
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
StringBuilder sb = new StringBuilder("select distinct d.DOC_ID_C, d.DOC_TITLE_C, d.DOC_DESCRIPTION_C, d.DOC_SUBJECT_C, d.DOC_IDENTIFIER_C, d.DOC_PUBLISHER_C, d.DOC_FORMAT_C, d.DOC_SOURCE_C, d.DOC_TYPE_C, d.DOC_COVERAGE_C, d.DOC_RIGHTS_C, d.DOC_CREATEDATE_D, d.DOC_UPDATEDATE_D, d.DOC_LANGUAGE_C, ");
|
||||
StringBuilder sb = new StringBuilder("select distinct d.DOC_ID_C, d.DOC_TITLE_C, d.DOC_DESCRIPTION_C, d.DOC_SUBJECT_C, d.DOC_IDENTIFIER_C, d.DOC_PUBLISHER_C, d.DOC_FORMAT_C, d.DOC_SOURCE_C, d.DOC_TYPE_C, d.DOC_COVERAGE_C, d.DOC_RIGHTS_C, d.DOC_CREATEDATE_D, d.DOC_UPDATEDATE_D, d.DOC_LANGUAGE_C, d.DOC_IDFILE_C,");
|
||||
sb.append(" (select count(s.SHA_ID_C) from T_SHARE s, T_ACL ac where ac.ACL_SOURCEID_C = d.DOC_ID_C and ac.ACL_TARGETID_C = s.SHA_ID_C and ac.ACL_DELETEDATE_D is null and s.SHA_DELETEDATE_D is null) shareCount, ");
|
||||
sb.append(" (select count(f.FIL_ID_C) from T_FILE f where f.FIL_DELETEDATE_D is null and f.FIL_IDDOC_C = d.DOC_ID_C) fileCount, ");
|
||||
sb.append(" u.USE_USERNAME_C ");
|
||||
@ -121,6 +121,7 @@ public class DocumentDao {
|
||||
documentDto.setCreateTimestamp(((Timestamp) o[i++]).getTime());
|
||||
documentDto.setUpdateTimestamp(((Timestamp) o[i++]).getTime());
|
||||
documentDto.setLanguage((String) o[i++]);
|
||||
documentDto.setFileId((String) o[i++]);
|
||||
documentDto.setShared(((Number) o[i++]).intValue() > 0);
|
||||
documentDto.setFileCount(((Number) o[i++]).intValue());
|
||||
documentDto.setCreator((String) o[i]);
|
||||
|
@ -19,7 +19,7 @@ public class DocumentCriteria {
|
||||
/**
|
||||
* Search query.
|
||||
*/
|
||||
private String search;
|
||||
private String simpleSearch;
|
||||
|
||||
/**
|
||||
* Full content search query.
|
||||
@ -96,12 +96,12 @@ public class DocumentCriteria {
|
||||
this.targetIdList = targetIdList;
|
||||
}
|
||||
|
||||
public String getSearch() {
|
||||
return search;
|
||||
public String getSimpleSearch() {
|
||||
return simpleSearch;
|
||||
}
|
||||
|
||||
public void setSearch(String search) {
|
||||
this.search = search;
|
||||
public void setSimpleSearch(String search) {
|
||||
this.simpleSearch = search;
|
||||
}
|
||||
|
||||
public String getFullSearch() {
|
||||
|
@ -276,9 +276,8 @@ public class LuceneIndexingHandler implements IndexingHandler {
|
||||
criteriaList.add("(a.ACL_ID_C is not null or a2.ACL_ID_C is not null)");
|
||||
}
|
||||
parameterMap.put("targetIdList", criteria.getTargetIdList());
|
||||
|
||||
if (!Strings.isNullOrEmpty(criteria.getSearch()) || !Strings.isNullOrEmpty(criteria.getFullSearch())) {
|
||||
documentSearchMap = search(criteria.getSearch(), criteria.getFullSearch());
|
||||
if (!Strings.isNullOrEmpty(criteria.getSimpleSearch()) || !Strings.isNullOrEmpty(criteria.getFullSearch())) {
|
||||
documentSearchMap = search(criteria.getSimpleSearch(), criteria.getFullSearch());
|
||||
if (documentSearchMap.isEmpty()) {
|
||||
// If the search doesn't find any document, the request should return nothing
|
||||
documentSearchMap.put(UUID.randomUUID().toString(), null);
|
||||
@ -413,14 +412,14 @@ public class LuceneIndexingHandler implements IndexingHandler {
|
||||
/**
|
||||
* Fulltext search in files and documents.
|
||||
*
|
||||
* @param searchQuery Search query on metadatas
|
||||
* @param simpleSearchQuery Search query on metadatas
|
||||
* @param fullSearchQuery Search query on all fields
|
||||
* @return Map of document IDs as key and highlight as value
|
||||
* @throws Exception e
|
||||
*/
|
||||
private Map<String, String> search(String searchQuery, String fullSearchQuery) throws Exception {
|
||||
private Map<String, String> search(String simpleSearchQuery, String fullSearchQuery) throws Exception {
|
||||
// The fulltext query searches in all fields
|
||||
searchQuery = searchQuery + " " + fullSearchQuery;
|
||||
String searchQuery = simpleSearchQuery + " " + fullSearchQuery;
|
||||
|
||||
// Build search query
|
||||
Analyzer analyzer = new StandardAnalyzer();
|
||||
|
@ -68,7 +68,7 @@ public class PaginatedLists {
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a query and returns the data of the currunt page.
|
||||
* Executes a query and returns the data of the current page.
|
||||
*
|
||||
* @param paginatedList Paginated list object containing parameters, and into which results are added by side effects
|
||||
* @param queryParam Query parameters
|
||||
@ -82,18 +82,6 @@ public class PaginatedLists {
|
||||
q.setMaxResults(paginatedList.getLimit());
|
||||
return q.getResultList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a paginated request with 2 native queries (one to count the number of results, and one to return the page).
|
||||
*
|
||||
* @param paginatedList Paginated list object containing parameters, and into which results are added by side effects
|
||||
* @param queryParam Query parameters
|
||||
* @return List of results
|
||||
*/
|
||||
public static <E> List<Object[]> executePaginatedQuery(PaginatedList<E> paginatedList, QueryParam queryParam) {
|
||||
executeCountQuery(paginatedList, queryParam);
|
||||
return executeResultQuery(paginatedList, queryParam);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a paginated request with 2 native queries (one to count the number of results, and one to return the page).
|
||||
|
@ -30,7 +30,7 @@ import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
||||
*/
|
||||
public abstract class BaseTransactionalTest extends BaseTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
public void setUp() {
|
||||
// Initialize the entity manager
|
||||
EntityManager em = EMF.get().createEntityManager();
|
||||
ThreadLocalContext context = ThreadLocalContext.get();
|
||||
@ -40,7 +40,8 @@ public abstract class BaseTransactionalTest extends BaseTest {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
public void tearDown() {
|
||||
ThreadLocalContext.get().getEntityManager().getTransaction().rollback();
|
||||
}
|
||||
|
||||
protected User createUser(String userName) throws Exception {
|
||||
|
@ -63,7 +63,11 @@ public abstract class BaseJerseyTest extends JerseyTest {
|
||||
* Test mail server.
|
||||
*/
|
||||
private Wiser wiser;
|
||||
|
||||
|
||||
public String adminToken() {
|
||||
return clientUtil.login("admin", "admin", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
|
||||
return new ExternalTestContainerFactory();
|
||||
|
@ -1,7 +1,5 @@
|
||||
package com.sismics.docs.rest.resource;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.sismics.docs.core.constant.AclType;
|
||||
import com.sismics.docs.core.constant.ConfigType;
|
||||
@ -36,10 +34,10 @@ import com.sismics.docs.core.util.DocumentUtil;
|
||||
import com.sismics.docs.core.util.FileUtil;
|
||||
import com.sismics.docs.core.util.MetadataUtil;
|
||||
import com.sismics.docs.core.util.PdfUtil;
|
||||
import com.sismics.docs.core.util.TagUtil;
|
||||
import com.sismics.docs.core.util.jpa.PaginatedList;
|
||||
import com.sismics.docs.core.util.jpa.PaginatedLists;
|
||||
import com.sismics.docs.core.util.jpa.SortCriteria;
|
||||
import com.sismics.docs.rest.util.DocumentSearchCriteriaUtil;
|
||||
import com.sismics.rest.exception.ClientException;
|
||||
import com.sismics.rest.exception.ForbiddenClientException;
|
||||
import com.sismics.rest.exception.ServerException;
|
||||
@ -57,6 +55,7 @@ import jakarta.ws.rs.Consumes;
|
||||
import jakarta.ws.rs.DELETE;
|
||||
import jakarta.ws.rs.FormParam;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.HEAD;
|
||||
import jakarta.ws.rs.NotFoundException;
|
||||
import jakarta.ws.rs.POST;
|
||||
import jakarta.ws.rs.PUT;
|
||||
@ -69,11 +68,6 @@ import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
|
||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.joda.time.format.DateTimeFormatterBuilder;
|
||||
import org.joda.time.format.DateTimeParser;
|
||||
|
||||
import javax.mail.Message;
|
||||
import javax.mail.MessagingException;
|
||||
@ -97,26 +91,12 @@ import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Document REST resources.
|
||||
*
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
@Path("/document")
|
||||
public class DocumentResource extends BaseResource {
|
||||
|
||||
protected static final DateTimeParser YEAR_PARSER = DateTimeFormat.forPattern("yyyy").getParser();
|
||||
protected static final DateTimeParser MONTH_PARSER = DateTimeFormat.forPattern("yyyy-MM").getParser();
|
||||
protected static final DateTimeParser DAY_PARSER = DateTimeFormat.forPattern("yyyy-MM-dd").getParser();
|
||||
|
||||
private static final DateTimeFormatter DAY_FORMATTER = new DateTimeFormatter(null, DAY_PARSER);
|
||||
private static final DateTimeFormatter MONTH_FORMATTER = new DateTimeFormatter(null, MONTH_PARSER);
|
||||
private static final DateTimeFormatter YEAR_FORMATTER = new DateTimeFormatter(null, YEAR_PARSER);
|
||||
|
||||
private static final DateTimeParser[] DATE_PARSERS = new DateTimeParser[]{
|
||||
YEAR_PARSER,
|
||||
MONTH_PARSER,
|
||||
DAY_PARSER};
|
||||
private static final DateTimeFormatter DATE_FORMATTER = new DateTimeFormatterBuilder().append( null, DATE_PARSERS).toFormatter();
|
||||
|
||||
/**
|
||||
* Returns a document.
|
||||
*
|
||||
@ -124,8 +104,8 @@ public class DocumentResource extends BaseResource {
|
||||
* @apiName GetDocument
|
||||
* @apiGroup Document
|
||||
* @apiParam {String} id Document ID
|
||||
* @apiParam {String} share Share ID
|
||||
* @apiParam {Booleans} files If true includes files information
|
||||
* @apiParam {String} [share] Share ID
|
||||
* @apiParam {Boolean} [files] If true includes files information
|
||||
* @apiSuccess {String} id ID
|
||||
* @apiSuccess {String} title Title
|
||||
* @apiSuccess {String} description Description
|
||||
@ -147,6 +127,7 @@ public class DocumentResource extends BaseResource {
|
||||
* @apiSuccess {String} coverage Coverage
|
||||
* @apiSuccess {String} rights Rights
|
||||
* @apiSuccess {String} creator Username of the creator
|
||||
* @apiSuccess {String} file_id Main file ID
|
||||
* @apiSuccess {Boolean} writable True if the document is writable by the current user
|
||||
* @apiSuccess {Object[]} acls List of ACL
|
||||
* @apiSuccess {String} acls.id ID
|
||||
@ -198,22 +179,24 @@ public class DocumentResource extends BaseResource {
|
||||
@QueryParam("share") String shareId,
|
||||
@QueryParam("files") Boolean files) {
|
||||
authenticate();
|
||||
|
||||
|
||||
DocumentDao documentDao = new DocumentDao();
|
||||
DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId));
|
||||
if (documentDto == null) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
JsonObjectBuilder document = Json.createObjectBuilder()
|
||||
.add("id", documentDto.getId())
|
||||
.add("title", documentDto.getTitle())
|
||||
.add("description", JsonUtil.nullable(documentDto.getDescription()))
|
||||
.add("create_date", documentDto.getCreateTimestamp())
|
||||
.add("update_date", documentDto.getUpdateTimestamp())
|
||||
.add("language", documentDto.getLanguage())
|
||||
.add("shared", documentDto.getShared())
|
||||
.add("file_count", documentDto.getFileCount());
|
||||
|
||||
JsonObjectBuilder document = createDocumentObjectBuilder(documentDto)
|
||||
.add("creator", documentDto.getCreator())
|
||||
.add("coverage", JsonUtil.nullable(documentDto.getCoverage()))
|
||||
.add("file_count", documentDto.getFileCount())
|
||||
.add("format", JsonUtil.nullable(documentDto.getFormat()))
|
||||
.add("identifier", JsonUtil.nullable(documentDto.getIdentifier()))
|
||||
.add("publisher", JsonUtil.nullable(documentDto.getPublisher()))
|
||||
.add("rights", JsonUtil.nullable(documentDto.getRights()))
|
||||
.add("source", JsonUtil.nullable(documentDto.getSource()))
|
||||
.add("subject", JsonUtil.nullable(documentDto.getSubject()))
|
||||
.add("type", JsonUtil.nullable(documentDto.getType()));
|
||||
|
||||
List<TagDto> tagDtoList = null;
|
||||
if (principal.isAnonymous()) {
|
||||
@ -227,26 +210,8 @@ public class DocumentResource extends BaseResource {
|
||||
.setTargetIdList(getTargetIdList(null)) // No tags for shares
|
||||
.setDocumentId(documentId),
|
||||
new SortCriteria(1, true));
|
||||
JsonArrayBuilder tags = Json.createArrayBuilder();
|
||||
for (TagDto tagDto : tagDtoList) {
|
||||
tags.add(Json.createObjectBuilder()
|
||||
.add("id", tagDto.getId())
|
||||
.add("name", tagDto.getName())
|
||||
.add("color", tagDto.getColor()));
|
||||
}
|
||||
document.add("tags", tags);
|
||||
document.add("tags", createTagsArrayBuilder(tagDtoList));
|
||||
}
|
||||
|
||||
// Below is specific to GET /document/id
|
||||
document.add("subject", JsonUtil.nullable(documentDto.getSubject()));
|
||||
document.add("identifier", JsonUtil.nullable(documentDto.getIdentifier()));
|
||||
document.add("publisher", JsonUtil.nullable(documentDto.getPublisher()));
|
||||
document.add("format", JsonUtil.nullable(documentDto.getFormat()));
|
||||
document.add("source", JsonUtil.nullable(documentDto.getSource()));
|
||||
document.add("type", JsonUtil.nullable(documentDto.getType()));
|
||||
document.add("coverage", JsonUtil.nullable(documentDto.getCoverage()));
|
||||
document.add("rights", JsonUtil.nullable(documentDto.getRights()));
|
||||
document.add("creator", documentDto.getCreator());
|
||||
|
||||
// Add ACL
|
||||
AclUtil.addAcls(document, documentId, getTargetIdList(shareId));
|
||||
@ -270,7 +235,7 @@ public class DocumentResource extends BaseResource {
|
||||
}
|
||||
document.add("inherited_acls", aclList);
|
||||
}
|
||||
|
||||
|
||||
// Add contributors
|
||||
ContributorDao contributorDao = new ContributorDao();
|
||||
List<ContributorDto> contributorDtoList = contributorDao.getByDocumentId(documentId);
|
||||
@ -281,7 +246,7 @@ public class DocumentResource extends BaseResource {
|
||||
.add("email", contributorDto.getEmail()));
|
||||
}
|
||||
document.add("contributors", contributorList);
|
||||
|
||||
|
||||
// Add relations
|
||||
RelationDao relationDao = new RelationDao();
|
||||
List<RelationDto> relationDtoList = relationDao.getByDocumentId(documentId);
|
||||
@ -320,7 +285,7 @@ public class DocumentResource extends BaseResource {
|
||||
|
||||
return Response.ok().entity(document.build()).build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Export a document to PDF.
|
||||
*
|
||||
@ -330,7 +295,6 @@ public class DocumentResource extends BaseResource {
|
||||
* @apiParam {String} id Document ID
|
||||
* @apiParam {String} share Share ID
|
||||
* @apiParam {Boolean} metadata If true, export metadata
|
||||
* @apiParam {Boolean} comments If true, export comments
|
||||
* @apiParam {Boolean} fitimagetopage If true, fit the images to pages
|
||||
* @apiParam {Number} margin Margin around the pages, in millimeter
|
||||
* @apiSuccess {String} pdf The whole response is the PDF file
|
||||
@ -342,7 +306,6 @@ public class DocumentResource extends BaseResource {
|
||||
* @param documentId Document ID
|
||||
* @param shareId Share ID
|
||||
* @param metadata Export metadata
|
||||
* @param comments Export comments
|
||||
* @param fitImageToPage Fit images to page
|
||||
* @param marginStr Margins
|
||||
* @return Response
|
||||
@ -353,21 +316,20 @@ public class DocumentResource extends BaseResource {
|
||||
@PathParam("id") String documentId,
|
||||
@QueryParam("share") String shareId,
|
||||
final @QueryParam("metadata") Boolean metadata,
|
||||
final @QueryParam("comments") Boolean comments,
|
||||
final @QueryParam("fitimagetopage") Boolean fitImageToPage,
|
||||
@QueryParam("margin") String marginStr) {
|
||||
authenticate();
|
||||
|
||||
|
||||
// Validate input
|
||||
final int margin = ValidationUtil.validateInteger(marginStr, "margin");
|
||||
|
||||
|
||||
// Get document and check read permission
|
||||
DocumentDao documentDao = new DocumentDao();
|
||||
final DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId));
|
||||
if (documentDto == null) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
|
||||
// Get files
|
||||
FileDao fileDao = new FileDao();
|
||||
UserDao userDao = new UserDao();
|
||||
@ -378,7 +340,7 @@ public class DocumentResource extends BaseResource {
|
||||
User user = userDao.getById(file.getUserId());
|
||||
file.setPrivateKey(user.getPrivateKey());
|
||||
}
|
||||
|
||||
|
||||
// Convert to PDF
|
||||
StreamingOutput stream = outputStream -> {
|
||||
try {
|
||||
@ -393,19 +355,36 @@ public class DocumentResource extends BaseResource {
|
||||
.header("Content-Disposition", "inline; filename=\"" + documentDto.getTitle() + ".pdf\"")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all documents.
|
||||
* Returns all documents, if a parameter is considered invalid, the search result will be empty.
|
||||
*
|
||||
* @api {get} /document/list Get documents
|
||||
* @apiName GetDocumentList
|
||||
* @apiGroup Document
|
||||
* @apiParam {String} limit Total number of documents to return
|
||||
* @apiParam {String} offset Start at this index
|
||||
* @apiParam {Number} sort_column Column index to sort on
|
||||
* @apiParam {Boolean} asc If true, sort in ascending order
|
||||
* @apiParam {String} search Search query (see "Document search syntax" on the top of the page for explanations)
|
||||
* @apiParam {Booleans} files If true includes files information
|
||||
*
|
||||
* @apiParam {String} [limit] Total number of documents to return (default is <code>10</code>)
|
||||
* @apiParam {String} [offset] Start at this index (default is <code>0</code>)
|
||||
* @apiParam {Number} [sort_column] Column index to sort on
|
||||
* @apiParam {Boolean} [asc] If <code>true</code> sorts in ascending order
|
||||
* @apiParam {String} [search] Search query (see "Document search syntax" on the top of the page for explanations) when the input is entered by a human.
|
||||
* @apiParam {Boolean} [files] If <code>true</code> includes files information
|
||||
*
|
||||
* @apiParam {String} [search[after]] The document must have been created after or at the value moment, accepted format is <code>yyyy-MM-dd</code>
|
||||
* @apiParam {String} [search[before]] The document must have been created before or at the value moment, accepted format is <code>yyyy-MM-dd</code>
|
||||
* @apiParam {String} [search[by]] The document must have been created by the specified creator's username with an exact match, the user must not be deleted
|
||||
* @apiParam {String} [search[full]] Used as a search criteria for all fields including the document's files content, several comma-separated values can be specified and the document must match any of them
|
||||
* @apiParam {String} [search[lang]] The document must be of the specified language (example: <code>en</code>)
|
||||
* @apiParam {String} [search[mime]] The document must be of the specified mime type (example: <code>image/png</code>)
|
||||
* @apiParam {String} [search[simple]] Used as a search criteria for all fields except the document's files content, several comma-separated values can be specified and the document must match any of them
|
||||
* @apiParam {Boolean} [search[shared]] If <code>true</code> the document must be shared, else it is ignored
|
||||
* @apiParam {String} [search[tag]] The document must contain a tag or a child of a tag that starts with the value, case is ignored, several comma-separated values can be specified and the document must match all tag filters
|
||||
* @apiParam {String} [search[nottag]] The document must not contain a tag or a child of a tag that starts with the value, case is ignored, several comma-separated values can be specified and the document must match all tag filters
|
||||
* @apiParam {String} [search[title]] The document's title must be the value, several comma-separated values can be specified and the document must match any of the titles
|
||||
* @apiParam {String} [search[uafter]] The document must have been updated after or at the value moment, accepted format is <code>yyyy-MM-dd</code>
|
||||
* @apiParam {String} [search[ubefore]] The document must have been updated before or at the value moment, accepted format is <code>yyyy-MM-dd</code>
|
||||
* @apiParam {String} [search[workflow]] If the value is <code>me</code> the document must have an active route, for other values the criteria is ignored
|
||||
*
|
||||
* @apiSuccess {Number} total Total number of documents
|
||||
* @apiSuccess {Object[]} documents List of documents
|
||||
* @apiSuccess {String} documents.id ID
|
||||
@ -431,6 +410,7 @@ public class DocumentResource extends BaseResource {
|
||||
* @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
|
||||
* @apiPermission user
|
||||
@ -452,19 +432,56 @@ public class DocumentResource extends BaseResource {
|
||||
@QueryParam("sort_column") Integer sortColumn,
|
||||
@QueryParam("asc") Boolean asc,
|
||||
@QueryParam("search") String search,
|
||||
@QueryParam("files") Boolean files) {
|
||||
@QueryParam("files") Boolean files,
|
||||
|
||||
@QueryParam("search[after]") String searchCreatedAfter,
|
||||
@QueryParam("search[before]") String searchCreatedBefore,
|
||||
@QueryParam("search[by]") String searchBy,
|
||||
@QueryParam("search[full]") String searchFull,
|
||||
@QueryParam("search[lang]") String searchLang,
|
||||
@QueryParam("search[mime]") String searchMime,
|
||||
@QueryParam("search[shared]") Boolean searchShared,
|
||||
@QueryParam("search[simple]") String searchSimple,
|
||||
@QueryParam("search[tag]") String searchTag,
|
||||
@QueryParam("search[nottag]") String searchTagNot,
|
||||
@QueryParam("search[title]") String searchTitle,
|
||||
@QueryParam("search[uafter]") String searchUpdatedAfter,
|
||||
@QueryParam("search[ubefore]") String searchUpdatedBefore,
|
||||
@QueryParam("search[searchworkflow]") String searchWorkflow
|
||||
) {
|
||||
if (!authenticate()) {
|
||||
throw new ForbiddenClientException();
|
||||
}
|
||||
|
||||
|
||||
JsonObjectBuilder response = Json.createObjectBuilder();
|
||||
JsonArrayBuilder documents = Json.createArrayBuilder();
|
||||
|
||||
|
||||
TagDao tagDao = new TagDao();
|
||||
PaginatedList<DocumentDto> paginatedList = PaginatedLists.create(limit, offset);
|
||||
List<String> suggestionList = Lists.newArrayList();
|
||||
SortCriteria sortCriteria = new SortCriteria(sortColumn, asc);
|
||||
DocumentCriteria documentCriteria = parseSearchQuery(search);
|
||||
|
||||
List<TagDto> allTagDtoList = tagDao.findByCriteria(new TagCriteria().setTargetIdList(getTargetIdList(null)), null);
|
||||
|
||||
DocumentCriteria documentCriteria = DocumentSearchCriteriaUtil.parseSearchQuery(search, allTagDtoList);
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
searchBy,
|
||||
searchCreatedAfter,
|
||||
searchCreatedBefore,
|
||||
searchFull,
|
||||
searchLang,
|
||||
searchMime,
|
||||
searchShared,
|
||||
searchSimple,
|
||||
searchTag,
|
||||
searchTagNot,
|
||||
searchTitle,
|
||||
searchUpdatedAfter,
|
||||
searchUpdatedBefore,
|
||||
searchWorkflow,
|
||||
allTagDtoList);
|
||||
|
||||
documentCriteria.setTargetIdList(getTargetIdList(null));
|
||||
try {
|
||||
AppContext.getInstance().getIndexingHandler().findByCriteria(paginatedList, suggestionList, documentCriteria, sortCriteria);
|
||||
@ -488,13 +505,6 @@ public class DocumentResource extends BaseResource {
|
||||
List<TagDto> tagDtoList = tagDao.findByCriteria(new TagCriteria()
|
||||
.setTargetIdList(getTargetIdList(null))
|
||||
.setDocumentId(documentDto.getId()), new SortCriteria(1, true));
|
||||
JsonArrayBuilder tags = Json.createArrayBuilder();
|
||||
for (TagDto tagDto : tagDtoList) {
|
||||
tags.add(Json.createObjectBuilder()
|
||||
.add("id", tagDto.getId())
|
||||
.add("name", tagDto.getName())
|
||||
.add("color", tagDto.getColor()));
|
||||
}
|
||||
|
||||
Long filesCount;
|
||||
Collection<File> filesOfDocument = null;
|
||||
@ -506,20 +516,13 @@ public class DocumentResource extends BaseResource {
|
||||
filesCount = filesCountByDocument.getOrDefault(documentDto.getId(), 0L);
|
||||
}
|
||||
|
||||
JsonObjectBuilder documentObjectBuilder = Json.createObjectBuilder()
|
||||
.add("id", documentDto.getId())
|
||||
.add("highlight", JsonUtil.nullable(documentDto.getHighlight()))
|
||||
.add("file_id", JsonUtil.nullable(documentDto.getFileId()))
|
||||
.add("title", documentDto.getTitle())
|
||||
.add("description", JsonUtil.nullable(documentDto.getDescription()))
|
||||
.add("create_date", documentDto.getCreateTimestamp())
|
||||
.add("update_date", documentDto.getUpdateTimestamp())
|
||||
.add("language", documentDto.getLanguage())
|
||||
.add("shared", documentDto.getShared())
|
||||
JsonObjectBuilder documentObjectBuilder = createDocumentObjectBuilder(documentDto)
|
||||
.add("active_route", documentDto.isActiveRoute())
|
||||
.add("current_step_name", JsonUtil.nullable(documentDto.getCurrentStepName()))
|
||||
.add("highlight", JsonUtil.nullable(documentDto.getHighlight()))
|
||||
.add("file_count", filesCount)
|
||||
.add("tags", tags);
|
||||
.add("tags", createTagsArrayBuilder(tagDtoList));
|
||||
|
||||
if (Boolean.TRUE == files) {
|
||||
JsonArrayBuilder filesArrayBuilder = Json.createArrayBuilder();
|
||||
for (File fileDb : filesOfDocument) {
|
||||
@ -538,7 +541,7 @@ public class DocumentResource extends BaseResource {
|
||||
response.add("total", paginatedList.getResultCount())
|
||||
.add("documents", documents)
|
||||
.add("suggestions", suggestions);
|
||||
|
||||
|
||||
return Response.ok().entity(response.build()).build();
|
||||
}
|
||||
|
||||
@ -567,188 +570,44 @@ public class DocumentResource extends BaseResource {
|
||||
@FormParam("sort_column") Integer sortColumn,
|
||||
@FormParam("asc") Boolean asc,
|
||||
@FormParam("search") String search,
|
||||
@FormParam("files") Boolean files) {
|
||||
return list(limit, offset, sortColumn, asc, search, files);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a query according to the specified syntax, eg.:
|
||||
* tag:assurance tag:other before:2012 after:2011-09 shared:yes lang:fra thing
|
||||
*
|
||||
* @param search Search query
|
||||
* @return DocumentCriteria
|
||||
*/
|
||||
private DocumentCriteria parseSearchQuery(String search) {
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
if (Strings.isNullOrEmpty(search)) {
|
||||
return documentCriteria;
|
||||
}
|
||||
|
||||
TagDao tagDao = new TagDao();
|
||||
List<TagDto> allTagDtoList = tagDao.findByCriteria(new TagCriteria().setTargetIdList(getTargetIdList(null)), null);
|
||||
UserDao userDao = new UserDao();
|
||||
|
||||
String[] criteriaList = search.split(" +");
|
||||
List<String> query = new ArrayList<>();
|
||||
List<String> fullQuery = new ArrayList<>();
|
||||
for (String criteria : criteriaList) {
|
||||
String[] params = criteria.split(":");
|
||||
if (params.length != 2 || Strings.isNullOrEmpty(params[0]) || Strings.isNullOrEmpty(params[1])) {
|
||||
// This is not a special criteria, do a fulltext search on it
|
||||
fullQuery.add(criteria);
|
||||
continue;
|
||||
}
|
||||
String paramName = params[0];
|
||||
String paramValue = params[1];
|
||||
|
||||
switch (paramName) {
|
||||
case "tag":
|
||||
case "!tag":
|
||||
// New tag criteria
|
||||
List<TagDto> tagDtoList = TagUtil.findByName(paramValue, allTagDtoList);
|
||||
if (tagDtoList.isEmpty()) {
|
||||
// No tag found, the request must return nothing
|
||||
documentCriteria.getTagIdList().add(Lists.newArrayList(UUID.randomUUID().toString()));
|
||||
} else {
|
||||
List<String> tagIdList = Lists.newArrayList();
|
||||
for (TagDto tagDto : tagDtoList) {
|
||||
tagIdList.add(tagDto.getId());
|
||||
List<TagDto> childrenTagDtoList = TagUtil.findChildren(tagDto, allTagDtoList);
|
||||
for (TagDto childrenTagDto : childrenTagDtoList) {
|
||||
tagIdList.add(childrenTagDto.getId());
|
||||
}
|
||||
}
|
||||
if (paramName.startsWith("!")) {
|
||||
documentCriteria.getExcludedTagIdList().add(tagIdList);
|
||||
} else {
|
||||
documentCriteria.getTagIdList().add(tagIdList);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "after":
|
||||
case "before":
|
||||
case "uafter":
|
||||
case "ubefore":
|
||||
// New date span criteria
|
||||
try {
|
||||
boolean isUpdated = paramName.startsWith("u");
|
||||
DateTime date = DATE_FORMATTER.parseDateTime(paramValue);
|
||||
if (paramName.endsWith("before")) {
|
||||
if (isUpdated) documentCriteria.setUpdateDateMax(date.toDate());
|
||||
else documentCriteria.setCreateDateMax(date.toDate());
|
||||
} else {
|
||||
if (isUpdated) documentCriteria.setUpdateDateMin(date.toDate());
|
||||
else documentCriteria.setCreateDateMin(date.toDate());
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Invalid date, returns no documents
|
||||
documentCriteria.setCreateDateMin(new Date(0));
|
||||
documentCriteria.setCreateDateMax(new Date(0));
|
||||
}
|
||||
break;
|
||||
case "uat":
|
||||
case "at":
|
||||
// New specific date criteria
|
||||
boolean isUpdated = params[0].startsWith("u");
|
||||
try {
|
||||
switch (paramValue.length()) {
|
||||
case 10: {
|
||||
DateTime date = DATE_FORMATTER.parseDateTime(params[1]);
|
||||
if (isUpdated) {
|
||||
documentCriteria.setUpdateDateMin(date.toDate());
|
||||
documentCriteria.setUpdateDateMax(date.plusDays(1).minusSeconds(1).toDate());
|
||||
} else {
|
||||
documentCriteria.setCreateDateMin(date.toDate());
|
||||
documentCriteria.setCreateDateMax(date.plusDays(1).minusSeconds(1).toDate());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
DateTime date = MONTH_FORMATTER.parseDateTime(params[1]);
|
||||
if (isUpdated) {
|
||||
documentCriteria.setUpdateDateMin(date.toDate());
|
||||
documentCriteria.setUpdateDateMax(date.plusMonths(1).minusSeconds(1).toDate());
|
||||
} else {
|
||||
documentCriteria.setCreateDateMin(date.toDate());
|
||||
documentCriteria.setCreateDateMax(date.plusMonths(1).minusSeconds(1).toDate());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
DateTime date = YEAR_FORMATTER.parseDateTime(params[1]);
|
||||
if (isUpdated) {
|
||||
documentCriteria.setUpdateDateMin(date.toDate());
|
||||
documentCriteria.setUpdateDateMax(date.plusYears(1).minusSeconds(1).toDate());
|
||||
} else {
|
||||
documentCriteria.setCreateDateMin(date.toDate());
|
||||
documentCriteria.setCreateDateMax(date.plusYears(1).minusSeconds(1).toDate());
|
||||
}
|
||||
break;
|
||||
} default: {
|
||||
// Invalid format, returns no documents
|
||||
documentCriteria.setCreateDateMin(new Date(0));
|
||||
documentCriteria.setCreateDateMax(new Date(0));
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Invalid date, returns no documents
|
||||
documentCriteria.setCreateDateMin(new Date(0));
|
||||
documentCriteria.setCreateDateMax(new Date(0));
|
||||
}
|
||||
break;
|
||||
case "shared":
|
||||
// New shared state criteria
|
||||
documentCriteria.setShared(paramValue.equals("yes"));
|
||||
break;
|
||||
case "lang":
|
||||
// New language criteria
|
||||
if (Constants.SUPPORTED_LANGUAGES.contains(paramValue)) {
|
||||
documentCriteria.setLanguage(paramValue);
|
||||
} else {
|
||||
// Unsupported language, returns no documents
|
||||
documentCriteria.setLanguage(UUID.randomUUID().toString());
|
||||
}
|
||||
break;
|
||||
case "mime":
|
||||
// New mime type criteria
|
||||
documentCriteria.setMimeType(paramValue);
|
||||
break;
|
||||
case "by":
|
||||
// New creator criteria
|
||||
User user = userDao.getActiveByUsername(paramValue);
|
||||
if (user == null) {
|
||||
// This user doesn't exist, return nothing
|
||||
documentCriteria.setCreatorId(UUID.randomUUID().toString());
|
||||
} else {
|
||||
// This user exists, search its documents
|
||||
documentCriteria.setCreatorId(user.getId());
|
||||
}
|
||||
break;
|
||||
case "workflow":
|
||||
// New shared state criteria
|
||||
documentCriteria.setActiveRoute(paramValue.equals("me"));
|
||||
break;
|
||||
case "simple":
|
||||
// New simple search criteria
|
||||
query.add(paramValue);
|
||||
break;
|
||||
case "full":
|
||||
// New fulltext search criteria
|
||||
fullQuery.add(paramValue);
|
||||
break;
|
||||
case "title":
|
||||
// New title criteria
|
||||
documentCriteria.getTitleList().add(paramValue);
|
||||
break;
|
||||
default:
|
||||
fullQuery.add(criteria);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
documentCriteria.setSearch(Joiner.on(" ").join(query));
|
||||
documentCriteria.setFullSearch(Joiner.on(" ").join(fullQuery));
|
||||
return documentCriteria;
|
||||
@FormParam("files") Boolean files,
|
||||
@FormParam("search[after]") String searchCreatedAfter,
|
||||
@FormParam("search[before]") String searchCreatedBefore,
|
||||
@FormParam("search[by]") String searchBy,
|
||||
@FormParam("search[full]") String searchFull,
|
||||
@FormParam("search[lang]") String searchLang,
|
||||
@FormParam("search[mime]") String searchMime,
|
||||
@FormParam("search[shared]") Boolean searchShared,
|
||||
@FormParam("search[simple]") String searchSimple,
|
||||
@FormParam("search[tag]") String searchTag,
|
||||
@FormParam("search[nottag]") String searchTagNot,
|
||||
@FormParam("search[title]") String searchTitle,
|
||||
@FormParam("search[uafter]") String searchUpdatedAfter,
|
||||
@FormParam("search[ubefore]") String searchUpdatedBefore,
|
||||
@FormParam("search[searchworkflow]") String searchWorkflow
|
||||
) {
|
||||
return list(
|
||||
limit,
|
||||
offset,
|
||||
sortColumn,
|
||||
asc,
|
||||
search,
|
||||
files,
|
||||
searchCreatedAfter,
|
||||
searchCreatedBefore,
|
||||
searchBy,
|
||||
searchFull,
|
||||
searchLang,
|
||||
searchMime,
|
||||
searchShared,
|
||||
searchSimple,
|
||||
searchTag,
|
||||
searchTagNot,
|
||||
searchTitle,
|
||||
searchUpdatedAfter,
|
||||
searchUpdatedBefore,
|
||||
searchWorkflow
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -818,7 +677,7 @@ public class DocumentResource extends BaseResource {
|
||||
if (!authenticate()) {
|
||||
throw new ForbiddenClientException();
|
||||
}
|
||||
|
||||
|
||||
// Validate input data
|
||||
title = ValidationUtil.validateLength(title, "title", 1, 100, false);
|
||||
language = ValidationUtil.validateLength(language, "language", 3, 7, false);
|
||||
@ -882,7 +741,7 @@ public class DocumentResource extends BaseResource {
|
||||
.add("id", document.getId());
|
||||
return Response.ok().entity(response.build()).build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the document.
|
||||
*
|
||||
@ -904,7 +763,7 @@ public class DocumentResource extends BaseResource {
|
||||
* @apiParam {String[]} [relations] List of related documents ID
|
||||
* @apiParam {String[]} [metadata_id] List of metadata ID
|
||||
* @apiParam {String[]} [metadata_value] List of metadata values
|
||||
* @apiParam {String} language Language
|
||||
* @apiParam {String} [language] Language
|
||||
* @apiParam {Number} [create_date] Create date (timestamp)
|
||||
* @apiSuccess {String} id Document ID
|
||||
* @apiError (client) ForbiddenError Access denied or document not writable
|
||||
@ -940,7 +799,7 @@ public class DocumentResource extends BaseResource {
|
||||
if (!authenticate()) {
|
||||
throw new ForbiddenClientException();
|
||||
}
|
||||
|
||||
|
||||
// Validate input data
|
||||
title = ValidationUtil.validateLength(title, "title", 1, 100, false);
|
||||
language = ValidationUtil.validateLength(language, "language", 3, 7, false);
|
||||
@ -957,20 +816,20 @@ public class DocumentResource extends BaseResource {
|
||||
if (language != null && !Constants.SUPPORTED_LANGUAGES.contains(language)) {
|
||||
throw new ClientException("ValidationError", MessageFormat.format("{0} is not a supported language", language));
|
||||
}
|
||||
|
||||
|
||||
// Check write permission
|
||||
AclDao aclDao = new AclDao();
|
||||
if (!aclDao.checkPermission(id, PermType.WRITE, getTargetIdList(null))) {
|
||||
throw new ForbiddenClientException();
|
||||
}
|
||||
|
||||
|
||||
// Get the document
|
||||
DocumentDao documentDao = new DocumentDao();
|
||||
Document document = documentDao.getById(id);
|
||||
if (document == null) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
|
||||
// Update the document
|
||||
document.setTitle(title);
|
||||
document.setDescription(description);
|
||||
@ -988,12 +847,12 @@ public class DocumentResource extends BaseResource {
|
||||
} else {
|
||||
document.setCreateDate(createDate);
|
||||
}
|
||||
|
||||
|
||||
documentDao.update(document, principal.getId());
|
||||
|
||||
|
||||
// Update tags
|
||||
updateTagList(id, tagList);
|
||||
|
||||
|
||||
// Update relations
|
||||
updateRelationList(id, relationList);
|
||||
|
||||
@ -1009,7 +868,7 @@ public class DocumentResource extends BaseResource {
|
||||
documentUpdatedAsyncEvent.setUserId(principal.getId());
|
||||
documentUpdatedAsyncEvent.setDocumentId(id);
|
||||
ThreadLocalContext.get().addAsyncEvent(documentUpdatedAsyncEvent);
|
||||
|
||||
|
||||
JsonObjectBuilder response = Json.createObjectBuilder()
|
||||
.add("id", id);
|
||||
return Response.ok().entity(response.build()).build();
|
||||
@ -1144,7 +1003,7 @@ public class DocumentResource extends BaseResource {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
List<File> fileList = fileDao.getByDocumentId(principal.getId(), id);
|
||||
|
||||
|
||||
// Delete the document
|
||||
documentDao.delete(id, principal.getId());
|
||||
|
||||
@ -1162,7 +1021,7 @@ public class DocumentResource extends BaseResource {
|
||||
documentDeletedAsyncEvent.setUserId(principal.getId());
|
||||
documentDeletedAsyncEvent.setDocumentId(id);
|
||||
ThreadLocalContext.get().addAsyncEvent(documentDeletedAsyncEvent);
|
||||
|
||||
|
||||
// Always return OK
|
||||
JsonObjectBuilder response = Json.createObjectBuilder()
|
||||
.add("status", "ok");
|
||||
@ -1215,4 +1074,27 @@ public class DocumentResource extends BaseResource {
|
||||
relationDao.updateRelationList(documentId, documentIdSet);
|
||||
}
|
||||
}
|
||||
|
||||
private JsonObjectBuilder createDocumentObjectBuilder(DocumentDto documentDto) {
|
||||
return Json.createObjectBuilder()
|
||||
.add("create_date", documentDto.getCreateTimestamp())
|
||||
.add("description", JsonUtil.nullable(documentDto.getDescription()))
|
||||
.add("file_id", JsonUtil.nullable(documentDto.getFileId()))
|
||||
.add("id", documentDto.getId())
|
||||
.add("language", documentDto.getLanguage())
|
||||
.add("shared", documentDto.getShared())
|
||||
.add("title", documentDto.getTitle())
|
||||
.add("update_date", documentDto.getUpdateTimestamp());
|
||||
}
|
||||
|
||||
private static JsonArrayBuilder createTagsArrayBuilder(List<TagDto> tagDtoList) {
|
||||
JsonArrayBuilder tags = Json.createArrayBuilder();
|
||||
for (TagDto tagDto : tagDtoList) {
|
||||
tags.add(Json.createObjectBuilder()
|
||||
.add("id", tagDto.getId())
|
||||
.add("name", tagDto.getName())
|
||||
.add("color", tagDto.getColor()));
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
}
|
||||
|
@ -67,8 +67,8 @@ public class FileResource extends BaseResource {
|
||||
* This resource accepts only multipart/form-data.
|
||||
* @apiName PutFile
|
||||
* @apiGroup File
|
||||
* @apiParam {String} id Document ID
|
||||
* @apiParam {String} previousFileId ID of the file to replace by this new version
|
||||
* @apiParam {String} [id] Document ID
|
||||
* @apiParam {String} [previousFileId] ID of the file to replace by this new version
|
||||
* @apiParam {String} file File data
|
||||
* @apiSuccess {String} status Status OK
|
||||
* @apiSuccess {String} id File ID
|
||||
@ -390,8 +390,8 @@ public class FileResource extends BaseResource {
|
||||
* @api {get} /file/list Get files
|
||||
* @apiName GetFileList
|
||||
* @apiGroup File
|
||||
* @apiParam {String} id Document ID
|
||||
* @apiParam {String} share Share ID
|
||||
* @apiParam {String} [id] Document ID
|
||||
* @apiParam {String} [share] Share ID
|
||||
* @apiSuccess {Object[]} files List of files
|
||||
* @apiSuccess {String} files.id ID
|
||||
* @apiSuccess {String} files.processing True if the file is currently processing
|
||||
@ -497,7 +497,6 @@ public class FileResource extends BaseResource {
|
||||
* @apiName DeleteFile
|
||||
* @apiGroup File
|
||||
* @apiParam {String} id File ID
|
||||
* @apiParam {String} share Share ID
|
||||
* @apiSuccess {String} status Status OK
|
||||
* @apiError (client) ForbiddenError Access denied
|
||||
* @apiError (client) NotFound File or document not found
|
||||
|
@ -0,0 +1,318 @@
|
||||
package com.sismics.docs.rest.util;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.sismics.docs.core.constant.Constants;
|
||||
import com.sismics.docs.core.dao.UserDao;
|
||||
import com.sismics.docs.core.dao.criteria.DocumentCriteria;
|
||||
import com.sismics.docs.core.dao.dto.TagDto;
|
||||
import com.sismics.docs.core.model.jpa.User;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.joda.time.format.DateTimeFormatterBuilder;
|
||||
import org.joda.time.format.DateTimeParser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DocumentSearchCriteriaUtil {
|
||||
private static final DateTimeParser YEAR_PARSER = DateTimeFormat.forPattern("yyyy").getParser();
|
||||
private static final DateTimeParser MONTH_PARSER = DateTimeFormat.forPattern("yyyy-MM").getParser();
|
||||
private static final DateTimeParser DAY_PARSER = DateTimeFormat.forPattern("yyyy-MM-dd").getParser();
|
||||
private static final DateTimeParser[] DATE_PARSERS = new DateTimeParser[]{
|
||||
YEAR_PARSER,
|
||||
MONTH_PARSER,
|
||||
DAY_PARSER};
|
||||
|
||||
private static final DateTimeFormatter YEAR_FORMATTER = new DateTimeFormatter(null, YEAR_PARSER);
|
||||
private static final DateTimeFormatter MONTH_FORMATTER = new DateTimeFormatter(null, MONTH_PARSER);
|
||||
private static final DateTimeFormatter DAY_FORMATTER = new DateTimeFormatter(null, DAY_PARSER);
|
||||
private static final DateTimeFormatter DATES_FORMATTER = new DateTimeFormatterBuilder().append(null, DATE_PARSERS).toFormatter();
|
||||
|
||||
private static final String PARAMETER_WITH_MULTIPLE_VALUES_SEPARATOR = ",";
|
||||
private static final String WORKFLOW_ME = "me";
|
||||
|
||||
/**
|
||||
* Parse a query according to the specified syntax, eg.:
|
||||
* tag:assurance tag:other before:2012 after:2011-09 shared:yes lang:fra thing
|
||||
*
|
||||
* @param search Search query
|
||||
* @param allTagDtoList List of tags
|
||||
* @return DocumentCriteria
|
||||
*/
|
||||
public static DocumentCriteria parseSearchQuery(String search, List<TagDto> allTagDtoList) {
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
if (Strings.isNullOrEmpty(search)) {
|
||||
return documentCriteria;
|
||||
}
|
||||
|
||||
String[] criteriaList = search.split(" +");
|
||||
List<String> simpleQuery = new ArrayList<>();
|
||||
List<String> fullQuery = new ArrayList<>();
|
||||
for (String criteria : criteriaList) {
|
||||
String[] params = criteria.split(":");
|
||||
if (params.length != 2 || Strings.isNullOrEmpty(params[0]) || Strings.isNullOrEmpty(params[1])) {
|
||||
// This is not a special criteria, do a fulltext search on it
|
||||
fullQuery.add(criteria);
|
||||
continue;
|
||||
}
|
||||
String paramName = params[0];
|
||||
String paramValue = params[1];
|
||||
|
||||
switch (paramName) {
|
||||
case "tag":
|
||||
case "!tag":
|
||||
parseTagCriteria(documentCriteria, paramValue, allTagDtoList, paramName.startsWith("!"));
|
||||
break;
|
||||
case "after":
|
||||
case "before":
|
||||
case "uafter":
|
||||
case "ubefore":
|
||||
parseDateCriteria(documentCriteria, paramValue, DATES_FORMATTER, paramName.startsWith("u"), paramName.endsWith("before"));
|
||||
break;
|
||||
case "uat":
|
||||
case "at":
|
||||
parseDateAtCriteria(documentCriteria, paramValue, params[0].startsWith("u"));
|
||||
break;
|
||||
case "shared":
|
||||
documentCriteria.setShared(paramValue.equals("yes"));
|
||||
break;
|
||||
case "lang":
|
||||
parseLangCriteria(documentCriteria, paramValue);
|
||||
break;
|
||||
case "mime":
|
||||
documentCriteria.setMimeType(paramValue);
|
||||
break;
|
||||
case "by":
|
||||
parseByCriteria(documentCriteria, paramValue);
|
||||
break;
|
||||
case "workflow":
|
||||
documentCriteria.setActiveRoute(paramValue.equals(WORKFLOW_ME));
|
||||
break;
|
||||
case "simple":
|
||||
simpleQuery.add(paramValue);
|
||||
break;
|
||||
case "full":
|
||||
fullQuery.add(paramValue);
|
||||
break;
|
||||
case "title":
|
||||
documentCriteria.getTitleList().add(paramValue);
|
||||
break;
|
||||
default:
|
||||
fullQuery.add(criteria);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
documentCriteria.setSimpleSearch(Joiner.on(" ").join(simpleQuery));
|
||||
documentCriteria.setFullSearch(Joiner.on(" ").join(fullQuery));
|
||||
return documentCriteria;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fill the document criteria with various possible parameters
|
||||
*
|
||||
* @param documentCriteria structure to be filled
|
||||
* @param searchBy author
|
||||
* @param searchCreatedAfter creation moment after
|
||||
* @param searchCreatedBefore creation moment before
|
||||
* @param searchFull full search
|
||||
* @param searchLang lang
|
||||
* @param searchMime mime type
|
||||
* @param searchShared share state
|
||||
* @param searchSimple search in
|
||||
* @param searchTag tags or parent tags
|
||||
* @param searchNotTag tags or parent tags to ignore
|
||||
* @param searchTitle title
|
||||
* @param searchUpdatedAfter update moment after
|
||||
* @param searchUpdatedBefore update moment before
|
||||
* @param searchWorkflow exiting workflow
|
||||
* @param allTagDtoList list of existing tags
|
||||
*/
|
||||
public static void addHttpSearchParams(
|
||||
DocumentCriteria documentCriteria,
|
||||
String searchBy,
|
||||
String searchCreatedAfter,
|
||||
String searchCreatedBefore,
|
||||
String searchFull,
|
||||
String searchLang,
|
||||
String searchMime,
|
||||
Boolean searchShared,
|
||||
String searchSimple,
|
||||
String searchTag,
|
||||
String searchNotTag,
|
||||
String searchTitle,
|
||||
String searchUpdatedAfter,
|
||||
String searchUpdatedBefore,
|
||||
String searchWorkflow,
|
||||
List<TagDto> allTagDtoList
|
||||
) {
|
||||
if (searchBy != null) {
|
||||
parseByCriteria(documentCriteria, searchBy);
|
||||
}
|
||||
if (searchCreatedAfter != null) {
|
||||
parseDateCriteria(documentCriteria, searchCreatedAfter, DAY_FORMATTER, false, false);
|
||||
}
|
||||
if (searchCreatedBefore != null) {
|
||||
parseDateCriteria(documentCriteria, searchCreatedBefore, DAY_FORMATTER, false, true);
|
||||
}
|
||||
if (searchFull != null) {
|
||||
documentCriteria.setFullSearch(Joiner.on(" ").join(searchFull.split(PARAMETER_WITH_MULTIPLE_VALUES_SEPARATOR)));
|
||||
}
|
||||
if (searchLang != null) {
|
||||
parseLangCriteria(documentCriteria, searchLang);
|
||||
}
|
||||
if (searchMime != null) {
|
||||
documentCriteria.setMimeType(searchMime);
|
||||
}
|
||||
if ((searchShared != null) && searchShared) {
|
||||
documentCriteria.setShared(true);
|
||||
}
|
||||
if (searchSimple != null) {
|
||||
documentCriteria.setSimpleSearch(Joiner.on(" ").join(searchSimple.split(PARAMETER_WITH_MULTIPLE_VALUES_SEPARATOR)));
|
||||
}
|
||||
if (searchTitle != null) {
|
||||
documentCriteria.getTitleList().addAll(Arrays.asList(searchTitle.split(PARAMETER_WITH_MULTIPLE_VALUES_SEPARATOR)));
|
||||
}
|
||||
if (searchTag != null) {
|
||||
for (String tag : searchTag.split(PARAMETER_WITH_MULTIPLE_VALUES_SEPARATOR)) {
|
||||
parseTagCriteria(documentCriteria, tag, allTagDtoList, false);
|
||||
}
|
||||
}
|
||||
if (searchNotTag != null) {
|
||||
for (String tag : searchNotTag.split(PARAMETER_WITH_MULTIPLE_VALUES_SEPARATOR)) {
|
||||
parseTagCriteria(documentCriteria, tag, allTagDtoList, true);
|
||||
}
|
||||
}
|
||||
if (searchUpdatedAfter != null) {
|
||||
parseDateCriteria(documentCriteria, searchUpdatedAfter, DAY_FORMATTER, true, false);
|
||||
}
|
||||
if (searchUpdatedBefore != null) {
|
||||
parseDateCriteria(documentCriteria, searchUpdatedBefore, DAY_FORMATTER, true, true);
|
||||
}
|
||||
if ((WORKFLOW_ME.equals(searchWorkflow))) {
|
||||
documentCriteria.setActiveRoute(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void parseDateCriteria(DocumentCriteria documentCriteria, String value, DateTimeFormatter formatter, boolean isUpdated, boolean isBefore) {
|
||||
try {
|
||||
DateTime date = formatter.parseDateTime(value);
|
||||
if (isBefore) {
|
||||
if (isUpdated) {
|
||||
documentCriteria.setUpdateDateMax(date.toDate());
|
||||
} else {
|
||||
documentCriteria.setCreateDateMax(date.toDate());
|
||||
}
|
||||
} else {
|
||||
if (isUpdated) {
|
||||
documentCriteria.setUpdateDateMin(date.toDate());
|
||||
} else {
|
||||
documentCriteria.setCreateDateMin(date.toDate());
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Invalid date, returns no documents
|
||||
documentCriteria.setCreateDateMin(new Date(0));
|
||||
documentCriteria.setCreateDateMax(new Date(0));
|
||||
}
|
||||
}
|
||||
|
||||
private static void parseDateAtCriteria(DocumentCriteria documentCriteria, String value, boolean isUpdated) {
|
||||
try {
|
||||
switch (value.length()) {
|
||||
case 10: {
|
||||
DateTime date = DATES_FORMATTER.parseDateTime(value);
|
||||
if (isUpdated) {
|
||||
documentCriteria.setUpdateDateMin(date.toDate());
|
||||
documentCriteria.setUpdateDateMax(date.plusDays(1).minusSeconds(1).toDate());
|
||||
} else {
|
||||
documentCriteria.setCreateDateMin(date.toDate());
|
||||
documentCriteria.setCreateDateMax(date.plusDays(1).minusSeconds(1).toDate());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
DateTime date = MONTH_FORMATTER.parseDateTime(value);
|
||||
if (isUpdated) {
|
||||
documentCriteria.setUpdateDateMin(date.toDate());
|
||||
documentCriteria.setUpdateDateMax(date.plusMonths(1).minusSeconds(1).toDate());
|
||||
} else {
|
||||
documentCriteria.setCreateDateMin(date.toDate());
|
||||
documentCriteria.setCreateDateMax(date.plusMonths(1).minusSeconds(1).toDate());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
DateTime date = YEAR_FORMATTER.parseDateTime(value);
|
||||
if (isUpdated) {
|
||||
documentCriteria.setUpdateDateMin(date.toDate());
|
||||
documentCriteria.setUpdateDateMax(date.plusYears(1).minusSeconds(1).toDate());
|
||||
} else {
|
||||
documentCriteria.setCreateDateMin(date.toDate());
|
||||
documentCriteria.setCreateDateMax(date.plusYears(1).minusSeconds(1).toDate());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// Invalid format, returns no documents
|
||||
documentCriteria.setCreateDateMin(new Date(0));
|
||||
documentCriteria.setCreateDateMax(new Date(0));
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Invalid date, returns no documents
|
||||
documentCriteria.setCreateDateMin(new Date(0));
|
||||
documentCriteria.setCreateDateMax(new Date(0));
|
||||
}
|
||||
}
|
||||
|
||||
private static void parseTagCriteria(DocumentCriteria documentCriteria, String value, List<TagDto> allTagDtoList, boolean exclusion) {
|
||||
List<TagDto> tagDtoList = TagUtil.findByName(value, allTagDtoList);
|
||||
if (tagDtoList.isEmpty()) {
|
||||
// No tag found, the request must return nothing
|
||||
documentCriteria.getTagIdList().add(Lists.newArrayList(UUID.randomUUID().toString()));
|
||||
} else {
|
||||
List<String> tagIdList = Lists.newArrayList();
|
||||
for (TagDto tagDto : tagDtoList) {
|
||||
tagIdList.add(tagDto.getId());
|
||||
List<TagDto> childrenTagDtoList = TagUtil.findChildren(tagDto, allTagDtoList);
|
||||
for (TagDto childrenTagDto : childrenTagDtoList) {
|
||||
tagIdList.add(childrenTagDto.getId());
|
||||
}
|
||||
}
|
||||
if (exclusion) {
|
||||
documentCriteria.getExcludedTagIdList().add(tagIdList);
|
||||
} else {
|
||||
documentCriteria.getTagIdList().add(tagIdList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void parseLangCriteria(DocumentCriteria documentCriteria, String value) {
|
||||
// New language criteria
|
||||
if (Constants.SUPPORTED_LANGUAGES.contains(value)) {
|
||||
documentCriteria.setLanguage(value);
|
||||
} else {
|
||||
// Unsupported language, returns no documents
|
||||
documentCriteria.setLanguage(UUID.randomUUID().toString());
|
||||
}
|
||||
}
|
||||
|
||||
private static void parseByCriteria(DocumentCriteria documentCriteria, String value) {
|
||||
User user = new UserDao().getActiveByUsername(value);
|
||||
if (user == null) {
|
||||
// This user doesn't exist, return nothing
|
||||
documentCriteria.setCreatorId(UUID.randomUUID().toString());
|
||||
} else {
|
||||
// This user exists, search its documents
|
||||
documentCriteria.setCreatorId(user.getId());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
package com.sismics.docs.core.util;
|
||||
package com.sismics.docs.rest.util;
|
||||
|
||||
import com.sismics.docs.core.dao.dto.TagDto;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -39,10 +40,10 @@ public class TagUtil {
|
||||
* @return List of filtered tags
|
||||
*/
|
||||
public static List<TagDto> findByName(String name, List<TagDto> allTagDtoList) {
|
||||
List<TagDto> tagDtoList = new ArrayList<>();
|
||||
if (name.isEmpty()) {
|
||||
return tagDtoList;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<TagDto> tagDtoList = new ArrayList<>();
|
||||
name = name.toLowerCase();
|
||||
for (TagDto tagDto : allTagDtoList) {
|
||||
if (tagDto.getName().toLowerCase().startsWith(name)) {
|
@ -50,11 +50,11 @@ curl -i -X POST -H "Cookie: auth_token=64085630-2ae6-415c-9a92-4b22c107eaa4" htt
|
||||
|
||||
## Document search syntax
|
||||
|
||||
The `/api/document/list` endpoint use a String `search` parameter.
|
||||
The `/api/document/list` endpoint use a String `search` parameter, useful when the query is entered by a human.
|
||||
|
||||
This parameter is split in segments using the space character (the other whitespace characters are not considered).
|
||||
|
||||
If a segment contains exactly one colon (`:`), it will used as a field criteria (see bellow).
|
||||
If a segment contains exactly one colon (`:`), it will be used as a field criteria (see bellow).
|
||||
In other cases (zero or more than one colon), the segment will be used as a search criteria for all fields including the document's files content.
|
||||
|
||||
### Search fields
|
||||
@ -69,7 +69,7 @@ If a search `VALUE` is considered invalid, the search result will be empty.
|
||||
* `at:VALUE`: the document must have been created at the `VALUE` moment, accepted format are `yyyy`, `yyyy-MM` and `yyyy-MM-dd` (for `yyyy` it must be the same year, for `yyyy-MM` the same month, for `yyyy-MM-dd` the same day)
|
||||
* `before:VALUE`: the document must have been created before or at the `VALUE` moment, accepted format are `yyyy`, `yyyy-MM` and `yyyy-MM-dd`
|
||||
* `uafter:VALUE`: the document must have been last updated after or at the `VALUE` moment, accepted format are `yyyy`, `yyyy-MM` and `yyyy-MM-dd`
|
||||
* `at:VALUE`: the document must have been updated at the `VALUE` moment, accepted format are `yyyy`, `yyyy-MM` and `yyyy-MM-dd` (for `yyyy` it must be the same year, for `yyyy-MM` the same month, for `yyyy-MM-dd` the same day)
|
||||
* `uat:VALUE`: the document must have been updated at the `VALUE` moment, accepted format are `yyyy`, `yyyy-MM` and `yyyy-MM-dd` (for `yyyy` it must be the same year, for `yyyy-MM` the same month, for `yyyy-MM-dd` the same day)
|
||||
* `ubefore:VALUE`: the document must have been updated before or at the `VALUE` moment, accepted format are `yyyy`, `yyyy-MM` and `yyyy-MM-dd`
|
||||
* Language
|
||||
* `lang:VALUE`: the document must be of the specified language (example: `en`)
|
||||
|
@ -0,0 +1,41 @@
|
||||
package com.sismics.docs.rest;
|
||||
|
||||
import com.sismics.docs.core.dao.UserDao;
|
||||
import com.sismics.docs.core.model.jpa.User;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
import com.sismics.util.jpa.EMF;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.EntityTransaction;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
public abstract class BaseTransactionalTest {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
// Initialize the entity manager
|
||||
EntityManager em = EMF.get().createEntityManager();
|
||||
ThreadLocalContext context = ThreadLocalContext.get();
|
||||
context.setEntityManager(em);
|
||||
em.getTransaction().begin();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ThreadLocalContext.get().getEntityManager().getTransaction().rollback();
|
||||
}
|
||||
|
||||
protected User createUser(String userName) throws Exception {
|
||||
UserDao userDao = new UserDao();
|
||||
User user = new User();
|
||||
user.setUsername(userName);
|
||||
user.setPassword("12345678");
|
||||
user.setEmail("toto@docs.com");
|
||||
user.setRoleId("admin");
|
||||
user.setStorageQuota(100_000L);
|
||||
userDao.create(user, userName);
|
||||
return user;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -28,7 +28,7 @@ public class TestAppResource extends BaseJerseyTest {
|
||||
@Test
|
||||
public void testAppResource() {
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Check the application info
|
||||
JsonObject json = target().path("/app").request()
|
||||
@ -86,7 +86,7 @@ public class TestAppResource extends BaseJerseyTest {
|
||||
@Test
|
||||
public void testLogResource() {
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Check the logs (page 1)
|
||||
JsonObject json = target().path("/app/log")
|
||||
@ -120,7 +120,7 @@ public class TestAppResource extends BaseJerseyTest {
|
||||
@Test
|
||||
public void testGuestLogin() {
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Try to login as guest
|
||||
Response response = target().path("/user/login").request()
|
||||
@ -185,7 +185,7 @@ public class TestAppResource extends BaseJerseyTest {
|
||||
@Test
|
||||
public void testSmtpConfiguration() {
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Get SMTP configuration
|
||||
JsonObject json = target().path("/app/config_smtp").request()
|
||||
@ -224,7 +224,7 @@ public class TestAppResource extends BaseJerseyTest {
|
||||
@Test
|
||||
public void testInbox() {
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Create a tag
|
||||
JsonObject json = target().path("/tag").request()
|
||||
@ -365,7 +365,7 @@ public class TestAppResource extends BaseJerseyTest {
|
||||
// new LdifFileLoader(directoryService.getAdminSession(), new File(Resources.getResource("test.ldif").getFile()), null).execute();
|
||||
//
|
||||
// // Login admin
|
||||
// String adminToken = clientUtil.login("admin", "admin", false);
|
||||
// String adminToken = adminToken();
|
||||
//
|
||||
// // Get the LDAP configuration
|
||||
// JsonObject json = target().path("/app/config_ldap").request()
|
||||
@ -425,4 +425,4 @@ public class TestAppResource extends BaseJerseyTest {
|
||||
// ldapServer.stop();
|
||||
// directoryService.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -273,6 +273,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
Assert.assertFalse(relations.getJsonObject(0).getBoolean("source"));
|
||||
Assert.assertEquals("My super title document 2", relations.getJsonObject(0).getString("title"));
|
||||
Assert.assertFalse(json.containsKey("files"));
|
||||
Assert.assertEquals(file1Id, json.getString("file_id"));
|
||||
|
||||
// Get document 2
|
||||
json = target().path("/document/" + document2Id).request()
|
||||
@ -285,6 +286,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
Assert.assertTrue(relations.getJsonObject(0).getBoolean("source"));
|
||||
Assert.assertEquals("My super title document 1", relations.getJsonObject(0).getString("title"));
|
||||
Assert.assertFalse(json.containsKey("files"));
|
||||
Assert.assertEquals(file1Id, json.getString("file_id"));
|
||||
|
||||
// Create a tag
|
||||
json = target().path("/tag").request()
|
||||
@ -818,7 +820,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
@Test
|
||||
public void testCustomMetadata() {
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Login metadata1
|
||||
clientUtil.createUser("metadata1");
|
||||
|
@ -25,7 +25,7 @@ public class TestGroupResource extends BaseJerseyTest {
|
||||
@Test
|
||||
public void testGroupResource() {
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Create group hierarchy
|
||||
clientUtil.createGroup("g1");
|
||||
@ -189,4 +189,4 @@ public class TestGroupResource extends BaseJerseyTest {
|
||||
Assert.assertTrue(groupList.contains("g11"));
|
||||
Assert.assertTrue(groupList.contains("g112"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public class TestMetadataResource extends BaseJerseyTest {
|
||||
@Test
|
||||
public void testMetadataResource() {
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Get all metadata with admin
|
||||
JsonObject json = target().path("/metadata")
|
||||
@ -79,4 +79,4 @@ public class TestMetadataResource extends BaseJerseyTest {
|
||||
metadata = json.getJsonArray("metadata");
|
||||
Assert.assertEquals(0, metadata.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public class TestRouteModelResource extends BaseJerseyTest {
|
||||
@Test
|
||||
public void testRouteModelResource() {
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Login routeModel1
|
||||
clientUtil.createUser("routeModel1");
|
||||
@ -138,4 +138,4 @@ public class TestRouteModelResource extends BaseJerseyTest {
|
||||
routeModels = json.getJsonArray("routemodels");
|
||||
Assert.assertEquals(1, routeModels.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class TestRouteResource extends BaseJerseyTest {
|
||||
String route1Token = clientUtil.login("route1");
|
||||
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Change SMTP configuration to target Wiser
|
||||
target().path("/app/config_smtp").request()
|
||||
@ -364,7 +364,7 @@ public class TestRouteResource extends BaseJerseyTest {
|
||||
@Test
|
||||
public void testTagActions() {
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Create an Approved tag
|
||||
JsonObject json = target().path("/tag").request()
|
||||
@ -511,4 +511,4 @@ public class TestRouteResource extends BaseJerseyTest {
|
||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||
.delete(JsonObject.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class TestThemeResource extends BaseJerseyTest {
|
||||
@Test
|
||||
public void testThemeResource() throws Exception {
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Get the stylesheet anonymously
|
||||
String stylesheet = target().path("/theme/stylesheet").request()
|
||||
@ -104,4 +104,4 @@ public class TestThemeResource extends BaseJerseyTest {
|
||||
response = target().path("/theme/image/background").request().get();
|
||||
Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ public class TestUserResource extends BaseJerseyTest {
|
||||
clientUtil.createUser("alice");
|
||||
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// List all users
|
||||
json = target().path("/user/list")
|
||||
@ -250,7 +250,7 @@ public class TestUserResource extends BaseJerseyTest {
|
||||
clientUtil.createUser("admin_user1");
|
||||
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Check admin information
|
||||
JsonObject json = target().path("/user").request()
|
||||
@ -336,7 +336,7 @@ public class TestUserResource extends BaseJerseyTest {
|
||||
@Test
|
||||
public void testTotp() {
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Create totp1 user
|
||||
clientUtil.createUser("totp1");
|
||||
@ -425,7 +425,7 @@ public class TestUserResource extends BaseJerseyTest {
|
||||
@Test
|
||||
public void testResetPassword() throws Exception {
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Change SMTP configuration to target Wiser
|
||||
target().path("/app/config_smtp").request()
|
||||
@ -493,4 +493,4 @@ public class TestUserResource extends BaseJerseyTest {
|
||||
json = response.readEntity(JsonObject.class);
|
||||
Assert.assertEquals("KeyNotFound", json.getString("type"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public class TestVocabularyResource extends BaseJerseyTest {
|
||||
String vocabulary1Token = clientUtil.login("vocabulary1");
|
||||
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Get coverage vocabularies entries
|
||||
JsonObject json = target().path("/vocabulary/coverage").request()
|
||||
@ -109,4 +109,4 @@ public class TestVocabularyResource extends BaseJerseyTest {
|
||||
.get(JsonObject.class);
|
||||
Assert.assertEquals(0, json.getJsonArray("entries").size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ public class TestWebhookResource extends BaseJerseyTest {
|
||||
@Test
|
||||
public void testWebhookResource() {
|
||||
// Login admin
|
||||
String adminToken = clientUtil.login("admin", "admin", false);
|
||||
String adminToken = adminToken();
|
||||
|
||||
// Login webhook1
|
||||
clientUtil.createUser("webhook1");
|
||||
@ -85,4 +85,4 @@ public class TestWebhookResource extends BaseJerseyTest {
|
||||
webhooks = json.getJsonArray("webhooks");
|
||||
Assert.assertEquals(0, webhooks.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,492 @@
|
||||
package com.sismics.docs.rest.util;
|
||||
|
||||
import com.sismics.docs.core.dao.TagDao;
|
||||
import com.sismics.docs.core.dao.criteria.DocumentCriteria;
|
||||
import com.sismics.docs.core.dao.criteria.TagCriteria;
|
||||
import com.sismics.docs.core.dao.dto.TagDto;
|
||||
import com.sismics.docs.core.model.jpa.Tag;
|
||||
import com.sismics.docs.core.model.jpa.User;
|
||||
import com.sismics.docs.rest.BaseTransactionalTest;
|
||||
import com.sismics.util.mime.MimeType;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class TestDocumentSearchCriteriaUtil extends BaseTransactionalTest {
|
||||
|
||||
@Test
|
||||
public void testHttpParamsBy() throws Exception {
|
||||
User user = createUser("user1");
|
||||
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
"user1",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
Assert.assertEquals(documentCriteria.getCreatorId(), user.getId());
|
||||
|
||||
documentCriteria = new DocumentCriteria();
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
"missing",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
Assert.assertNotNull(documentCriteria.getCreatorId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpParamsCreatedAfter() {
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
null,
|
||||
"2022-03-27",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
Assert.assertEquals(documentCriteria.getCreateDateMin(), new DateTime(2022, 3, 27, 0, 0, 0).toDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpParamsCreatedBefore() {
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
null,
|
||||
null,
|
||||
"2022-03-27",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
Assert.assertEquals(documentCriteria.getCreateDateMax(), new DateTime(2022, 3, 27, 0, 0, 0).toDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpParamsFull() {
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"full",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
Assert.assertEquals(documentCriteria.getFullSearch(), "full");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpParamsLang() {
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"fra",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
Assert.assertEquals(documentCriteria.getLanguage(), "fra");
|
||||
|
||||
documentCriteria = new DocumentCriteria();
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"unknown",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
Assert.assertNotNull(documentCriteria.getLanguage());
|
||||
Assert.assertNotEquals(documentCriteria.getLanguage(), "unknown");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpParamsMime() {
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
MimeType.IMAGE_GIF,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
Assert.assertEquals(documentCriteria.getMimeType(), MimeType.IMAGE_GIF);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpParamsShared() {
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
Assert.assertTrue(documentCriteria.getShared());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpParamsSimple() {
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"simple",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
Assert.assertEquals(documentCriteria.getSimpleSearch(), "simple");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpParamsTag() throws Exception {
|
||||
TagDao tagDao = new TagDao();
|
||||
|
||||
User user = createUser("user1");
|
||||
Tag tag1 = new Tag();
|
||||
tag1.setName("tag1");
|
||||
tag1.setColor("#bbb");
|
||||
tag1.setUserId(user.getId());
|
||||
tagDao.create(tag1, user.getId());
|
||||
|
||||
Tag tag2 = new Tag();
|
||||
tag2.setName("tag2");
|
||||
tag2.setColor("#bbb");
|
||||
tag2.setUserId(user.getId());
|
||||
tagDao.create(tag2, user.getId());
|
||||
|
||||
Tag tag3 = new Tag();
|
||||
tag3.setName("tag3");
|
||||
tag3.setColor("#bbb");
|
||||
tag3.setUserId(user.getId());
|
||||
tag3.setParentId(tag2.getId());
|
||||
tagDao.create(tag3, user.getId());
|
||||
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
List<TagDto> allTagDtoList = tagDao.findByCriteria(new TagCriteria(), null);
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"tag1",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
allTagDtoList
|
||||
);
|
||||
Assert.assertEquals(documentCriteria.getTagIdList(), List.of(Collections.singletonList(tag1.getId())));
|
||||
|
||||
documentCriteria = new DocumentCriteria();
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"tag2",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
allTagDtoList
|
||||
);
|
||||
Assert.assertEquals(documentCriteria.getTagIdList(), List.of(List.of(tag2.getId(), tag3.getId())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpParamsNotTag() throws Exception {
|
||||
TagDao tagDao = new TagDao();
|
||||
|
||||
User user = createUser("user1");
|
||||
Tag tag1 = new Tag();
|
||||
tag1.setName("tag1");
|
||||
tag1.setColor("#bbb");
|
||||
tag1.setUserId(user.getId());
|
||||
tagDao.create(tag1, user.getId());
|
||||
|
||||
Tag tag2 = new Tag();
|
||||
tag2.setName("tag2");
|
||||
tag2.setColor("#bbb");
|
||||
tag2.setUserId(user.getId());
|
||||
tagDao.create(tag2, user.getId());
|
||||
|
||||
Tag tag3 = new Tag();
|
||||
tag3.setName("tag3");
|
||||
tag3.setColor("#bbb");
|
||||
tag3.setUserId(user.getId());
|
||||
tag3.setParentId(tag2.getId());
|
||||
tagDao.create(tag3, user.getId());
|
||||
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
List<TagDto> allTagDtoList = tagDao.findByCriteria(new TagCriteria(), null);
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"tag1",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
allTagDtoList
|
||||
);
|
||||
Assert.assertEquals(documentCriteria.getExcludedTagIdList(), List.of(Collections.singletonList(tag1.getId())));
|
||||
|
||||
documentCriteria = new DocumentCriteria();
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"tag2",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
allTagDtoList
|
||||
);
|
||||
Assert.assertEquals(documentCriteria.getExcludedTagIdList(), List.of(List.of(tag2.getId(), tag3.getId())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpParamsTitle() {
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"title1,title2",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
Assert.assertEquals(documentCriteria.getTitleList(), Arrays.asList(new String[]{"title1", "title2"}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpParamsUpdatedAfter() {
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"2022-03-27",
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
Assert.assertEquals(documentCriteria.getUpdateDateMin(), new DateTime(2022, 3, 27, 0, 0, 0).toDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpParamsUpdatedBefore() {
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"2022-03-27",
|
||||
null,
|
||||
null
|
||||
);
|
||||
Assert.assertEquals(documentCriteria.getUpdateDateMax(), new DateTime(2022, 3, 27, 0, 0, 0).toDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpParamsWorkflow() {
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||
documentCriteria,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"me",
|
||||
null
|
||||
);
|
||||
Assert.assertTrue(documentCriteria.getActiveRoute());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user