BrightSide Workbench Full Report + Source Code
KnowledgeBaseQuery.java
Go to the documentation of this file.
1 /*
2  * TurrĂ³ i Cutiller Foundation. License notice.
3  * Copyright (C) 2016 Lluis TurrĂ³ Cutiller <http://www.turro.org/>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Affero General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Affero General Public License for more details.
14  *
15  * You should have received a copy of the GNU Affero General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 package org.turro.dossier.kb;
20 
21 import java.util.Collections;
22 import java.util.EnumSet;
23 import java.util.Set;
24 import org.turro.string.Strings;
25 import org.turro.action.Contacts;
26 import org.turro.auth.Authentication;
27 import org.turro.dossier.db.DossierPU;
28 import org.turro.dossier.entity.Category;
29 import org.turro.dossier.entity.Dossier;
30 import org.turro.dossier.entity.DossierStatus;
31 import org.turro.dossier.entity.IssueParticipantRole;
32 import org.turro.dossier.entity.IssueResolution;
33 import org.turro.dossier.entity.IssueStatus;
34 import org.turro.dossier.entity.IssueType;
35 import org.turro.elephant.db.WhereClause;
36 import org.turro.jpa.Dao;
37 import org.turro.plugin.contacts.IContact;
38 import org.turro.util.Chars;
39 
44 public class KnowledgeBaseQuery {
45 
46  private String searchValue = "";
47  private IContact byParticipant;
48  private final IContact realContact;
49  private Long dossierId;
50  private Dossier dossier;
51  private EnumSet<IssueParticipantRole> roles = EnumSet.noneOf(IssueParticipantRole.class);
52  private EnumSet<IssueStatus> status = EnumSet.noneOf(IssueStatus.class);
53  private EnumSet<IssueResolution> resolutions = EnumSet.noneOf(IssueResolution.class);
54  private EnumSet<IssueType> types = EnumSet.noneOf(IssueType.class);
55  private Category category;
56  private int maxResults = 300;
57  private boolean onlyTitle = false;
58 
59  public KnowledgeBaseQuery() {
60  resetToDefault();
61  realContact = Authentication.getIContact();
62  }
63 
64  public KnowledgeBaseQuery(IContact contact) {
65  resetToDefault();
66  realContact = contact;
67  }
68 
69  private void resetToDefault() {
70  roles.clear();
71  types.clear();
72  status.clear();
73  resolutions.clear();
74  }
75 
77  Dao dao = new DossierPU();
79  if(wc != null) {
80  return new KnowledgeBaseList(dao.getResultList(wc, maxResults), realContact);
81  } else {
82  return new KnowledgeBaseList(Collections.EMPTY_LIST, realContact);
83  }
84  }
85 
86  public Category getCategory() {
87  return category;
88  }
89 
90  public void setCategory(Category category) {
91  this.category = category;
92  }
93 
94  public Set<IssueResolution> getResolutions() {
95  return resolutions;
96  }
97 
98  public void setResolutions(Set<IssueResolution> resolutions) {
99  this.resolutions = resolutions.isEmpty() ? EnumSet.noneOf(IssueResolution.class) : EnumSet.copyOf(resolutions);
100  }
101 
102  public Set<IssueParticipantRole> getRoles() {
103  return roles;
104  }
105 
106  public void setRoles(Set<IssueParticipantRole> roles) {
107  this.roles = EnumSet.copyOf(roles);
108  }
109 
110  public Set<IssueStatus> getStatus() {
111  return status;
112  }
113 
114  public void setStatus(Set<IssueStatus> status) {
115  this.status = status.isEmpty() ? EnumSet.noneOf(IssueStatus.class) : EnumSet.copyOf(status);
116  }
117 
118  public Set<IssueType> getTypes() {
119  return types;
120  }
121 
122  public void setTypes(Set<IssueType> types) {
123  this.types = types.isEmpty() ? EnumSet.noneOf(IssueType.class) : EnumSet.copyOf(types);
124  }
125 
126  public void setType(IssueType type) {
127  this.types = EnumSet.of(type);
128  }
129 
130  public int getMaxResults() {
131  return maxResults;
132  }
133 
134  public void setMaxResults(int maxResults) {
135  this.maxResults = maxResults;
136  }
137 
139  WhereClause wc = new WhereClause();
140  wc.addClause("select distinct issue from Issue as issue");
141  wc.addClause("left outer join issue.participants participant");
142  wc.addClause("left outer join issue.comments comment");
143  wc.addClause("where issue.publishable = TRUE");
144 
145  boolean asParticipant = false;
146 
147  if(byParticipant != null && byParticipant.isValid()) {
148  asParticipant = roles.isEmpty() ||
149  roles.contains(IssueParticipantRole.ISSUE_REPORTER) ||
150  roles.contains(IssueParticipantRole.ISSUE_RESPONSIBLE) ||
151  roles.contains(IssueParticipantRole.ISSUE_QA) ||
152  roles.contains(IssueParticipantRole.ISSUE_ASSISTANT);
153  }
154 
155  if(Strings.isEmpty(searchValue)) {
156  return null;
157  }
158 
159  try {
160  long id = Long.valueOf(searchValue);
161  if(id > 0) {
162  wc.addClause("and issue.id = :id");
163  wc.addNamedValue("id", id);
164  return wc;
165  }
166  } catch(Exception ex) {}
167 
168  if(onlyTitle) {
169  wc.addLikeFields(new String[] {
170  "issue.description"
171  }, (searchValue == null ? "" : searchValue.replaceAll("\\*", "%")));
172  } else {
173  wc.addLikeFields(new String[] {
174  "issue.description",
175  "comment.comment"
176  }, (searchValue == null ? "" : searchValue.replaceAll("\\*", "%")));
177  }
178 
179  if(asParticipant) {
180  String sep = "";
181  wc.addClause("and (");
182  if(roles.isEmpty()) {
183  wc.addClause("(");
184  wc.addClause("participant.idContact = :idContact");
185  wc.addNamedValue("idContact", byParticipant.getId());
186  wc.addClause(")");
187  } else {
188  for(IssueParticipantRole ii : roles) {
189  wc.addClause(sep);
190  sep = "or";
191  wc.addClause("(");
192  wc.addClause("participant.idContact = :idContact");
193  wc.addNamedValue("idContact", byParticipant.getId());
194  wc.addClause("and participant.role = :" + ii.toString());
195  wc.addNamedValue(ii.toString(), ii);
196  wc.addClause(")");
197  }
198  }
199  wc.addClause(")");
200  }
201 
202  if(!status.isEmpty()) {
203  String sep = "";
204  wc.addClause("and (");
205  for(IssueStatus ii : status) {
206  wc.addClause(sep);
207  sep = "or";
208  wc.addClause("issue.status = :" + ii.toString());
209  wc.addNamedValue(ii.toString(), ii);
210  }
211  wc.addClause(")");
212  }
213 
214  if(!resolutions.isEmpty()) {
215  String sep = "";
216  wc.addClause("and (");
217  for(IssueResolution ii : resolutions) {
218  wc.addClause(sep);
219  sep = "or";
220  wc.addClause("issue.resolution = :" + ii.toString());
221  wc.addNamedValue(ii.toString(), ii);
222  }
223  wc.addClause(")");
224  }
225 
226  if(!types.isEmpty()) {
227  String sep = "";
228  wc.addClause("and (");
229  for(IssueType ii : types) {
230  wc.addClause(sep);
231  sep = "or";
232  wc.addClause("issue.type = :" + ii.toString());
233  wc.addNamedValue(ii.toString(), ii);
234  }
235  wc.addClause(")");
236  }
237 
238  if(dossier != null) {
239  wc.addClause("and issue.dossier = :dossier");
240  wc.addNamedValue("dossier", dossier);
241  } else if(dossierId != null && dossierId > 0) {
242  wc.addClause("and issue.dossier.id = :dossierId");
243  wc.addNamedValue("dossierId", dossierId);
244  } else {
245  wc.addClause("and issue.dossier.status = :dstatus");
247  }
248 
249  if(category != null) {
250  wc.addClause("and (");
251  wc.addClause("issue.dossier.category.fullDescription = :fullCatDesc");
252  wc.addClause("or issue.dossier.category.fullDescription like concat(:fullCatDesc, '" + Chars.backward().spaced() + "%')");
253  wc.addNamedValue("fullCatDesc", category.getFullDescription());
254  wc.addClause(")");
255  }
256 
257  wc.addClause("order by issue.modification desc");
258 
259  return wc;
260  }
261 
262  public Dossier getDossier() {
263  return dossier;
264  }
265 
266  public void setDossier(Dossier dossier) {
267  this.dossier = dossier;
268  }
269 
270  public Long getDossierId() {
271  return dossierId;
272  }
273 
274  public void setDossierId(Long dossierId) {
275  this.dossierId = dossierId;
276  }
277 
278  public String getSearchValue() {
279  return searchValue;
280  }
281 
282  public void setSearchValue(String searchValue) {
283  this.searchValue = searchValue;
284  }
285 
286  public boolean isOnlyTitle() {
287  return onlyTitle;
288  }
289 
290  public void setOnlyTitle(boolean onlyTitle) {
291  this.onlyTitle = onlyTitle;
292  }
293 
295  return byParticipant;
296  }
297 
298  public void setByParticipant(IContact byParticipant) {
299  this.byParticipant = byParticipant;
300  }
301 
302  public void setByParticipantId(String id) {
303  this.byParticipant = Contacts.getContactById(id);
304  }
305 
306 }
static IContact getContactById(String id)
Definition: Contacts.java:72
void setResolutions(Set< IssueResolution > resolutions)
void setByParticipant(IContact byParticipant)
void setRoles(Set< IssueParticipantRole > roles)
void setStatus(Set< IssueStatus > status)
Set< IssueParticipantRole > getRoles()
void addLikeFields(String[] fields, String value)
void addNamedValue(String name, Object value)