/**
* Yobi, Project Hosting SW
*
* Copyright 2014 NAVER Corp.
* http://yobi.io
*
* @author Keesun Baik
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package models;
import com.avaje.ebean.Expr;
import com.avaje.ebean.ExpressionList;
import com.avaje.ebean.Junction;
import com.avaje.ebean.Page;
import models.enumeration.Operation;
import models.enumeration.ProjectScope;
import models.enumeration.UserState;
import utils.AccessControl;
import java.util.ArrayList;
import java.util.List;
public class Search {
private static final String DEFAULT_PATH_TO_PROJECT = "project";
private static final String DEFAULT_PATH_TO_AUTHOR = "authorId";
private static JunctionOperation<Issue> containsKeywordInIssue = new JunctionOperation<Issue>() {
@Override
public void withJunction(String keyword, Junction<Issue> junction) {
containsKeywordIn(keyword, junction, new String[]{"title", "body"});
}
};
private static JunctionOperation<Posting> containsKeywordInPosting = new JunctionOperation<Posting>() {
@Override
public void withJunction(String keyword, Junction<Posting> junction) {
containsKeywordIn(keyword, junction, new String[]{"title", "body"});
}
};
private static JunctionOperation<Milestone> containsKeywordInMilestone = new JunctionOperation<Milestone>() {
@Override
public void withJunction(String keyword, Junction<Milestone> junction) {
containsKeywordIn(keyword, junction, new String[]{"title", "contents"});
}
};
private static JunctionOperation<IssueComment> containsKeywordInIssueComment = new JunctionOperation<IssueComment>() {
@Override
public void withJunction(String keyword, Junction<IssueComment> junction) {
containsKeywordIn(keyword, junction, new String[]{"contents"});
}
};
private static JunctionOperation<PostingComment> containsKeywordInPostComment = new JunctionOperation<PostingComment>() {
@Override
public void withJunction(String keyword, Junction<PostingComment> junction) {
containsKeywordIn(keyword, junction, new String[]{"contents"});
}
};
private static JunctionOperation<ReviewComment> containsKeywordInReviewComment = new JunctionOperation<ReviewComment>() {
@Override
public void withJunction(String keyword, Junction<ReviewComment> junction) {
containsKeywordIn(keyword, junction, new String[]{"contents"});
}
};
/**
* Finds all issues that a {@code user} can see.
* - anonymous: find from only public project's issues.
* - logged in user: find from
* - public projects
* - private projects that the user is member or admin of the project
* - protected projects that the user is member or admin of a group which has the project
*
* TODO sorting(default, desc createdDate)
*
* @param keyword
* @param user
* @param pageParam
* @return
*/
public static Page<Issue> findIssues(String keyword, User user, PageParam pageParam) {
return issuesEL(keyword, user).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
/**
* Returns only the count of the {@link #findIssues(String, User, PageParam)}
*
* @param keyword
* @param user
* @return
*/
public static int countIssues(String keyword, User user) {
return issuesEL(keyword, user).findRowCount();
}
/**
* (Project && Keyword) || (Author && Keyword) || (Assignee && Keyword)
*
* @param keyword
* @param user
* @return
*/
private static ExpressionList<Issue> issuesEL(String keyword, User user) {
ExpressionList<Issue> el = Issue.finder.where();
Junction<Issue> junction = el.disjunction();
inProjectsTemplate(keyword, user, junction, DEFAULT_PATH_TO_PROJECT, containsKeywordInIssue);
equalsUserTemplate(keyword, user, junction, DEFAULT_PATH_TO_AUTHOR, containsKeywordInIssue);
equalsUserTemplate(keyword, user, junction, "assignee.user.id", containsKeywordInIssue);
junction.endJunction();
el.orderBy().desc("createdDate");
return el;
}
/**
* Finds all issues in a {@code project} that a {@code user} can see
* - If the project is public, then all user including anonymous can find by {@code keyword}
* - If the project is private, keyword searching is available when
* the {@code user} is member or admin of the {@code project}.
* - If the project id protected, keyword searching is available when
* the {@code user} is member or admin of the group of the {@code project}.
* - Or, the issues created by the user.
*
* @param keyword
* @param user
* @param project
* @param pageParam
* @return
*/
public static Page<Issue> findIssues(String keyword, User user, Project project, PageParam pageParam) {
return issuesEL(keyword, user, project).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
/**
* Returns only the count of the {@link #findIssues(String, User, Project, PageParam)}
*
* @param keyword
* @param user
* @param project
* @return
*/
public static int countIssues(String keyword, User user, Project project) {
ExpressionList<Issue> el = issuesEL(keyword, user, project);
return el.findRowCount();
}
private static ExpressionList<Issue> issuesEL(String keyword, User user, Project project) {
ExpressionList<Issue> el = Issue.finder.where().eq("project", project);
if(!AccessControl.isAllowed(user, project.asResource(), Operation.READ)) {
Junction<Issue> junction = el.disjunction();
junction.add(Expr.eq("authorId", user.id));
junction.add(Expr.eq("assignee.user.id", user.id));
junction.endJunction();
}
containsKeywordIn(keyword, el.conjunction(), new String[]{"title", "body"});
el.orderBy().desc("createdDate");
return el;
}
/**
* Finds all issues in a {@code organization} that a {@code user} can see
* - If the project is public, then all user including anonymous can find by {@code keyword}
* - If the project is private, keyword searching is available when
* the {@code user} is member or admin of the {@code project}.
* - If the project is protected, keyword searching is available to
* the project's members and the organization's members
*
* @param keyword
* @param user
* @param organization
* @param pageParam
* @return
*/
public static Page<Issue> findIssues(String keyword, User user, Organization organization, PageParam pageParam) {
return issuesEL(keyword, user, organization).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
/**
* Returns only the count of the {@link #findIssues(String, User, Organization, PageParam)}
*
* @param keyword
* @param user
* @param organization
* @return
*/
public static int countIssues(String keyword, User user, Organization organization) {
ExpressionList<Issue> el = issuesEL(keyword, user, organization);
return el.findRowCount();
}
private static ExpressionList<Issue> issuesEL(String keyword, User user, Organization organization) {
ExpressionList<Issue> el = Issue.finder.where()
.eq("project.organization", organization);
Junction<Issue> junction = el.disjunction();
inProjectsTemplate(keyword, user, organization, junction, DEFAULT_PATH_TO_PROJECT, containsKeywordInIssue);
equalsUserTemplate(keyword, user, junction, DEFAULT_PATH_TO_AUTHOR, containsKeywordInIssue);
equalsUserTemplate(keyword, user, junction, "assignee.user.id", containsKeywordInIssue);
junction.endJunction();
el.orderBy().desc("createdDate");
return el;
}
/**
* Finds all posts that a {@code user} can see.
* - anonymous: find from only public project's posts.
* - logged in user: find from
* - public projects
* - private projects that the user is member or admin of the project
* - protected projects that the user is member or admin of a group which has the project
*
* @param keyword
* @param user
* @param pageParam
* @return
*/
public static Page<Posting> findPosts(String keyword, User user, PageParam pageParam) {
return postsEL(keyword, user).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
/**
* Returns only the count of the {@link #findPosts(String, User, PageParam)}
*
* @param keyword
* @param user
* @return
*/
public static int countPosts(String keyword, User user) {
return postsEL(keyword, user).findRowCount();
}
private static ExpressionList<Posting> postsEL(String keyword, User user) {
ExpressionList<Posting> el = Posting.finder.where();
Junction<Posting> junction = el.disjunction();
inProjectsTemplate(keyword, user, junction, DEFAULT_PATH_TO_PROJECT, containsKeywordInPosting);
equalsUserTemplate(keyword, user, junction, DEFAULT_PATH_TO_AUTHOR, containsKeywordInPosting);
junction.endJunction();
el.orderBy().desc("createdDate");
return el;
}
/**
* Finds all posts in a {@code project} that a {@code user} can see
* - If the project is public, then all user including anonymous can find by {@code keyword}
* - If the project is private, keyword searching is available when
* the {@code user} is member or admin of the {@code project}.
* - If the project is protected, keyword searching is available to
* the project's members and the organization's members
*
* @param keyword
* @param user
* @param project
* @param pageParam
* @return
*/
public static Page<Posting> findPosts(String keyword, User user, Project project, PageParam pageParam) {
return postsEL(keyword, user, project).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
/**
* Returns only the count of the {@link #findPosts(String, User, Project, PageParam)}
*
* @param keyword
* @param user
* @param project
* @return
*/
public static int countPosts(String keyword, User user, Project project) {
return postsEL(keyword, user, project).findRowCount();
}
private static ExpressionList<Posting> postsEL(String keyword, User user, Project project) {
ExpressionList<Posting> el = Posting.finder.where()
.eq("project", project);
if(!AccessControl.isAllowed(user, project.asResource(), Operation.READ)) {
el.eq("authorId", user.id);
}
containsKeywordIn(keyword, el.conjunction(), new String[]{"title", "body"});
el.orderBy().desc("createdDate");
return el;
}
/**
* Finds all posts in a {@code organization} that a {@code user} can see
* - If the project is public, then all user including anonymous can find by {@code keyword}
* - If the project is private, keyword searching is available when
* the {@code user} is member or admin of the {@code project}.
* - If the project is protected, keyword searching is available to
* the project's members and the organization's members
*
* @param keyword
* @param user
* @param organization
* @param pageParam
* @return
*/
public static Page<Posting> findPosts(String keyword, User user, Organization organization, PageParam pageParam) {
return postsEL(keyword, user, organization).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
/**
* Returns only the count of the {@link #findPosts(String, User, Organization, PageParam)}
*
* @param keyword
* @param user
* @param organization
* @return
*/
public static int countPosts(String keyword, User user, Organization organization) {
ExpressionList<Posting> el = postsEL(keyword, user, organization);
return el.findRowCount();
}
private static ExpressionList<Posting> postsEL(String keyword, User user, Organization organization) {
ExpressionList<Posting> el = Posting.finder.where()
.eq("project.organization", organization);
Junction<Posting> junction = el.disjunction();
inProjectsTemplate(keyword, user, organization, junction, DEFAULT_PATH_TO_PROJECT, containsKeywordInPosting);
equalsUserTemplate(keyword, user, junction, DEFAULT_PATH_TO_AUTHOR, containsKeywordInPosting);
junction.endJunction();
el.orderBy().desc("createdDate");
return el;
}
/**
* Finds all users who contains the {@code keyword} in name or loginId.
*
* @param keyword
* @param pageParam
* @return
*/
public static Page<User> findUsers(String keyword, PageParam pageParam) {
return usersEL(keyword).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
/**
* Returns only the count of the {@link #findUsers(String, PageParam)}
*
* @param keyword
* @return
*/
public static int countUsers(String keyword) {
return usersEL(keyword).findRowCount();
}
private static ExpressionList<User> usersEL(String keyword) {
ExpressionList<User> el = User.find.where()
.eq("state", UserState.ACTIVE);
el.disjunction()
.add(Expr.icontains("name", keyword))
.add(Expr.icontains("loginId", keyword))
.endJunction()
.orderBy().asc("name");
return el;
}
/**
* Finds all users in a {@code project} who contains the {@code keyword} in name or loginId.
*
* @param keyword
* @param project
* @param pageParam
* @return
*/
public static Page<User> findUsers(String keyword, Project project, PageParam pageParam) {
return usersEL(keyword, project).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
/**
* Returns only the count of the {@link #findUsers(String, Project, PageParam)}
*
* @param keyword
* @param project
* @return
*/
public static int countUsers(String keyword, Project project) {
ExpressionList<User> el = usersEL(keyword, project);
return el.findRowCount();
}
private static ExpressionList<User> usersEL(String keyword, Project project) {
ExpressionList<User> el = User.find.where()
.eq("state", UserState.ACTIVE)
.eq("projectUser.project", project);
el.disjunction()
.add(Expr.icontains("name", keyword))
.add(Expr.icontains("loginId", keyword))
.endJunction()
.orderBy().asc("name");
return el;
}
/**
* Finds all users in an {@code organization} who contains the {@code keyword} in name or loginId.
*
* @param keyword
* @param organization
* @param pageParam
* @return
*/
public static Page<User> findUsers(String keyword, Organization organization, PageParam pageParam) {
return usersEL(keyword, organization).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
/**
* Returns only the count of the {@link #findUsers(String, Organization, PageParam)}
*
* @param keyword
* @param organization
* @return
*/
public static int countUsers(String keyword, Organization organization) {
return usersEL(keyword, organization).findRowCount();
}
private static ExpressionList<User> usersEL(String keyword, Organization organization) {
ExpressionList<User> el = User.find.where()
.eq("state", UserState.ACTIVE)
.eq("groupUser.organization", organization);
el.disjunction()
.add(Expr.icontains("name", keyword))
.add(Expr.icontains("loginId", keyword))
.endJunction()
.orderBy().asc("name");
return el;
}
/**
* Finds projects that contains {@code keyword} in name or overview.
*
* @param keyword
* @param user
* @param pageParam
* @return
*/
public static Page<Project> findProjects(String keyword, User user, PageParam pageParam) {
return projectsEL(keyword, user).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
/**
* Returns only the count of the {@link #projectsEL(String, User)}
*
* findRowCounts()'s performance is better then findList().size()'s,
* but findRowCounts() has some issues in some cases:
* - https://groups.google.com/forum/#!msg/ebean/BRRTpyL_Bek/lK4IcuVhplwJ
* - https://github.com/ebean-orm/avaje-ebeanorm/issues/165
* - https://github.com/ebean-orm/avaje-ebeanorm/blob/master/src/test/java/com/avaje/tests/query/other/TestQueryConversationRowCount.java
*
* @param keyword
* @param user
* @return
*/
public static int countProjects(String keyword, User user) {
return projectsEL(keyword, user).findList().size();
}
/**
* Finds all projects in an {@code organization} that contains the {@code keyword} in name or overview.
*
* @param keyword
* @param user
* @param organization
* @param pageParam
* @return
*/
public static Page<Project> findProjects(String keyword, User user, Organization organization, PageParam pageParam) {
return projectsEL(keyword, user).eq("organization", organization)
.findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
/**
* Returns only the count of the {@link #findProjects(String, User, Organization, PageParam)}
*
* @param keyword
* @param user
* @param organization
* @return
*/
public static int countProjects(String keyword, User user, Organization organization) {
return projectsEL(keyword, user).eq("organization", organization).findList().size();
}
private static ExpressionList<Project> projectsEL(String keyword, User user) {
ExpressionList<Project> el = Project.find.where();
if(user.isAnonymous()) {
el.eq("projectScope", ProjectScope.PUBLIC);
el.disjunction()
.icontains("overview", keyword)
.icontains("name", keyword)
.endJunction();
} else {
Junction<Project> junction = el.conjunction();
Junction<Project> pj = junction.disjunction();
pj.add(Expr.eq("projectScope", ProjectScope.PUBLIC)); // public
List<Organization> orgs = Organization.findOrganizationsByUserLoginId(user.loginId); // protected
if(!orgs.isEmpty()) {
pj.and(Expr.in("organization", orgs), Expr.eq("projectScope", ProjectScope.PROTECTED));
}
pj.add(Expr.eq("projectUser.user.id", user.id)); // private
pj.endJunction();
junction.disjunction()
.icontains("overview", keyword)
.icontains("name", keyword)
.endJunction();
junction.endJunction();
}
el.orderBy().asc("name");
return el;
}
public static Page<Milestone> findMilestones(String keyword, User user, PageParam pageParam) {
return milestonesEL(keyword, user).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
public static int countMilestones(String keyword, User user) {
return milestonesEL(keyword, user).findRowCount();
}
private static ExpressionList<Milestone> milestonesEL(String keyword, User user) {
ExpressionList<Milestone> el = Milestone.find.where();
Junction<Milestone> junction = el.disjunction();
inProjectsTemplate(keyword, user, junction, DEFAULT_PATH_TO_PROJECT, containsKeywordInMilestone);
junction.endJunction();
el.orderBy().desc("dueDate");
return el;
}
public static Page<Milestone> findMilestones(String keyword, User user, Project project, PageParam pageParam) {
if(!AccessControl.isAllowed(user, project.asResource(), Operation.READ)) {
return emptyPage();
}
return milestonesEL(keyword, project).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
public static int countMilestones(String keyword, User user, Project project) {
if(!AccessControl.isAllowed(user, project.asResource(), Operation.READ)) {
return 0;
}
return milestonesEL(keyword, project).findRowCount();
}
private static ExpressionList<Milestone> milestonesEL(String keyword, Project project) {
ExpressionList<Milestone> el = Milestone.find.where()
.eq("project", project);
Junction<Milestone> junction = el.disjunction();
containsKeywordIn(keyword, junction, new String[]{"title", "contents"});
junction.endJunction();
el.orderBy().desc("dueDate");
return el;
}
public static Page<Milestone> findMilestones(String keyword, User user, Organization organization, PageParam pageParam) {
return milestonesEL(keyword, user, organization).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
public static int countMilestones(String keyword, User user, Organization organization) {
return milestonesEL(keyword, user, organization).findRowCount();
}
private static ExpressionList<Milestone> milestonesEL(String keyword, User user, Organization organization) {
ExpressionList<Milestone> el = Milestone.find.where()
.eq("project.organization", organization);
Junction<Milestone> junction = el.disjunction();
inProjectsTemplate(keyword, user, organization, junction, DEFAULT_PATH_TO_PROJECT, containsKeywordInMilestone);
junction.endJunction();
el.orderBy().desc("dueDate");
return el;
}
public static Page<IssueComment> findIssueComments(String keyword, User user, PageParam pageParam) {
return issueCommentsEL(keyword, user).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
public static int countIssueComments(String keyword, User user) {
return issueCommentsEL(keyword, user).findRowCount();
}
private static ExpressionList<IssueComment> issueCommentsEL(String keyword, User user) {
ExpressionList<IssueComment> el = IssueComment.find.where();
Junction<IssueComment> junction = el.disjunction();
inProjectsTemplate(keyword, user, junction, "issue.project", containsKeywordInIssueComment);
equalsUserTemplate(keyword, user, junction, DEFAULT_PATH_TO_AUTHOR, containsKeywordInIssueComment);
junction.endJunction();
el.orderBy().desc("createdDate");
return el;
}
public static Page<IssueComment> findIssueComments(String keyword, User user, Project project, PageParam pageParam) {
return issueCommentsEL(keyword, user, project).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
public static int countIssueComments(String keyword, User user, Project project) {
return issueCommentsEL(keyword, user, project).findRowCount();
}
private static ExpressionList<IssueComment> issueCommentsEL(String keyword, User user, Project project) {
ExpressionList<IssueComment> el = IssueComment.find.where()
.eq("issue.project", project);
if(!AccessControl.isAllowed(user, project.asResource(), Operation.READ)) {
el.eq("authorId", user.id);
}
containsKeywordIn(keyword, el.conjunction(), new String[]{"contents"});
el.orderBy().desc("createdDate");
return el;
}
public static Page<IssueComment> findIssueComments(String keyword, User user, Organization organization, PageParam pageParam) {
return issueCommentsEL(keyword, user, organization).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
public static int countIssueComments(String keyword, User user, Organization organization) {
return issueCommentsEL(keyword, user, organization).findRowCount();
}
private static ExpressionList<IssueComment> issueCommentsEL(String keyword, User user, Organization organization) {
ExpressionList<IssueComment> el = IssueComment.find.where()
.eq("issue.project.organization", organization);
Junction<IssueComment> junction = el.disjunction();
inProjectsTemplate(keyword, user, organization, junction, "issue.project", containsKeywordInIssueComment);
equalsUserTemplate(keyword, user, junction, DEFAULT_PATH_TO_AUTHOR, containsKeywordInIssueComment);
junction.endJunction();
el.orderBy().desc("createdDate");
return el;
}
public static Page<PostingComment> findPostComments(String keyword, User user, PageParam pageParam) {
return postCommentsEL(keyword, user).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
public static int countPostComments(String keyword, User user) {
return postCommentsEL(keyword, user).findRowCount();
}
private static ExpressionList<PostingComment> postCommentsEL(String keyword, User user) {
ExpressionList<PostingComment> el = PostingComment.find.where();
Junction<PostingComment> junction = el.disjunction();
inProjectsTemplate(keyword, user, junction, "posting.project", containsKeywordInPostComment);
equalsUserTemplate(keyword, user, junction, DEFAULT_PATH_TO_AUTHOR, containsKeywordInPostComment);
junction.endJunction();
el.orderBy().desc("createdDate");
return el;
}
public static Page<PostingComment> findPostComments(String keyword, User user, Project project, PageParam pageParam) {
return postCommentsEL(keyword, user, project).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
public static int countPostComments(String keyword, User user, Project project) {
return postCommentsEL(keyword, user, project).findRowCount();
}
private static ExpressionList<PostingComment> postCommentsEL(String keyword, User user, Project project) {
ExpressionList<PostingComment> el = PostingComment.find.where()
.eq("posting.project", project);
if(!AccessControl.isAllowed(user, project.asResource(), Operation.READ)) {
el.eq("authorId", user.id);
}
containsKeywordIn(keyword, el.conjunction(), new String[]{"contents"});
el.orderBy().desc("createdDate");
return el;
}
public static Page<PostingComment> findPostComments(String keyword, User user, Organization organization, PageParam pageParam) {
return postCommentsEL(keyword, user, organization).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
public static int countPostComments(String keyword, User user, Organization organization) {
return postCommentsEL(keyword, user, organization).findRowCount();
}
private static ExpressionList<PostingComment> postCommentsEL(String keyword, User user, Organization organization) {
ExpressionList<PostingComment> el = PostingComment.find.where()
.eq("posting.project.organization", organization);
Junction<PostingComment> junction = el.disjunction();
inProjectsTemplate(keyword, user, organization, junction, "posting.project", containsKeywordInPostComment);
equalsUserTemplate(keyword, user, junction, DEFAULT_PATH_TO_AUTHOR, containsKeywordInPostComment);
junction.endJunction();
el.orderBy().desc("createdDate");
return el;
}
public static Page<ReviewComment> findReviews(String keyword, User user, PageParam pageParam) {
return reviewsEL(keyword, user).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
public static int countReviews(String keyword, User user) {
return reviewsEL(keyword, user).findRowCount();
}
private static ExpressionList<ReviewComment> reviewsEL(String keyword, User user) {
ExpressionList<ReviewComment> el = ReviewComment.find.where();
Junction<ReviewComment> junction = el.disjunction();
inProjectsTemplate(keyword, user, junction, "thread.project", containsKeywordInReviewComment);
equalsUserTemplate(keyword, user, junction, "author.id", containsKeywordInReviewComment);
junction.endJunction();
el.orderBy().desc("createdDate");
return el;
}
public static Page<ReviewComment> findReviews(String keyword, User user, Project project, PageParam pageParam) {
return reviewsEL(keyword, user, project).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
public static int countReviews(String keyword, User user, Project project) {
return reviewsEL(keyword, user, project).findRowCount();
}
private static ExpressionList<ReviewComment> reviewsEL(String keyword, User user, Project project) {
ExpressionList<ReviewComment> el = ReviewComment.find.where()
.eq("thread.project", project);
if(!AccessControl.isAllowed(user, project.asResource(), Operation.READ)) {
el.eq("author.id", user.id);
}
containsKeywordIn(keyword, el.conjunction(), new String[]{"contents"});
el.orderBy().desc("createdDate");
return el;
}
public static Page<ReviewComment> findReviews(String keyword, User user, Organization organization, PageParam pageParam) {
return reviewsEL(keyword, user, organization).findPagingList(pageParam.getSize()).getPage(pageParam.getPage());
}
public static int countReviews(String keyword, User user, Organization organization) {
return reviewsEL(keyword, user, organization).findRowCount();
}
private static ExpressionList<ReviewComment> reviewsEL(String keyword, User user, Organization organization) {
ExpressionList<ReviewComment> el = ReviewComment.find.where()
.eq("thread.project.organization", organization);
Junction<ReviewComment> junction = el.disjunction();
inProjectsTemplate(keyword, user, organization, junction, "thread.project", containsKeywordInReviewComment);
equalsUserTemplate(keyword, user, junction, "author.id", containsKeywordInReviewComment);
junction.endJunction();
el.orderBy().desc("createdDate");
return el;
}
interface JunctionOperation<T> {
void withJunction(String keyword, Junction<T> junction);
}
private static <T> void containsKeywordIn(String keyword, Junction<T> junction, String[] fields) {
Junction<T> byKeyword = junction.disjunction();
for(String field : fields) {
byKeyword.add(Expr.icontains(field, keyword));
}
byKeyword.endJunction();
}
private static <T> void inProjectsTemplate(String keyword, User user, Organization organization, Junction<T> junction, String pathToProject, JunctionOperation<T> junctionOperation) {
if(pathToProject == null) {
pathToProject = "project";
}
Junction<T> projectAndKeyword = junction.conjunction();
if(user.isAnonymous()) {
projectAndKeyword.eq(pathToProject + ".projectScope", ProjectScope.PUBLIC);
} else {
ExpressionList<Project> pel = Project.find.where()
.eq("organization", organization)
.disjunction()
.add(Expr.eq("projectUser.user.id", user.id));
if(OrganizationUser.exist(organization.id, user.id)) {
pel.add(Expr.in("projectScope", new ProjectScope[]{ProjectScope.PUBLIC, ProjectScope.PROTECTED}));
} else {
pel.add(Expr.eq("projectScope", ProjectScope.PUBLIC));
}
pel.endJunction();
List<Project> projects = pel.findList();
if(!projects.isEmpty()) {
projectAndKeyword.in(pathToProject, projects);
}
}
junctionOperation.withJunction(keyword, projectAndKeyword);
projectAndKeyword.endJunction();
junction.endJunction();
}
private static <T> void inProjectsTemplate(String keyword, User user, Junction<T> junction, String pathToProject, JunctionOperation<T> junctionOperation) {
if(pathToProject == null) {
pathToProject = "project";
}
Junction<T> projectAndKeyword = junction.conjunction();
if(user.isAnonymous()) {
projectAndKeyword.eq(pathToProject + ".projectScope", ProjectScope.PUBLIC);
} else {
ExpressionList<Project> pel = Project.find.where().disjunction()
.add(Expr.eq("projectScope", ProjectScope.PUBLIC))
.add(Expr.eq("projectUser.user.id", user.id));
List<Organization> orgs = Organization.findOrganizationsByUserLoginId(user.loginId);
if(!orgs.isEmpty()) {
pel.and(Expr.in("organization", orgs), Expr.ne("projectScope", ProjectScope.PRIVATE));
}
pel.endJunction();
List<Project> projects = pel.findList();
if(!projects.isEmpty()) {
projectAndKeyword.in(pathToProject, projects);
}
}
junctionOperation.withJunction(keyword, projectAndKeyword);
projectAndKeyword.endJunction();
}
private static <T> void equalsUserTemplate(String keyword, User user, Junction<T> junction, String pathToUserId, JunctionOperation<T> junctionOperation) {
if(!user.isAnonymous()) {
if(pathToUserId == null) {
pathToUserId = "authorId";
}
Junction<T> userAndKeyword = junction.conjunction();
userAndKeyword.eq(pathToUserId, user.id);
junctionOperation.withJunction(keyword, userAndKeyword);
userAndKeyword.endJunction();
}
}
private static <T> Page<T> emptyPage() {
return new Page<T>() {
@Override
public List<T> getList() {
return new ArrayList<>();
}
@Override
public int getTotalRowCount() {
return 0;
}
@Override
public int getTotalPageCount() {
return 0;
}
@Override
public int getPageIndex() {
return 0;
}
@Override
public boolean hasNext() {
return false;
}
@Override
public boolean hasPrev() {
return false;
}
@Override
public Page<T> next() {
return null;
}
@Override
public Page<T> prev() {
return null;
}
@Override
public String getDisplayXtoYofZ(String s, String s2) {
return null;
}
};
}
}