19 package org.turro.dossier.content;
21 import java.io.Writer;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.EnumSet;
25 import java.util.List;
27 import org.turro.string.Strings;
28 import org.turro.attach.www.AttachCtrl;
29 import org.turro.charts.Data;
30 import org.turro.collections.ItemOf;
31 import org.turro.collections.SetOf;
32 import org.turro.dossier.command.DossierAction;
33 import org.turro.dossier.db.DossierPU;
34 import org.turro.dossier.dossier.ProjectContext;
35 import org.turro.dossier.dw.DWIssueModel;
36 import org.turro.dossier.dw.DWWebChart;
37 import org.turro.dossier.entity.Category;
38 import org.turro.dossier.entity.Dossier;
39 import org.turro.dossier.entity.DossierStatus;
40 import org.turro.dossier.entity.DossierType;
41 import org.turro.dossier.entity.IssueResolution;
42 import org.turro.dossier.entity.IssueStatus;
43 import org.turro.dossier.entity.IssueType;
44 import org.turro.dossier.entity.ParticipantRole;
45 import org.turro.dossier.search.CategoryResults;
46 import org.turro.dossier.www.CategoriesTree;
47 import org.turro.dossier.www.KnowledgeBaseDashboard;
48 import org.turro.dossier.www.PhaseHtmlFilter;
49 import org.turro.elephant.context.Application;
50 import org.turro.elephant.context.ElephantContext;
51 import org.turro.elephant.context.IConstructor;
52 import org.turro.elephant.db.WhereClause;
53 import org.turro.elephant.impl.repository.Repository;
54 import org.turro.elephant.impl.repository.RepositoryFile;
55 import org.turro.elephant.web.SocialImageMap;
56 import org.turro.elephant.web.SocialNet;
57 import org.turro.entities.Entities;
58 import org.turro.file.util.FileAttach;
59 import org.turro.i18n.I_;
60 import org.turro.indicator.Statistics;
61 import org.turro.jpa.content.EntityDaoContentIterator;
62 import org.turro.jpa.search.DaoHtmlSearch;
63 import org.turro.jpa.search.DaoSearchKey;
64 import org.turro.marker.ElephantMarker;
65 import org.turro.phase.PhaseDefinitions;
66 import org.turro.plugin.contacts.IContact;
67 import org.turro.polls.PollsCtrl;
68 import org.turro.tags.TagCloud;
69 import org.turro.util.Arrays;
70 import org.turro.visual.DossierVisualElements;
71 import org.turro.visual.VisualElements;
72 import org.turro.www.commentit.CommentItCtrl;
73 import org.turro.www.describeit.DescribeItCtrl;
74 import org.turro.www.starit.StarItCtrl;
75 import org.turro.www.voteit.VoteItCtrl;
83 private String allowedCategories, issuePath, pendingWorths;
84 private long categoryId, dossierId, lastCategoryId = -1;
85 private List<String> dossierTypes, dossierStatus, projectPhases;
86 private boolean showSubject;
87 private boolean all, direct;
88 private Collection<IContact> related;
97 this.categoryId = categoryId;
101 this.dossierId = dossierId;
105 this.dossierTypes = dossierTypes;
109 this.dossierStatus = dossierStatus;
113 return projectPhases;
117 this.projectPhases = projectPhases;
125 this.showSubject = showSubject;
129 this.allowedCategories = allowedCategories;
137 this.issuePath = issuePath;
145 this.phaseFilter = phaseFilter;
153 this.direct = direct;
157 this.related = related;
161 return pendingWorths;
165 this.pendingWorths = pendingWorths;
171 wc.
addClause(
"select distinct dossier from Dossier as dossier");
172 wc.
addClause(
"left outer join dossier.participants participant");
173 wc.
addClause(
"left outer join dossier.project project");
179 .setEntityFields(
"dossier",
"id")
180 .setDefaultSorting(
"dossier.description")
181 .onCriteria(w -> addCriteria(w,
true))
188 wc.
addClause(
"select count(distinct dossier) from Dossier as dossier");
189 wc.
addClause(
"left outer join dossier.participants participant");
190 wc.
addClause(
"left outer join dossier.project project");
191 addCriteria(wc,
true);
205 prepareValues(e, page);
214 prepareValues(e, page);
227 wc.
addClause(
"select distinct dossier from Dossier as dossier");
228 wc.
addClause(
"left outer join dossier.participants participant");
229 wc.
addClause(
"left outer join dossier.project project");
230 addCriteria(wc,
true);
239 if(identifier ==
null) {
240 identifier = super.getIdentifier();
245 private void addCriteria(
WhereClause wc,
boolean filterPhase) {
252 dsk.
applyToQuery(wc, Arrays.objects(
"dossier.description"),
true);
256 PhaseHtmlFilter phf = PhaseHtmlFilter.getInstance(
constructor, ElephantContext.getContextVariable(
constructor));
257 if(phf !=
null && !phf.isEmpty()) {
258 int phase = Integer.valueOf(phf.getPhase());
261 wc.
addClause(
"and dossier.project.phase = :" + par);
268 wc.
addClause(
"and dossier.publishable = TRUE");
270 if(!Strings.isBlank(pendingWorths)) {
272 wc.
addClause(
"select v from WorthValue v");
273 wc.
addClause(
"where v.dossier = dossier");
274 wc.
addClause(
"and v.worthDefinition.id in (" + pendingWorths +
")");
275 wc.
addClause(
"and v.idContact = :pendContact");
280 wc.
addClause(
"and dossier.category.id in (" + getCategories(categoryId) +
")");
281 }
else if(dossierId > 0) {
282 wc.
addClause(
"and dossier.id = " + dossierId);
283 }
else if(!Strings.isBlank(allowedCategories)) {
285 String selCat = CategoriesTree.getSelectedItem(
constructor, ElephantContext.getContextVariable(
constructor));
286 if(!Strings.isBlank(selCat)) {
287 wc.
addClause(
"and dossier.category.fullDescription like '" + Category.getPathToFullDescription(selCat +
"%'"));
290 if(!
"all".equals(allowedCategories)) {
291 CategoryResults.addExistsCategoryAffiliance(wc, allowedCategories,
"dossier");
294 if(dossierTypes !=
null && dossierTypes.size() > 0) {
297 for(String s : dossierTypes) {
298 DossierType dt = DossierType.valueOf(s);
301 wc.
addClause(sep +
"dossier.type = :" + par);
308 if(dossierStatus !=
null && dossierStatus.size() > 0) {
311 for(String s : dossierStatus) {
312 DossierStatus ds = DossierStatus.valueOf(s);
315 wc.
addClause(sep +
"dossier.status = :" + par);
323 if(projectPhases !=
null && !projectPhases.isEmpty()) {
324 List<Integer> indexes = PhaseDefinitions.instance().stream()
325 .filter(pd -> pd.anyStringMatch(projectPhases))
326 .map(pd -> pd.getIndex()).toList();
327 wc.
addClause(
"and dossier.project.phase in (:phases)");
332 wc.
addIn(
"and",
"dossier.id", TagCloud.getIdentifiersAsLong(
constructor,
"dossier"));
341 return super.isValid(e);
350 private String getCategories(
long categoryId) {
351 String result =
null;
353 return addCategory(category, result);
356 private String addCategory(Category category, String result) {
357 if(category !=
null) {
358 result = (String) (((result ==
null) ?
"" : result +
",") + category.getId());
359 for(Category c : category.getChildren()) {
360 result = addCategory(c, result);
366 private void prepareValues(
final Dossier dossier,
int page) {
370 (dossier.getStatus().equals(DossierStatus.DOSSIER_OPENED) ?
" openned" :
"") +
371 (dossier.getStatus().equals(DossierStatus.DOSSIER_CLOSED) ?
" closed" :
"") +
372 (dossier.getStatus().equals(DossierStatus.DOSSIER_FROZEN) ?
" frozen" :
""));
374 if(!Strings.isBlank(issuePath)) {
375 marker.
put(
"issuePath", ElephantContext.getRootWebPath() + issuePath);
376 }
else if(dossier.getFullParticipants().isShowAllIssues(
getContact())) {
377 marker.
put(
"issuePath", ElephantContext.getRootWebPath() +
"/user/kbase");
380 final DWIssueModel issueModel =
new DWIssueModel();
381 issueModel.setDossierId(dossier.getId());
385 protected void onCreate(Data data, Object[] pars) {
386 data.setLink(ElephantContext.getRootWebPath() + KnowledgeBaseDashboard.createLink(
"*",
false,
387 (Set<IssueType>) EnumSet.of((IssueType) pars[0]),
null,
null, dossier.getId()));
390 protected void loadData() {
391 setData(I_.get(
"Type"), issueModel.getByType());
397 protected void onCreate(Data data, Object[] pars) {
398 data.setLink(ElephantContext.getRootWebPath() + KnowledgeBaseDashboard.createLink(
"*",
false,
null,
399 (Set<IssueStatus>) EnumSet.of((IssueStatus) pars[0]),
null, dossier.getId()));
402 protected void loadData() {
403 setData(I_.get(
"Status"), issueModel.getByStatus());
407 DWWebChart resolution =
new DWWebChart(
constructor) {
409 protected void onCreate(Data data, Object[] pars) {
410 data.setLink(ElephantContext.getRootWebPath() + KnowledgeBaseDashboard.createLink(
"*",
false,
null,
null,
411 (Set<IssueResolution>) EnumSet.of((IssueResolution) pars[0]), dossier.getId()));
414 protected void loadData() {
415 setData(I_.get(
"Resolution"), issueModel.getByResolution());
418 marker.
put(
"resolutionChart", resolution);
420 marker.
put(
"actions",
new DossierAction());
422 marker.
put(
"projectContext",
new ProjectContext());
424 marker.
put(
"dve", DossierVisualElements.load());
438 ArrayList<RepositoryFile> files =
new ArrayList<>();
461 wc.
addClause(
"participant.idContact = :idContact");
463 wc.
addClause(
"and (participant.role = :cpdrole1 or participant.role = :cpdrole2)");
464 wc.
addNamedValue(
"cpdrole1", ParticipantRole.PARTICIPANT_OWNER);
465 wc.
addNamedValue(
"cpdrole2", ParticipantRole.PARTICIPANT_ASSISTANT);
468 }
else if(related !=
null) {
469 if(related.isEmpty()) {
473 wc.
addClause(
"participant.idContact in (:idContact)");
474 wc.
addNamedValue(
"idContact",
new SetOf<IContact, String>(related,
new ItemOf<IContact, String>() {
476 public String getFrom(IContact e) {
480 wc.
addClause(
"and (participant.role = :cpdrole1 or participant.role = :cpdrole2)");
481 wc.
addNamedValue(
"cpdrole1", ParticipantRole.PARTICIPANT_OWNER);
482 wc.
addNamedValue(
"cpdrole2", ParticipantRole.PARTICIPANT_ASSISTANT);
485 }
else if(
isRestricted() && !Application.getApplication().isInRole(
"dossier:all")) {
490 wc.
addClause(
"participant.idContact = :idContact");
492 wc.
addClause(
"and (participant.role = :cpdrole1 or participant.role = :cpdrole2)");
493 wc.
addNamedValue(
"cpdrole1", ParticipantRole.PARTICIPANT_OWNER);
494 wc.
addNamedValue(
"cpdrole2", ParticipantRole.PARTICIPANT_ASSISTANT);
496 CategoryResults.addParticipantAffiliance(wc,
"or",
getContact().
getId(),
"dossier");
506 return isMail() ?
"content/newsletter/sections/dossiers" :
"dossier";
565 if(Strings.isBlank(path)) {
568 if(Strings.isBlank(path)) {
576 return "/user/my" + getTypePath() +
"s";
579 private String getTypePath() {
580 if(dossierTypes !=
null && dossierTypes.size() == 1 &&
void setShowSubject(boolean showSubject)
Object doDescriptionsCtrl(Dossier e)
Object doCommentsCtrl(Dossier e)
void setProjectPhases(List< String > projectPhases)
Object doInterestCtrl(Dossier e)
Object doFilesCtrl(Dossier e)
WhereClause getCountClause()
Object doPollsCtrl(Dossier e)
String getPendingWorths()
void setDossierTypes(List< String > dossierTypes)
void setCategoryId(long categoryId)
Object doAttachmentsCtrl(Dossier e)
Object doVotesCtrl(Dossier e)
VisualElements loadVisuals()
void setPhaseFilter(PhaseHtmlFilter phaseFilter)
boolean isValid(Dossier e)
void setAllowedCategories(String allowedCategories)
List< String > getProjectPhases()
void setPendingWorths(String pendingWorths)
String getRestrictedLink()
void setIssuePath(String issuePath)
void setDirect(boolean direct)
WhereClause getWhereClause()
Collection< String > metas(Dossier e)
void renderSummary(ElephantMarker marker, Dossier e, int page)
void renderItem(ElephantMarker marker, Dossier e, int page)
DossierContentIterator(IConstructor constructor, Writer writer, IContact contact, boolean mail, String pubPath)
PhaseHtmlFilter getPhaseFilter()
void setRelated(Collection< IContact > related)
String getItemLink(Dossier dossier)
Dossier entity(Long value)
void setDossierId(long dossierId)
void setDossierStatus(List< String > dossierStatus)
static String getObjectPath(Object object)
String getFullDescription()
ParticipantSet< IDossierParticipant > getFullParticipants()
static String getRootWebPath()
static String getContextVariable(IConstructor constructor)
static String getEntityWebContext(String path)
void addClause(String clause)
void addIn(String operator, String field, List values)
void addNamedValue(String name, Object value)
Set< RepositoryFile > getRepositoryFiles(String pattern)
static boolean hasImage(String url)
List< String > getMetas()
static IElephantEntity getController(String path)
Repository getPublishableRepository(IConstructor constructor)
static Statistics load(IConstructor constructor, String rankingInstance, String matchingInstance, WhereClause wc)
Object getSingleResultOrNull(SqlClause sc)
void prepareControls(E entity, int page)
String doItemLink(E entity, ID id, boolean obfuscated)
ID getIDFromURL(String root)
boolean isAllowMatching()
String getSummaryTemplate()
static DaoHtmlSearch getInstance(IConstructor constructor, String context)
boolean applyToQuery(WhereClause wc, List< String > fields, boolean withSynonyms)
void process(String rootTmpl, String tmpl)
Object put(Object key, Object value)
boolean isInRole(String role)
static DossierVisualElements load()
Object configureCtrl(Object ctrl, IContact contact)