blob: 502cb0dd01e329efc44e9a3c9229afbe755d020a [file] [log] [blame]
Matthias Andreas Benkardd9b95882020-01-24 11:42:49 +01001package eu.mulk.mulkcms2.benki.generic;
Matthias Andreas Benkard734879e2020-01-24 10:47:37 +01002
Matthias Andreas Benkard2d4f92e2020-02-09 16:15:07 +01003import eu.mulk.mulkcms2.benki.accesscontrol.Role;
Matthias Andreas Benkardf5999552020-03-22 06:52:06 +01004import eu.mulk.mulkcms2.benki.bookmarks.Bookmark;
5import eu.mulk.mulkcms2.benki.lazychat.LazychatMessage;
Matthias Andreas Benkardd9b95882020-01-24 11:42:49 +01006import eu.mulk.mulkcms2.benki.users.User;
Matthias Andreas Benkardf5999552020-03-22 06:52:06 +01007import eu.mulk.mulkcms2.benki.users.User_;
Matthias Andreas Benkard35cb1592020-01-24 11:05:20 +01008import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
Matthias Andreas Benkardf5999552020-03-22 06:52:06 +01009import io.quarkus.security.identity.SecurityIdentity;
Matthias Andreas Benkardd9b95882020-01-24 11:42:49 +010010import java.time.OffsetDateTime;
Matthias Andreas Benkardf5999552020-03-22 06:52:06 +010011import java.util.ArrayList;
Matthias Andreas Benkardf9c74272020-01-24 11:51:35 +010012import java.util.Set;
Matthias Andreas Benkardf5999552020-03-22 06:52:06 +010013import javax.annotation.CheckForNull;
Matthias Andreas Benkard734879e2020-01-24 10:47:37 +010014import javax.persistence.Column;
15import javax.persistence.Entity;
Matthias Andreas Benkardf9c74272020-01-24 11:51:35 +010016import javax.persistence.FetchType;
Matthias Andreas Benkard0246c3e2020-01-27 05:39:08 +010017import javax.persistence.GeneratedValue;
18import javax.persistence.GenerationType;
Matthias Andreas Benkard734879e2020-01-24 10:47:37 +010019import javax.persistence.Id;
Matthias Andreas Benkardd9b95882020-01-24 11:42:49 +010020import javax.persistence.Inheritance;
21import javax.persistence.InheritanceType;
Matthias Andreas Benkard734879e2020-01-24 10:47:37 +010022import javax.persistence.JoinColumn;
Matthias Andreas Benkardf9c74272020-01-24 11:51:35 +010023import javax.persistence.JoinTable;
24import javax.persistence.ManyToMany;
Matthias Andreas Benkard734879e2020-01-24 10:47:37 +010025import javax.persistence.ManyToOne;
Matthias Andreas Benkard0246c3e2020-01-27 05:39:08 +010026import javax.persistence.SequenceGenerator;
Matthias Andreas Benkard734879e2020-01-24 10:47:37 +010027import javax.persistence.Table;
Matthias Andreas Benkardf5999552020-03-22 06:52:06 +010028import javax.persistence.criteria.CriteriaBuilder;
29import javax.persistence.criteria.CriteriaQuery;
30import javax.persistence.criteria.From;
31import javax.persistence.criteria.JoinType;
32import javax.persistence.criteria.Predicate;
Matthias Andreas Benkard734879e2020-01-24 10:47:37 +010033
34@Entity
Matthias Andreas Benkard57c9a8a2020-01-24 19:09:38 +010035@Table(name = "posts", schema = "benki")
Matthias Andreas Benkardd9b95882020-01-24 11:42:49 +010036@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
37public abstract class Post extends PanacheEntityBase {
Matthias Andreas Benkard734879e2020-01-24 10:47:37 +010038
39 @Id
Matthias Andreas Benkard0246c3e2020-01-27 05:39:08 +010040 @SequenceGenerator(
41 allocationSize = 1,
42 sequenceName = "posts_id_seq",
43 name = "posts_id_seq",
44 schema = "benki")
45 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "posts_id_seq")
Matthias Andreas Benkard734879e2020-01-24 10:47:37 +010046 @Column(name = "id", nullable = false)
Matthias Andreas Benkard0246c3e2020-01-27 05:39:08 +010047 public Integer id;
Matthias Andreas Benkard734879e2020-01-24 10:47:37 +010048
Matthias Andreas Benkard734879e2020-01-24 10:47:37 +010049 @Column(name = "date", nullable = true)
Matthias Andreas Benkardd9b95882020-01-24 11:42:49 +010050 public OffsetDateTime date;
Matthias Andreas Benkard734879e2020-01-24 10:47:37 +010051
Matthias Andreas Benkardaa754802020-01-24 11:55:26 +010052 @ManyToOne(fetch = FetchType.LAZY)
Matthias Andreas Benkard734879e2020-01-24 10:47:37 +010053 @JoinColumn(name = "owner", referencedColumnName = "id")
Matthias Andreas Benkard35cb1592020-01-24 11:05:20 +010054 public User owner;
Matthias Andreas Benkardf9c74272020-01-24 11:51:35 +010055
56 @ManyToMany(fetch = FetchType.LAZY)
57 @JoinTable(
58 name = "user_visible_posts",
Matthias Andreas Benkard553de3e2020-01-27 05:33:15 +010059 schema = "benki",
Matthias Andreas Benkardf9c74272020-01-24 11:51:35 +010060 joinColumns = @JoinColumn(name = "message"),
61 inverseJoinColumns = @JoinColumn(name = "user"))
62 public Set<User> visibleTo;
Matthias Andreas Benkard2d4f92e2020-02-09 16:15:07 +010063
64 @ManyToMany(fetch = FetchType.LAZY)
65 @JoinTable(
66 name = "post_targets",
67 schema = "benki",
68 joinColumns = @JoinColumn(name = "message"),
69 inverseJoinColumns = @JoinColumn(name = "target"))
70 public Set<Role> targets;
Matthias Andreas Benkardf5999552020-03-22 06:52:06 +010071
72 public static <T extends Post> CriteriaQuery<T> findViewable(
73 Class<T> entityClass,
74 SecurityIdentity readerIdentity,
75 @CheckForNull User owner,
76 @CheckForNull Integer cursor,
77 CriteriaBuilder cb,
78 boolean forward) {
79 CriteriaQuery<T> query = cb.createQuery(entityClass);
80
81 var conditions = new ArrayList<Predicate>();
82
83 From<?, T> post;
84 if (readerIdentity.isAnonymous()) {
85 post = query.from(entityClass);
86 var target = post.join(Post_.targets);
87 conditions.add(cb.equal(target, Role.getWorld()));
88 } else {
89 var userName = readerIdentity.getPrincipal().getName();
90 var user = User.findByNickname(userName);
91
92 var root = query.from(User.class);
93 conditions.add(cb.equal(root, user));
94 if (entityClass.isAssignableFrom(Bookmark.class)) {
95 post = (From<?, T>) root.join(User_.visibleBookmarks);
96 } else {
97 assert entityClass.isAssignableFrom(LazychatMessage.class) : entityClass;
98 post = (From<?, T>) root.join(User_.visibleLazychatMessages);
99 }
100 }
101
102 query.select(post);
103 post.fetch(Post_.owner, JoinType.LEFT);
104
105 if (owner != null) {
106 conditions.add(cb.equal(post.get(Post_.owner), owner));
107 }
108
109 if (forward) {
110 query.orderBy(cb.desc(post.get(Post_.id)));
111 } else {
112 query.orderBy(cb.asc(post.get(Post_.id)));
113 }
114
115 if (cursor != null) {
116 if (forward) {
117 conditions.add(cb.le(post.get(Post_.id), cursor));
118 } else {
119 conditions.add(cb.gt(post.get(Post_.id), cursor));
120 }
121 }
122
123 query.where(conditions.toArray(new Predicate[0]));
124
125 return query;
126 }
Matthias Andreas Benkard734879e2020-01-24 10:47:37 +0100127}