BrightSide Workbench Full Report + Source Code
DossierIndicator.java
Go to the documentation of this file.
1 /*
2  * TurrĂ³ i Cutiller Foundation. License notice.
3  * Copyright (C) 2020 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.indicator;
20 
21 import java.time.Duration;
22 import java.time.Instant;
23 import java.util.Date;
24 import java.util.stream.Stream;
25 import org.turro.string.Strings;
26 import org.turro.annotation.ElephantIndicator;
27 import org.turro.dossier.db.DossierPU;
28 import org.turro.dossier.entity.DescriptorValue;
29 import org.turro.dossier.entity.Dossier;
30 import org.turro.dossier.entity.IssueParticipantRole;
31 import org.turro.elephant.db.WhereClause;
32 import org.turro.jpa.Dao;
33 import org.turro.matching.ContactSiblings;
34 import org.turro.matching.GenericMatching;
35 import org.turro.matching.GenericSiblings;
36 import org.turro.matching.IMatching;
37 import org.turro.ranking.GenericRanking;
38 import org.turro.ranking.IRanking;
39 
44 @ElephantIndicator
45 public class DossierIndicator extends AbstractIndicator {
46 
47  public DossierIndicator() {
48  root = "dossier";
49  }
50 
51  @Override
52  protected void initVariables() {
53  addVariable("participation", true, VariableType.BOTH_VARIABLE);
54  addVariable("categoryParticipation", true, VariableType.BOTH_VARIABLE);
55  addVariable("daysCreation", VariableType.RANKING_VARIABLE);
56  addVariable("daysActivity", VariableType.RANKING_VARIABLE);
58  addVariable("issues", true, VariableType.BOTH_VARIABLE);
59  addVariable("issueActivity", true, VariableType.BOTH_VARIABLE);
60  addVariable("issueResponsible", true, VariableType.RANKING_VARIABLE, "dossier");
61  addVariable("issueReporter", true, VariableType.RANKING_VARIABLE, "dossier");
62  addVariable("issueQA", true, VariableType.RANKING_VARIABLE, "dossier");
63  addVariable("issueAssistant", true, VariableType.RANKING_VARIABLE, "dossier");
64  addVariable("siblings", true, VariableType.MATCHING_VARIABLE);
65  addVariable("siblingsCategory", true, VariableType.MATCHING_VARIABLE);
66  }
67 
68  @Override
69  protected void initExternalVariables() {
70  addExternalVariable("student", "challenges");
71  addExternalVariable("student", "responses");
72  addExternalVariable("generic", "stars");
73  addExternalVariable("generic", "comments");
74  addExternalVariable("attach", "attachments");
75  addExternalVariable("forum", "topics");
76  addExternalVariable("forum", "posts");
77  addExternalVariable("commons", "followed");
78  addExternalVariable("commons", "seen");
79  addExternalVariable("commons", "like");
80  }
81 
82  @Override
83  public void generateSiblings() {
84  getDao().executeNativeUpdate("truncate table " + ContactSiblings.class.getSimpleName());
85  try(Stream<GenericSiblings> siblings = Indicators.getIndicator("generic").getSiblingPaths("contact")) {
86  siblings.forEach(s -> getDao().poolObject(s.copyTo(new ContactSiblings()), 1000));
87  }
88  getDao().finishPool();
89  }
90 
91  @Override
92  protected Dao createDao() {
93  return new DossierPU();
94  }
95 
96  @Override
97  public double getValue(IndicatorVariable variable, Object entity) {
98  if((entity instanceof Dossier) && itsMine(variable)) {
99  Dossier dossier = (Dossier) entity;
100  switch(variable.getName()) {
101  case "daysCreation":
102  return dossier.getCreation() != null ? Duration.between(dossier.getCreation().toInstant(), Instant.now()).toDays() : 9999.9;
103  case "daysActivity":
104  return getDaysLastActivity(dossier);
105  case "words":
106  return countWords(dossier);
107  }
108  }
109  return 0.0;
110  }
111 
112  @Override
113  protected void processRankingVariable(Dao dao, IPreprocessor preprocessor, IndicatorVariable variable, String entityRoot) {
114  WhereClause wc = null;
115  if("dossier".equals(entityRoot)) {
116  switch(variable.getName()) {
117  case "participation":
118  wc = PreprocessClause.load("Participant")
119  .setRankingRoot(entityRoot)
120  .setRankingField("concat('/dossier/',dossier.id)")
121  .setVariable(variable)
122  .setAggregate("count(id)")
123  .getClause();
124  break;
125  case "categoryParticipation":
126  wc = PreprocessClause.load("Dossier d, CategoryParticipant cp")
127  .addCondition("and d.category.fullDescription like concat(cp.category.fullDescription, '%')")
128  .setRankingRoot(entityRoot)
129  .setRankingField("concat('/dossier/',d.id)")
130  .setVariable(variable)
131  .setAggregate("count(cp.id)")
132  .getClause();
133  break;
134  case "issues":
135  wc = PreprocessClause.load("Issue")
136  .setRankingRoot(entityRoot)
137  .setRankingField("concat('/dossier/',dossier.id)")
138  .setVariable(variable)
139  .setAggregate("count(id)")
140  .getClause();
141  break;
142  case "issueActivity":
143  wc = PreprocessClause.load("IssueComment")
144  .setRankingRoot(entityRoot)
145  .setRankingField("concat('/dossier/',issue.dossier.id)")
146  .setVariable(variable)
147  .setAggregate("count(id)")
148  .getClause();
149  break;
150  }
151  } else if("contact".equals(entityRoot)) {
152  switch(variable.getName()) {
153  case "participation":
154  wc = PreprocessClause.load("Participant")
155  .setRankingRoot(entityRoot)
156  .setRankingField("concat('/contact/', idContact)")
157  .setVariable(variable)
158  .setAggregate("count(id)")
159  .getClause();
160  break;
161  case "categoryParticipation":
162  wc = PreprocessClause.load("CategoryParticipant")
163  .setRankingRoot(entityRoot)
164  .setRankingField("concat('/contact/', idContact)")
165  .setVariable(variable)
166  .setAggregate("count(id)")
167  .getClause();
168  break;
169  case "issueResponsible":
170  wc = PreprocessClause.load("IssueParticipant")
171  .addCondition("and role = :role")
173  .setRankingRoot(entityRoot)
174  .setRankingField("concat('/contact/', idContact)")
175  .setVariable(variable)
176  .setAggregate("count(distinct issue.id)")
177  .getClause();
178  break;
179  case "issueReporter":
180  wc = PreprocessClause.load("IssueParticipant")
181  .addCondition("and role = :role")
183  .setRankingRoot(entityRoot)
184  .setRankingField("concat('/contact/', idContact)")
185  .setVariable(variable)
186  .setAggregate("count(distinct issue.id)")
187  .getClause();
188  break;
189  case "issueQA":
190  wc = PreprocessClause.load("IssueParticipant")
191  .addCondition("and role = :role")
193  .setRankingRoot(entityRoot)
194  .setRankingField("concat('/contact/', idContact)")
195  .setVariable(variable)
196  .setAggregate("count(distinct issue.id)")
197  .getClause();
198  break;
199  case "issueAssistant":
200  wc = PreprocessClause.load("IssueParticipant")
201  .addCondition("and role = :role")
203  .setRankingRoot(entityRoot)
204  .setRankingField("concat('/contact/', idContact)")
205  .setVariable(variable)
206  .setAggregate("count(distinct issue.id)")
207  .getClause();
208  break;
209  }
210  }
211  if(wc != null) {
212  try(Stream<GenericRanking> stream = dao.stream(GenericRanking.class, wc, 1000)) {
213  stream.forEach(r -> {
214  preprocessor.poolInstance(r.copyTo((IRanking) preprocessor.createInstance()));
215  });
216  preprocessor.finishPreprocessor();
217  }
218  }
219  }
220 
221  @Override
222  protected void processMatchingVariable(Dao dao, IPreprocessor preprocessor, IndicatorVariable variable, String entityRoot, String relatedRoot) {
223  WhereClause wc = null;
224  if("dossier".equals(entityRoot)) {
225  if("contact".equals(relatedRoot)) {
226  switch(variable.getName()) {
227  case "participation":
228  wc = PreprocessClause.load("Participant p")
229  .setRankingRoot(entityRoot)
230  .setMatchingRoot(relatedRoot)
231  .setRankingField("concat('/dossier/', p.dossier.id)")
232  .setMatchingField("p.idContact")
233  .setVariable(variable)
234  .setAggregate("count(p.id)")
235  .getClause();
236  break;
237  case "categoryParticipation":
238  wc = PreprocessClause.load("Dossier d, CategoryParticipant cp")
239  .addCondition("and d.category.fullDescription like concat(cp.category.fullDescription, '%')")
240  .setRankingRoot(entityRoot)
241  .setMatchingRoot(relatedRoot)
242  .setRankingField("concat('/dossier/', d.id)")
243  .setMatchingField("cp.idContact")
244  .setVariable(variable)
245  .setAggregate("count(cp.id)")
246  .getClause();
247  break;
248  case "issues":
249  wc = PreprocessClause.load("IssueParticipant p")
250  .setRankingRoot(entityRoot)
251  .setMatchingRoot(relatedRoot)
252  .setRankingField("concat('/dossier/', p.issue.dossier.id)")
253  .setMatchingField("p.idContact")
254  .setVariable(variable)
255  .setAggregate("count(distinct p.issue.id)")
256  .getClause();
257  break;
258  case "issueActivity":
259  wc = PreprocessClause.load("IssueComment c")
260  .setRankingRoot(entityRoot)
261  .setMatchingRoot(relatedRoot)
262  .setRankingField("concat('/dossier/', c.issue.dossier.id)")
263  .setMatchingField("c.idContact")
264  .setVariable(variable)
265  .setAggregate("count(c.id)")
266  .getClause();
267  break;
268  case "siblings":
269  wc = PreprocessClause.load("Participant p")
270  .addJoin("join ContactSiblings cs on cs.entityPath = concat('/contact/', p.idContact)")
271  .setRankingRoot(entityRoot)
272  .setMatchingRoot(relatedRoot)
273  .setRankingField("concat('/dossier/', p.dossier.id)")
274  .setMatchingField("cs.siblingPath")
276  .setVariable(variable)
277  .setAggregate("count(p.id)")
278  .getClause();
279  break;
280  case "siblingsCategory":
281  wc = PreprocessClause.load("Dossier d, CategoryParticipant cp, ContactSiblings cs")
282  .addCondition("and d.category.fullDescription like concat(cp.category.fullDescription, '%')")
283  .addCondition("and concat('/contact/', cp.idContact) = cs.entityPath")
284  .setRankingRoot(entityRoot)
285  .setMatchingRoot(relatedRoot)
286  .setRankingField("concat('/dossier/', d.id)")
287  .setMatchingField("cs.siblingPath")
289  .setVariable(variable)
290  .setAggregate("count(cp.id)")
291  .getClause();
292  break;
293  }
294  }
295  }
296  if(wc != null) {
297  try(Stream<GenericMatching> stream = dao.stream(GenericMatching.class, wc, 1000)) {
298  stream.forEach(r -> {
299  preprocessor.poolInstance(r.copyTo((IMatching) preprocessor.createInstance()));
300  });
301  preprocessor.finishPreprocessor();
302  }
303  }
304  }
305 
306  private double countWords(Dossier dossier) {
307  double count = 0;
308  if(dossier.getProject() != null) {
309  count += Strings.countWords(dossier.getProject().getGoal());
310  }
311  for(DescriptorValue dv :dossier.getDescriptors()) {
312  count += Strings.countWords(dv.getWiki());
313  }
314  return count;
315  }
316 
317  private double getDaysLastActivity(Dossier dossier) {
318  Date last = dossier.getLastActivity();
319  return last != null ? Duration.between(last.toInstant(), Instant.now()).toDays() : 0.0;
320  }
321 
322 }
Set< DescriptorValue > getDescriptors()
Definition: Dossier.java:231
void addVariable(String name, VariableType type)
void addExternalVariable(String root, String name)
void processMatchingVariable(Dao dao, IPreprocessor preprocessor, IndicatorVariable variable, String entityRoot, String relatedRoot)
double getValue(IndicatorVariable variable, Object entity)
void processRankingVariable(Dao dao, IPreprocessor preprocessor, IndicatorVariable variable, String entityRoot)
static IElephantIndicator getIndicator(String root)
Definition: Indicators.java:69
PreprocessClause setMatchingField(String pathField)
PreprocessClause addCondition(String condition)
PreprocessClause setVariable(IndicatorVariable variable)
PreprocessClause addJoin(String join)
PreprocessClause setMatchingRoot(String entityRoot)
PreprocessClause addNamedValue(String name, Object value)
PreprocessClause setAggregate(String aggregate)
PreprocessClause setRankingRoot(String entityRoot)
static PreprocessClause load(String table)
PreprocessClause setRankingField(String pathField)
void finishPool()
Definition: Dao.java:592
int executeNativeUpdate(SqlClause sc, Object... pars)
Definition: Dao.java:536
Stream< GenericSiblings > getSiblingPaths(String entityPath)
void poolInstance(Object value)