Bookmarks: Add owner bookmark pages (~{user}, ~{user}/feed).
Change-Id: I04395a6454d8c187e23683db72100f49b80fc655
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/accesscontrol/Role.java b/src/main/java/eu/mulk/mulkcms2/benki/accesscontrol/Role.java
index 4bfba8e..f35fc6c 100644
--- a/src/main/java/eu/mulk/mulkcms2/benki/accesscontrol/Role.java
+++ b/src/main/java/eu/mulk/mulkcms2/benki/accesscontrol/Role.java
@@ -74,4 +74,8 @@
@CollectionTable(name = "role_tags", schema = "benki", joinColumns = @JoinColumn(name = "role"))
@Column(name = "tag")
public Set<String> tags;
+
+ public static Role getWorld() {
+ return find("from Role r join r.tags tag where tag = 'world'").singleResult();
+ }
}
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java b/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java
index 3219f57..53b7ddc 100644
--- a/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java
+++ b/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java
@@ -13,8 +13,6 @@
import com.rometools.rome.io.WireFeedOutput;
import eu.mulk.mulkcms2.benki.accesscontrol.Role;
import eu.mulk.mulkcms2.benki.users.User;
-import io.quarkus.hibernate.orm.panache.PanacheQuery;
-import io.quarkus.panache.common.Sort;
import io.quarkus.qute.Template;
import io.quarkus.qute.TemplateExtension;
import io.quarkus.qute.TemplateInstance;
@@ -36,9 +34,15 @@
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.json.JsonObject;
import javax.json.spi.JsonProvider;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.From;
+import javax.persistence.criteria.JoinType;
import javax.transaction.Transactional;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@@ -48,12 +52,14 @@
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.eclipse.microprofile.config.inject.ConfigProperty;
+import org.hibernate.Session;
import org.jboss.logging.Logger;
import org.jsoup.Jsoup;
@@ -85,20 +91,45 @@
@ConfigProperty(name = "mulkcms.tag-base")
String tagBase;
+ @PersistenceContext EntityManager entityManager;
+
@GET
@Produces(TEXT_HTML)
public TemplateInstance getIndex() {
- var bookmarkQuery = bookmarkQuery();
+ var bookmarkQuery = selectBookmarks(null);
return bookmarkList
- .data("bookmarks", bookmarkQuery.list())
+ .data("bookmarks", bookmarkQuery)
+ .data("authenticated", !identity.isAnonymous());
+ }
+
+ @GET
+ @Path("~{ownerName}")
+ @Produces(TEXT_HTML)
+ public TemplateInstance getUserIndex(@PathParam("ownerName") String ownerName) {
+ var owner = User.findByNickname(ownerName);
+ var bookmarkQuery = selectBookmarks(owner);
+ return bookmarkList
+ .data("bookmarks", bookmarkQuery)
.data("authenticated", !identity.isAnonymous());
}
@GET
@Path("feed")
@Produces(APPLICATION_ATOM_XML)
- public String getFeed() throws FeedException {
- var bookmarks = bookmarkQuery().list();
+ public String getFeed(@Nullable User owner) throws FeedException {
+ return makeFeed(null);
+ }
+
+ @GET
+ @Path("~{ownerName}/feed")
+ @Produces(APPLICATION_ATOM_XML)
+ public String getUserFeed(@PathParam("ownerName") String ownerName) throws FeedException {
+ var owner = User.findByNickname(ownerName);
+ return makeFeed(owner);
+ }
+
+ private String makeFeed(@Nullable User owner) throws FeedException {
+ var bookmarks = selectBookmarks(owner);
var feed = new Feed("atom_1.0");
feed.setTitle("Book Marx");
@@ -185,8 +216,7 @@
throws URISyntaxException {
var userName = identity.getPrincipal().getName();
- User user =
- User.find("from BenkiUser u join u.nicknames n where ?1 = n", userName).singleResult();
+ var user = User.findByNickname(userName);
var bookmark = new Bookmark();
bookmark.uri = uri.toString();
@@ -229,21 +259,38 @@
return htmlDateFormatter.format(x);
}
- private PanacheQuery<Bookmark> bookmarkQuery() {
+ private List<Bookmark> selectBookmarks(@Nullable User owner) {
+ var cb = entityManager.unwrap(Session.class).getCriteriaBuilder();
+
+ CriteriaQuery<Bookmark> query = cb.createQuery(Bookmark.class);
+
+ From<?, Bookmark> bm;
if (identity.isAnonymous()) {
- Role world = Role.find("from Role r join r.tags tag where tag = 'world'").singleResult();
- return Bookmark.find(
- "select bm from Bookmark bm join bm.targets target left join fetch bm.owner where target = ?1",
- Sort.by("date").descending(),
- world);
+ var root = query.from(Bookmark.class);
+ bm = root;
+ query.select(root);
+ root.fetch("owner", JoinType.LEFT);
+
+ var target = root.join("targets");
+ query.where(cb.equal(target, Role.getWorld()));
} else {
var userName = identity.getPrincipal().getName();
- User user =
- User.find("from BenkiUser u join u.nicknames n where ?1 = n", userName).singleResult();
- return Bookmark.find(
- "select bm from BenkiUser u inner join u.visibleBookmarks bm left join fetch bm.owner where u.id = ?1",
- Sort.by("date").descending(),
- user.id);
+ var user = User.findByNickname(userName);
+
+ var root = query.from(User.class);
+ query.where(cb.equal(root, user));
+ bm = root.join("visibleBookmarks");
+ bm.fetch("owner", JoinType.LEFT);
}
+
+ query.orderBy(cb.desc(bm.get("date")));
+
+ if (owner != null) {
+ query.where(cb.equal(bm.get("owner"), owner));
+ }
+
+ var q = entityManager.createQuery(query);
+ log.debug(q.unwrap(org.hibernate.query.Query.class).getQueryString());
+ return q.getResultList();
}
}
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/users/User.java b/src/main/java/eu/mulk/mulkcms2/benki/users/User.java
index 71f6c43..6587ec4 100644
--- a/src/main/java/eu/mulk/mulkcms2/benki/users/User.java
+++ b/src/main/java/eu/mulk/mulkcms2/benki/users/User.java
@@ -137,4 +137,8 @@
public String getFirstAndLastName() {
return String.format("%s %s", firstName, lastName);
}
+
+ public static User findByNickname(String nickname) {
+ return User.find("from BenkiUser u join u.nicknames n where ?1 = n", nickname).singleResult();
+ }
}