BrightSide Workbench Full Report + Source Code
Tags.java
Go to the documentation of this file.
1 /*
2  * TurrĂ³ i Cutiller Foundation. License notice.
3  * Copyright (C) 2021 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.tags;
20 
21 import java.util.Arrays;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Optional;
27 import java.util.Set;
28 import java.util.stream.Collectors;
29 import org.turro.string.Strings;
30 import org.turro.action.Plugins;
31 import org.turro.elephant.db.ElephantPU;
32 import org.turro.elephant.db.WhereClause;
33 import org.turro.elephant.entities.db.Tag;
34 import org.turro.elephant.entities.db.TagPK;
35 import org.turro.entities.Entities;
36 import org.turro.jpa.Dao;
37 import org.turro.path.Path;
38 import org.turro.sql.SqlClause;
39 import org.turro.util.PhraseBuilder;
40 
45 public class Tags {
46 
47  public static TagSet search(String root, String value, int max) {
48  Dao dao = new ElephantPU();
49  WhereClause wc = new WhereClause();
50  wc.addClause("select new org.turro.tags.TagItem(t.tagName, count(t))");
51  wc.addClause("from Tag t");
52  wc.addClause("where t.entityPath like '/contact/%'");
53  if(!Strings.isBlank(root)) {
54  wc.addClause("and t.entityPath like concat('/', :root, '/%')");
55  wc.addNamedValue("root", root);
56  }
57  if(!Strings.isBlank(value)) {
58  wc.addLikeFields(new String[]{ "t.tagName" }, value.toString());
59  }
60  wc.addClause("group by t.tagName");
61  wc.addClause("order by t.tagName");
62  return new TagSet(dao.getResultList(wc, max));
63  }
64 
65  public static TagSet getAvailables() {
66  return getAvailables(null);
67  }
68 
69  public static TagSet getAvailables(String root) {
70  Dao dao = new ElephantPU();
71  WhereClause wc = new WhereClause();
72  wc.addClause("select new org.turro.tags.TagItem(t.tagName, count(t))");
73  wc.addClause("from Tag t");
74  if(!Strings.isBlank(root)) {
75  wc.addClause("where t.entityPath like concat('/', :root, '/%')");
76  wc.addNamedValue("root", root);
77  }
78  wc.addClause("group by t.tagName");
79  return new TagSet(dao.getResultList(wc));
80  }
81 
82  public static TagSet getSiblings(Set<String> tagNames) {
83  return getSiblings(null, tagNames);
84  }
85 
86  public static TagSet getSiblings(String root, Set<String> tagNames) {
87  Dao dao = new ElephantPU();
88  TagSet finalSet = null;
89  for(String tag : tagNames) {
90  TagSet set = getSiblings(dao, root, tag);
91  if(finalSet != null) {
92  finalSet.retainAll(set);
93  } else {
94  finalSet = set;
95  }
96  }
97  return Optional.ofNullable(finalSet).orElseGet(() -> TagSet.empty());
98  }
99 
100  private static TagSet getSiblings(Dao dao, String root, String tagName) {
101  WhereClause wc = new WhereClause();
102  wc.addClause("select new org.turro.tags.TagItem(t.tagName, count(t))");
103  wc.addClause("from Tag t");
104  wc.addClause("join Tag t1 on t.entityPath = t1.entityPath");
105  wc.addClause("where t.tagName <> :tag");
106  wc.addClause("and t1.tagName = :tag");
107  wc.addNamedValue("tag", tagName);
108  if(!Strings.isBlank(root)) {
109  wc.addClause("and t.entityPath like concat('/', :root, '/%')");
110  wc.addNamedValue("root", root);
111  }
112  wc.addClause("group by t.tagName");
113  return new TagSet(dao.getResultList(wc));
114  }
115 
116  public static List<TagItem> getAsItemFrom(String entityPath) {
117  return getFrom(entityPath).stream().map(s -> new TagItem(s.getTagName(), 0)).collect(Collectors.toList());
118  }
119 
120  public static List<Tag> getFrom(String entityPath) {
121  Dao dao = new ElephantPU();
122  WhereClause wc = new WhereClause();
123  wc.addClause("select t from Tag t");
124  wc.addClause("where t.entityPath = :path");
125  wc.addNamedValue("path", entityPath);
126  wc.addClause("order by t.tagName");
127  return dao.getResultList(wc);
128  }
129 
130  public static List<Tag> getFromRoot(String root) {
131  Dao dao = new ElephantPU();
132  WhereClause wc = new WhereClause();
133  wc.addClause("select t from Tag t");
134  wc.addClause("where t.entityPath like :path");
135  wc.addNamedValue("path", root + "%");
136  wc.addClause("order by t.tagName");
137  return dao.getResultList(wc);
138  }
139 
140  public static boolean existsTag(String tagName) {
141  Dao dao = new ElephantPU();
142  return ((Long) dao.getSingleResult(
143  " select count(*) from Tag " +
144  " where tagName = ?",
145  new Object[] { tagName }
146  )) > 0;
147  }
148 
149  public static void setTags(Object entity, String tags) {
150  setTags(Entities.getController(entity).getPath(), tags);
151  }
152 
153  public static void setTags(String entityPath, String tags) {
154  if(Strings.isBlank(tags)) {
155  removeTags(entityPath);
156  } else {
157  setTags(entityPath, Arrays.asList(tags.split("\\s*,\\s*")));
158  }
159  }
160 
161  public static void setTags(Object entity, Collection<String> tags) {
162  setTags(Entities.getController(entity).getPath(), tags);
163  }
164 
165  public static void setTags(String entityPath, Collection<String> tags) {
166  if(tags == null || tags.isEmpty()) {
167  removeTags(entityPath);
168  } else {
169  removeTags(entityPath);
170  for(String tag : tags) {
171  addTag(entityPath, tag);
172  }
173  }
174  }
175 
176  public static boolean hasTag(Object entity, String tagName) {
177  return hasTag(Entities.getController(entity).getPath(), tagName);
178  }
179 
180  public static boolean hasTag(String entityPath, String tagName) {
181  return hasTag(new ElephantPU(), entityPath, tagName);
182  }
183 
184  public static boolean hasTag(Dao dao, String entityPath, String tagName) {
185  return getTag(dao, entityPath, tagName) != null;
186  }
187 
188  public static void addTag(Object entity, String tagName) {
189  addTag(Entities.getController(entity).getPath(), tagName);
190  }
191 
192  public static void addTag(String entityPath, String tagName) {
193  Dao dao = new ElephantPU();
194  if(!hasTag(dao, entityPath, tagName)) {
195  Tag tag = new Tag();
196  tag.setEntityPath(entityPath);
197  tag.setTagName(tagName);
198  if(!tag.isEmpty()) dao.saveObject(tag);
199  }
200  }
201 
202  public static void changeTag(String entityPath, String oldName, String newName) {
203  Dao dao = new ElephantPU();
204  WhereClause wc = new WhereClause();
205  wc.addClause("update Tag");
206  wc.addClause("set tagName = :newtag");
207  wc.addNamedValue("newtag", newName);
208  wc.addClause("where entityPath = :path");
209  wc.addNamedValue("path", entityPath);
210  wc.addClause("and tagName = :oldtag");
211  wc.addNamedValue("oldtag", oldName);
212  dao.executeUpdate(wc);
213  }
214 
215  public static void removeTag(Object entity, String tagName) {
216  removeTag(Entities.getController(entity).getPath(), tagName);
217  }
218 
219  public static void removeTag(String entityPath, String tagName) {
220  Dao dao = new ElephantPU();
221  Tag tag = getTag(dao, entityPath, tagName);
222  if(tag != null) {
223  dao.deleteObject(tag);
224  }
225  }
226 
227  public static Tag getTag(Dao dao, String entityPath, String tagName) {
228  TagPK tagPk = new TagPK();
229  tagPk.setEntityPath(entityPath);
230  tagPk.setTagName(tagName);
231  return dao.find(Tag.class, tagPk);
232  }
233 
234  public static List<String> getIdentifiers(String root, Set<TagItem> set) {
235  return getIdentifiers(new ElephantPU(), root, set);
236  }
237 
238  public static List<String> getIdentifiers(Dao dao, String root, Set<TagItem> set) {
239  return getEntityPaths(dao, root, set).stream().map(s -> Path.getIdentifier(s)).collect(Collectors.toList());
240  }
241 
242  public static List<String> getEntityPaths(String root, Set<TagItem> set) {
243  return getEntityPaths(new ElephantPU(), root, set);
244  }
245 
246  public static List<String> getEntityPaths(Dao dao, String root, Set<TagItem> set) {
247  List<String> tags = set.stream().map(t -> t.getTagName()).collect(Collectors.toList());
248  if(!tags.isEmpty()) {
249  WhereClause wc = new WhereClause();
250  wc.addClause("select distinct t.entityPath from Tag t");
251  wc.addClause("where 1=1");
252  if(!Strings.isBlank(root)) {
253  wc.addClause("and t.entityPath like concat('/', :root, '/%')");
254  wc.addNamedValue("root", root);
255  }
256  int count = 0;
257  for(String tag : tags) {
258  wc.addClause("and exists (");
259  wc.addClause("select t2.entityPath from Tag t2");
260  wc.addClause("where t2.entityPath = t.entityPath");
261  wc.addClause("and t2.tagName = :tag" + count);
262  wc.addNamedValue("tag" + count, tag);
263  wc.addClause(")");
264  count++;
265  }
266  return dao.getResultList(String.class, wc);
267  }
268  return Collections.EMPTY_LIST;
269  }
270 
271  public static List<String> getIdentifiers(Dao dao, String root, List<TagSet> sets) {
272  return getEntityPaths(dao, root, sets).stream().map(s -> Path.getIdentifier(s)).collect(Collectors.toList());
273  }
274 
275  public static List<String> getEntityPaths(String root, List<TagSet> sets) {
276  return getEntityPaths(new ElephantPU(), root, sets);
277  }
278 
279  public static List<String> getEntityPaths(Dao dao, String root, List<TagSet> sets) {
280  WhereClause wc = new WhereClause();
281  wc.addClause("select distinct t.entityPath from Tag t");
282  wc.addClause("where 1=1");
283  if(!Strings.isBlank(root)) {
284  wc.addClause("and t.entityPath like concat('/', :root, '/%')");
285  wc.addNamedValue("root", root);
286  }
287  addResultCriteria(wc, sets);
288  return dao.getResultList(String.class, wc);
289  }
290 
291  public static void addResultCriteria(WhereClause wc, List<TagSet> sets) {
292  wc.addClause("and (");
293  String orSep = "";
294  int count = 0;
295  for(Set<TagItem> set : sets) {
296  wc.addClause(orSep + "(");
297  String andSep = "";
298  List<String> tags = set.stream().map(t -> t.getTagName()).collect(Collectors.toList());
299  if(!tags.isEmpty()) {
300  for(String tag : tags) {
301  wc.addClause(andSep + "exists (");
302  wc.addClause("select t2.entityPath from Tag t2");
303  wc.addClause("where t2.entityPath = t.entityPath");
304  wc.addClause("and t2.tagName = :tag" + count);
305  wc.addNamedValue("tag" + count, tag);
306  wc.addClause(")");
307  count++;
308  andSep = "and ";
309  }
310  }
311  wc.addClause(")");
312  orSep = "or ";
313  }
314  wc.addClause(")");
315  }
316 
317  public static List<String> getCommonIdentifiers(String source, String rootTarget) {
318  return getCommonEntityPaths(source, rootTarget).stream().map(s -> Path.getIdentifier(s)).collect(Collectors.toList());
319  }
320 
321  public static List<Long> getCommonLongIdentifiers(String source, String rootTarget) {
322  return getCommonEntityPaths(source, rootTarget).stream().map(s -> Path.getLongIdentifier(s)).collect(Collectors.toList());
323  }
324 
325  public static List<String> getCommonEntityPaths(String source, String rootTarget) {
326  return getCommonEntityPaths(new ElephantPU(), source, rootTarget);
327  }
328 
329  public static List<String> getCommonIdentifiers(Dao dao, String source, String rootTarget) {
330  return getCommonEntityPaths(dao, source, rootTarget).stream().map(s -> Path.getIdentifier(s)).collect(Collectors.toList());
331  }
332 
333  public static List<Long> getCommonLongIdentifiers(Dao dao, String source, String rootTarget) {
334  return getCommonEntityPaths(dao, source, rootTarget).stream().map(s -> Path.getLongIdentifier(s)).collect(Collectors.toList());
335  }
336 
337  public static List<String> getCommonEntityPaths(Dao dao, String source, String rootTarget) {
338  WhereClause wc = new WhereClause();
339  wc.addClause("select distinct t.entityPath from Tag t");
340  wc.addClause("where t.entityPath like concat('/', :target, '/%')");
341  wc.addNamedValue("target", rootTarget);
342  wc.addClause("and exists (");
343  wc.addClause("select t2.entityPath from Tag t2");
344  wc.addClause("where t2.entityPath = :source");
345  wc.addNamedValue("source", source);
346  wc.addClause("and t2.tagName = t.tagName");
347  wc.addClause(")");
348  return dao.getResultList(String.class, wc);
349  }
350 
351  public static TagSet getTags(Object entity) {
352  return getTags(Entities.getController(entity).getPath());
353  }
354 
355  public static TagSet getTags(String entityPath) {
356  Dao dao = new ElephantPU();
357  WhereClause wc = new WhereClause();
358  wc.addClause("select new org.turro.tags.TagItem(t.tagName, count(t))");
359  wc.addClause("from Tag t");
360  wc.addClause("where t.entityPath = :path");
361  wc.addNamedValue("path", entityPath);
362  wc.addClause("group by t.tagName");
363  return new TagSet(dao.getResultList(wc));
364  }
365 
366  public static void removeTags(Object entity) {
368  }
369 
370  public static void removeTags(String entityPath) {
371  Dao dao = new ElephantPU();
372  WhereClause wc = new WhereClause();
373  wc.addClause("delete from Tag");
374  wc.addClause("where entityPath = :path");
375  wc.addNamedValue("path", entityPath);
376  dao.executeUpdate(wc);
377  }
378 
379  public static void removeTags(String root, List<String> tags) {
380  Dao dao = new ElephantPU();
381  WhereClause wc = new WhereClause();
382  wc.addClause("delete from Tag");
383  wc.addClause("where entityPath like :path");
384  wc.addIn("and", "tagName", tags);
385  wc.addNamedValue("path", "/" + root + "/%");
386  dao.executeUpdate(wc);
387  }
388 
389  public static void removeMemberTags(long member) {
390  Dao dao = new ElephantPU();
391  WhereClause wc = new WhereClause();
392  wc.addClause("delete from Tag");
393  wc.addClause("where entityPath like :path");
394  wc.addNamedValue("path", "/%/%##" + member);
395  dao.executeUpdate(wc);
396  }
397 
398  public static Collection<String> tagChoices(Object entity) {
399  return tagChoices(Entities.getController(entity).getPath());
400  }
401 
402  public static Collection<String> tagChoices(String entityPath) {
403  Dao dao = new ElephantPU();
404  return dao.getResultList(
405  " select distinct tagName from Tag " +
406  " where entityPath <> ?",
407  new Object[] { entityPath }
408  );
409  }
410 
411  public static ITagCtrl getControl(Object entity) {
412  if(entity == null) return null;
413  ITagCtrl ctrl = Plugins.loadImplementation(ITagCtrl.class, "tag-label");
414  ctrl.setEntity(entity);
415  ctrl.updateControls();
416  return ctrl;
417  }
418 
419  public static String tagsString(Object entity) {
420  return tagsString(Entities.getController(entity).getPath());
421  }
422 
423  public static String tagsString(String entityPath) {
424  PhraseBuilder pb = new PhraseBuilder();
425  for(String tag : getTags(entityPath).getTagNames()) {
426  pb.addWord(tag);
427  pb.addPendingSeparator(",");
428  }
429  return pb.toString();
430  }
431 
432  /* Utils */
433 
434  public static Set<String> getAllPaths(String root) {
435  return new HashSet<>(SqlClause.select("distinct t.entityPath").from("Tag t")
436  .where().startsWith("t.entityPath", "/" + root + "/")
437  .dao(new ElephantPU())
438  .resultList(String.class));
439  }
440 
441  private Tags() {}
442 
443 }
static< T > T loadImplementation(Class< T > jclass)
Definition: Plugins.java:57
void addLikeFields(String[] fields, String value)
void addIn(String operator, String field, List values)
void addNamedValue(String name, Object value)
void setEntityPath(String entityPath)
Definition: TagPK.java:45
void setTagName(String tagName)
Definition: TagPK.java:37
void setTagName(String tagName)
Definition: Tag.java:51
void setEntityPath(String entityPath)
Definition: Tag.java:59
static IElephantEntity getController(String path)
Definition: Entities.java:78
void deleteObject(Object obj)
Definition: Dao.java:162
int executeUpdate(String query)
Definition: Dao.java:463
Object getSingleResult(WhereClause wc)
Definition: Dao.java:380
static TagSet empty()
Definition: TagSet.java:131
static TagSet getTags(String entityPath)
Definition: Tags.java:355
static void setTags(String entityPath, String tags)
Definition: Tags.java:153
static void removeTags(String root, List< String > tags)
Definition: Tags.java:379
static List< String > getIdentifiers(String root, Set< TagItem > set)
Definition: Tags.java:234
static List< String > getCommonEntityPaths(String source, String rootTarget)
Definition: Tags.java:325
static List< Long > getCommonLongIdentifiers(String source, String rootTarget)
Definition: Tags.java:321
static void setTags(String entityPath, Collection< String > tags)
Definition: Tags.java:165
static TagSet getSiblings(String root, Set< String > tagNames)
Definition: Tags.java:86
static ITagCtrl getControl(Object entity)
Definition: Tags.java:411
static Collection< String > tagChoices(String entityPath)
Definition: Tags.java:402
static List< Long > getCommonLongIdentifiers(Dao dao, String source, String rootTarget)
Definition: Tags.java:333
static void addTag(Object entity, String tagName)
Definition: Tags.java:188
static void removeTag(Object entity, String tagName)
Definition: Tags.java:215
static void setTags(Object entity, Collection< String > tags)
Definition: Tags.java:161
static List< String > getCommonEntityPaths(Dao dao, String source, String rootTarget)
Definition: Tags.java:337
static void addResultCriteria(WhereClause wc, List< TagSet > sets)
Definition: Tags.java:291
static TagSet search(String root, String value, int max)
Definition: Tags.java:47
static List< String > getEntityPaths(Dao dao, String root, List< TagSet > sets)
Definition: Tags.java:279
static List< String > getEntityPaths(Dao dao, String root, Set< TagItem > set)
Definition: Tags.java:246
static void removeTags(Object entity)
Definition: Tags.java:366
static void removeMemberTags(long member)
Definition: Tags.java:389
static boolean existsTag(String tagName)
Definition: Tags.java:140
static TagSet getSiblings(Set< String > tagNames)
Definition: Tags.java:82
static List< String > getEntityPaths(String root, Set< TagItem > set)
Definition: Tags.java:242
static String tagsString(String entityPath)
Definition: Tags.java:423
static Tag getTag(Dao dao, String entityPath, String tagName)
Definition: Tags.java:227
static boolean hasTag(String entityPath, String tagName)
Definition: Tags.java:180
static void setTags(Object entity, String tags)
Definition: Tags.java:149
static boolean hasTag(Object entity, String tagName)
Definition: Tags.java:176
static List< String > getCommonIdentifiers(String source, String rootTarget)
Definition: Tags.java:317
static TagSet getTags(Object entity)
Definition: Tags.java:351
static List< String > getIdentifiers(Dao dao, String root, Set< TagItem > set)
Definition: Tags.java:238
static void removeTag(String entityPath, String tagName)
Definition: Tags.java:219
static List< String > getEntityPaths(String root, List< TagSet > sets)
Definition: Tags.java:275
static List< Tag > getFromRoot(String root)
Definition: Tags.java:130
static Set< String > getAllPaths(String root)
Definition: Tags.java:434
static TagSet getAvailables()
Definition: Tags.java:65
static boolean hasTag(Dao dao, String entityPath, String tagName)
Definition: Tags.java:184
static void addTag(String entityPath, String tagName)
Definition: Tags.java:192
static void changeTag(String entityPath, String oldName, String newName)
Definition: Tags.java:202
static void removeTags(String entityPath)
Definition: Tags.java:370
static List< Tag > getFrom(String entityPath)
Definition: Tags.java:120
static List< String > getCommonIdentifiers(Dao dao, String source, String rootTarget)
Definition: Tags.java:329
static List< TagItem > getAsItemFrom(String entityPath)
Definition: Tags.java:116
static String tagsString(Object entity)
Definition: Tags.java:419
static List< String > getIdentifiers(Dao dao, String root, List< TagSet > sets)
Definition: Tags.java:271
static Collection< String > tagChoices(Object entity)
Definition: Tags.java:398
static TagSet getAvailables(String root)
Definition: Tags.java:69
void setEntity(Object entity)