[jboss-cvs] jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/dao ...
Christian Bauer
christian at hibernate.org
Tue Dec 18 23:29:26 EST 2007
User: cbauer
Date: 07/12/18 23:29:26
Modified: examples/wiki/src/main/org/jboss/seam/wiki/core/dao
UserDAO.java TagDAO.java WikiNodeFactory.java
UserRoleAccessFactory.java
Added: examples/wiki/src/main/org/jboss/seam/wiki/core/dao
WikiNodeDAO.java
Removed: examples/wiki/src/main/org/jboss/seam/wiki/core/dao
NodeDAO.java FeedDAO.java WikiTreeNodeAdapter.java
Log:
Major rewrite of the most of the application
Revision Changes Path
1.10 +7 -1 jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/UserDAO.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: UserDAO.java
===================================================================
RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/UserDAO.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- UserDAO.java 25 Sep 2007 14:30:43 -0000 1.9
+++ UserDAO.java 19 Dec 2007 04:29:26 -0000 1.10
@@ -68,7 +68,8 @@
User adminUser = (User) Component.getInstance("adminUser");
- entityManager.createQuery("update Node n set n.createdBy = :admin where n.createdBy = :user")
+ //TODO: This needs to do much more work now that we can't have the FK names anymore in the @MappedSuperclass WikiNode. Hibernate sucks. Shit.
+ entityManager.createQuery("update WikiNode n set n.createdBy = :admin where n.createdBy = :user")
.setParameter("admin", entityManager.merge(adminUser))
.setParameter("user", user)
.executeUpdate();
@@ -96,6 +97,11 @@
private Criteria prepareExampleCriteria(User exampleUser, String orderByProperty, boolean orderDescending, String... ignoreProperty) {
Example example = Example.create(exampleUser).enableLike(MatchMode.ANYWHERE).ignoreCase();
+ // Sanitize input
+ if (orderByProperty != null) {
+ orderByProperty = orderByProperty.replaceAll("[^a-zA-Z0-9]", "");
+ }
+
for (String s : ignoreProperty) example.excludeProperty(s);
Session session = (Session)entityManager.getDelegate();
1.3 +55 -117 jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/TagDAO.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: TagDAO.java
===================================================================
RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/TagDAO.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- TagDAO.java 15 Nov 2007 12:53:32 -0000 1.2
+++ TagDAO.java 19 Dec 2007 04:29:26 -0000 1.3
@@ -1,20 +1,21 @@
package org.jboss.seam.wiki.core.dao;
-import org.jboss.seam.annotations.Name;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.hibernate.transform.Transformers;
import org.jboss.seam.annotations.AutoCreate;
-import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.In;
+import org.jboss.seam.annotations.Logger;
+import org.jboss.seam.annotations.Name;
import org.jboss.seam.log.Log;
-import org.jboss.seam.wiki.core.model.Node;
-import org.hibernate.Session;
-import org.hibernate.Query;
-import org.hibernate.transform.ResultTransformer;
+import org.jboss.seam.wiki.core.model.DisplayTagCount;
+import org.jboss.seam.wiki.core.model.WikiDirectory;
+import org.jboss.seam.wiki.core.model.WikiFile;
+import org.jboss.seam.wiki.core.nestedset.query.NestedSetQueryBuilder;
import javax.persistence.EntityManager;
-import java.util.List;
-import java.util.ArrayList;
import java.util.Collections;
-import java.io.Serializable;
+import java.util.List;
@Name("tagDAO")
@AutoCreate
@@ -26,131 +27,68 @@
@In
protected EntityManager restrictedEntityManager;
- public List<TagCount> findTagsAggregatedSorted(Node startNode, Node ignoreNode, int limit) {
- List<TagCount> tagsSortedByCount = new ArrayList<TagCount>();
- List<Node> taggedNodes = findNodes(startNode, ignoreNode, null);
- for (Node taggedNode : taggedNodes) {
- String[] splitTags = taggedNode.getTags().split(",");
- for (String splitTag : splitTags) {
- String tag = splitTag.trim();
-
- Integer count = 1;
- TagCount newTag = new TagCount(tag, count);
- if (tagsSortedByCount.contains(newTag)) {
- tagsSortedByCount.get(tagsSortedByCount.indexOf(newTag)).incrementCount();
- } else {
- tagsSortedByCount.add(newTag);
- }
- }
- }
- Collections.sort(tagsSortedByCount);
- if (limit != 0 && tagsSortedByCount.size() > limit)
- return tagsSortedByCount.subList(0, limit);
- else
- return tagsSortedByCount;
- }
-
- public List<Node> findNodes(Node startNode, Node ignoreNode, final String tag) {
+ public List<DisplayTagCount> findTagCounts(WikiDirectory startDir, WikiFile ignoreFile, int limit) {
StringBuilder queryString = new StringBuilder();
- queryString.append("select distinct n1").append(" ");
- queryString.append("from ").append(startNode.getTreeSuperclassEntityName()).append(" n1, ");
- queryString.append(startNode.getTreeSuperclassEntityName()).append(" n2 ");
- queryString.append("where n1.nsThread = :thread and n2.nsThread = :thread").append(" ");
- queryString.append("and n1.nsLeft between n2.nsLeft and n2.nsRight").append(" ");
- queryString.append("and n2.nsLeft > :startLeft and n2.nsRight < :startRight").append(" ");
- queryString.append("and n2.class = :clazz").append(" ");
-
- if (tag != null && tag.length()>0) {
- queryString.append("and n1.tags like :tag").append(" ");
- } else {
- queryString.append("and n1.tags is not null").append(" ");
- queryString.append("and length(n1.tags)>0").append(" ");
- }
-
- if (ignoreNode != null && ignoreNode.getId() != null)
- queryString.append("and not n1 = :ignoreNode").append(" ");
-
- queryString.append("order by n1.createdOn desc");
+ queryString.append("select t as tag, count(t) as count").append(" ");
+ queryString.append("from WikiFile f join f.tags as t").append(" ");
+ queryString.append("where f.parent.id in");
+ queryString.append("(").append(getNestedDirectoryQuery(startDir)).append(")").append(" ");
+ if (ignoreFile != null && ignoreFile.getId() != null) queryString.append("and not f = :ignoreFile").append(" ");
+ queryString.append("group by t").append(" ");
+ queryString.append("order by count(t) desc, t asc ");
Query nestedSetQuery = getSession().createQuery(queryString.toString());
- nestedSetQuery.setParameter("thread", startNode.getNsThread());
- nestedSetQuery.setParameter("startLeft", startNode.getNsLeft());
- nestedSetQuery.setParameter("startRight", startNode.getNsRight());
- nestedSetQuery.setParameter("clazz", "DOCUMENT"); // TODO: Hibernate can't bind the discriminator? Not even with Hibernate.CLASS type...
- if (ignoreNode != null && ignoreNode.getId() != null)
- nestedSetQuery.setParameter("ignoreNode", ignoreNode);
-
- if (tag != null && tag.length()>0) {
- nestedSetQuery.setParameter("tag", "%" + tag + "%");
- // These nodes have the tag _as a substring_ in their comma-separated tags list, we need to find
- // the real tags, narrowing down the list of nodes by checking each node again.
- nestedSetQuery.setResultTransformer(
- new ResultTransformer() {
- public Object transformTuple(Object[] result, String[] aliases) {
- Node node = (Node)result[0];
- if (node.isTagged(tag)) return node;
- return null;
- }
- public List transformList(List list) {
- List listWithoutNulls = new ArrayList();
- for (Object o : list) if (o != null) listWithoutNulls.add(o);
- return listWithoutNulls;
- }
- }
- );
+ nestedSetQuery.setParameter("nsThread", startDir.getNodeInfo().getNsThread());
+ nestedSetQuery.setParameter("nsLeft", startDir.getNodeInfo().getNsLeft());
+ nestedSetQuery.setParameter("nsRight", startDir.getNodeInfo().getNsRight());
+ if (ignoreFile != null && ignoreFile.getId() != null)
+ nestedSetQuery.setParameter("ignoreFile", ignoreFile);
+ if (limit > 0) {
+ nestedSetQuery.setMaxResults(limit);
}
- return nestedSetQuery.list();
-
- }
-
- private Session getSession() {
- return ((Session)((org.jboss.seam.persistence.EntityManagerProxy) restrictedEntityManager).getDelegate());
- }
+ nestedSetQuery.setResultTransformer(Transformers.aliasToBean(DisplayTagCount.class));
- public class TagCount implements Comparable, Serializable {
- String tag;
- Integer count;
-
- public TagCount(String tag, Integer count) {
- this.tag = tag;
- this.count = count;
- }
-
- public String getTag() {
- return tag;
+ return nestedSetQuery.list();
}
- public Integer getCount() {
- return count;
- }
+ public List<WikiFile> findWikFiles(WikiDirectory startDir, WikiFile ignoreFile, final String tag) {
- public void incrementCount() {
- count++;
- }
+ if (tag == null || tag.length() == 0) return Collections.emptyList();
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
+ StringBuilder queryString = new StringBuilder();
- TagCount tagCount = (TagCount) o;
+ queryString.append("select distinct f from WikiFile f join f.tags as t where f.parent.id in");
+ queryString.append("(").append(getNestedDirectoryQuery(startDir)).append(")").append(" ");
+ if (ignoreFile != null && ignoreFile.getId() != null) queryString.append("and not f = :ignoreFile").append(" ");
+ queryString.append("and t = :tag").append(" ");
+ queryString.append("order by f.createdOn desc");
- return tag.equals(tagCount.tag);
+ Query nestedSetQuery = getSession().createQuery(queryString.toString());
+ nestedSetQuery.setParameter("nsThread", startDir.getNodeInfo().getNsThread());
+ nestedSetQuery.setParameter("nsLeft", startDir.getNodeInfo().getNsLeft());
+ nestedSetQuery.setParameter("nsRight", startDir.getNodeInfo().getNsRight());
+ if (ignoreFile != null && ignoreFile.getId() != null)
+ nestedSetQuery.setParameter("ignoreFile", ignoreFile);
+ nestedSetQuery.setParameter("tag", tag);
+ return nestedSetQuery.list();
}
- public int hashCode() {
- return tag.hashCode();
+ private String getNestedDirectoryQuery(WikiDirectory dir) {
+ NestedSetQueryBuilder builder = new NestedSetQueryBuilder(dir, true);
+ StringBuilder queryString = new StringBuilder();
+ queryString.append("select distinct ").append(NestedSetQueryBuilder.NODE_ALIAS).append(".id").append(" ");
+ queryString.append("from ").append(builder.getFromClause()).append(" ");
+ queryString.append("where ").append(builder.getWhereClause()).append(" ");
+ return queryString.toString();
}
- public int compareTo(Object o) {
- int result = ((TagCount)o).getCount().compareTo( this.getCount() );
- return result == 0
- ? this.getTag().compareTo( ((TagCount)o).getTag() )
- : result;
- }
+ private Session getSession() {
+ return ((Session)((org.jboss.seam.persistence.EntityManagerProxy) restrictedEntityManager).getDelegate());
}
+
}
1.14 +30 -25 jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/WikiNodeFactory.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: WikiNodeFactory.java
===================================================================
RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/WikiNodeFactory.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- WikiNodeFactory.java 12 Oct 2007 16:31:26 -0000 1.13
+++ WikiNodeFactory.java 19 Dec 2007 04:29:26 -0000 1.14
@@ -6,21 +6,26 @@
*/
package org.jboss.seam.wiki.core.dao;
-import org.jboss.seam.annotations.*;
-import org.jboss.seam.ScopeType;
import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Factory;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.annotations.Name;
import org.jboss.seam.faces.FacesMessages;
-import org.jboss.seam.wiki.core.model.Directory;
-import org.jboss.seam.wiki.core.model.Document;
-import org.jboss.seam.wiki.core.model.LinkProtocol;
import org.jboss.seam.wiki.core.action.prefs.WikiPreferences;
+import org.jboss.seam.wiki.core.model.LinkProtocol;
+import org.jboss.seam.wiki.core.model.WikiDirectory;
+import org.jboss.seam.wiki.core.model.WikiDocument;
+import org.jboss.seam.wiki.util.WikiUtil;
+import javax.faces.application.FacesMessage;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.NoResultException;
-import javax.faces.application.FacesMessage;
import java.io.Serializable;
-import java.util.*;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
@Name("wikiNodeFactory")
public class WikiNodeFactory implements Serializable {
@@ -32,10 +37,10 @@
protected EntityManager restrictedEntityManager;
@Factory(value = "wikiRoot", scope = ScopeType.PAGE, autoCreate = true)
- public Directory loadWikiRoot() {
+ public WikiDirectory loadWikiRoot() {
try {
- return (Directory) entityManager
- .createQuery("select d from Directory d where d.parent is null")
+ return (WikiDirectory) entityManager
+ .createQuery("select d from WikiDirectory d where d.parent is null")
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (RuntimeException ex) {
@@ -44,11 +49,11 @@
}
@Factory(value = "wikiStart", scope = ScopeType.PAGE, autoCreate = true)
- public Document loadWikiStart() {
+ public WikiDocument loadWikiStart() {
WikiPreferences wikiPreferences = (WikiPreferences) Component.getInstance("wikiPreferences");
try {
- return (Document) restrictedEntityManager
- .createQuery("select d from Document d where d.id = :id")
+ return (WikiDocument) restrictedEntityManager
+ .createQuery("select d from WikiDocument d where d.id = :id")
.setParameter("id", wikiPreferences.getDefaultDocumentId())
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
@@ -57,17 +62,17 @@
}
// TODO: Message instead!
- throw new RuntimeException("Couldn't find default document with id '" + wikiPreferences.getDefaultDocumentId() +"'");
+ throw new RuntimeException("Couldn't find wiki default start document with id '" + wikiPreferences.getDefaultDocumentId() +"'");
}
// Loads the same instance into a different persistence context
@Factory(value = "restrictedWikiRoot", scope = ScopeType.PAGE, autoCreate = true)
- public Directory loadWikiRootRestricted() {
- Directory wikiroot = (Directory) Component.getInstance("wikiRoot");
+ public WikiDirectory loadWikiRootRestricted() {
+ WikiDirectory wikiroot = (WikiDirectory) Component.getInstance("wikiRoot");
try {
- return (Directory) restrictedEntityManager
- .createQuery("select d from Directory d where d.id = :id")
+ return (WikiDirectory) restrictedEntityManager
+ .createQuery("select d from WikiDirectory d where d.id = :id")
.setParameter("id", wikiroot.getId())
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
@@ -77,20 +82,20 @@
}
@Factory(value = "memberArea", scope = ScopeType.PAGE, autoCreate = true)
- public Directory loadMemberArea() {
- Long memberAreaId = ((WikiPreferences)Component.getInstance("wikiPreferences")).getMemberAreaId();
+ public WikiDirectory loadMemberArea() {
+ String memberAreaName = ((WikiPreferences)Component.getInstance("wikiPreferences")).getMemberArea();
try {
- return (Directory) entityManager
- .createQuery("select d from Directory d where d.id = :dirId and d.parent.parent is null")
- .setParameter("dirId", memberAreaId)
+ return (WikiDirectory) entityManager
+ .createQuery("select d from WikiDirectory d where d.wikiname = :name and d.parent.parent is null")
+ .setParameter("name", WikiUtil.convertToWikiName(memberAreaName) )
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (RuntimeException ex) {
FacesMessages.instance().addFromResourceBundleOrDefault(
FacesMessage.SEVERITY_ERROR,
"lacewiki.msg.MemberHomedirectoryNotFound",
- "Could not find member area with id {0} - your configuration is broken, please change it.",
- memberAreaId
+ "Could not find member area with name {0} - your configuration is broken, please change it.",
+ memberAreaName
);
return null;
}
1.7 +16 -21 jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/UserRoleAccessFactory.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: UserRoleAccessFactory.java
===================================================================
RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/UserRoleAccessFactory.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- UserRoleAccessFactory.java 25 Sep 2007 14:30:44 -0000 1.6
+++ UserRoleAccessFactory.java 19 Dec 2007 04:29:26 -0000 1.7
@@ -15,11 +15,6 @@
@Name("userRoleAccessFactory")
public class UserRoleAccessFactory implements Serializable {
- public static final String GUEST_USERNAME = "guest";
- public static final String ADMIN_USERNAME = "admin";
- public static final int GUESTROLE_ACCESSLEVEL = 0;
- public static final int ADMINROLE_ACCESSLEVEL = 1000;
-
@In
EntityManager entityManager;
@@ -28,17 +23,17 @@
try {
User guestUser =
(User) entityManager
- .createQuery("select u from User u left join fetch u.roles where u.username = '"+GUEST_USERNAME+"'")
+ .createQuery("select u from User u left join fetch u.roles where u.username = '"+User.GUEST_USERNAME+"'")
.getSingleResult();
if (guestUser.getRoles().size() > 1 || guestUser.getRoles().size() == 0) {
- throw new RuntimeException("Your '"+GUEST_USERNAME+"' user has none or more than one role assigned, illegal database state");
+ throw new RuntimeException("Your '"+User.GUEST_USERNAME+"' user has none or more than one role assigned, illegal database state");
}
- if (guestUser.getRoles().iterator().next().getAccessLevel() != GUESTROLE_ACCESSLEVEL) {
- throw new RuntimeException("Your '"+GUEST_USERNAME+"' user isn't assigned to the guest role (access level "+GUESTROLE_ACCESSLEVEL+")");
+ if (guestUser.getRoles().iterator().next().getAccessLevel() != Role.GUESTROLE_ACCESSLEVEL) {
+ throw new RuntimeException("Your '"+User.GUEST_USERNAME+"' user isn't assigned to the guest role (access level "+Role.GUESTROLE_ACCESSLEVEL+")");
}
return guestUser;
} catch (NoResultException ex) {
- throw new RuntimeException("You need to INSERT a user with username '"+GUEST_USERNAME+"' into the database");
+ throw new RuntimeException("You need to INSERT a user with username '"+User.GUEST_USERNAME+"' into the database");
}
}
@@ -48,17 +43,17 @@
try {
User adminUser =
(User) entityManager
- .createQuery("select u from User u left join fetch u.roles where u.username = '"+ADMIN_USERNAME+"'")
+ .createQuery("select u from User u left join fetch u.roles where u.username = '"+User.ADMIN_USERNAME+"'")
.getSingleResult();
if (adminUser.getRoles().size() > 1 || adminUser.getRoles().size() == 0) {
- throw new RuntimeException("Your '"+ADMIN_USERNAME+"' user has none or more than one role assigned, illegal database state");
+ throw new RuntimeException("Your '"+User.ADMIN_USERNAME+"' user has none or more than one role assigned, illegal database state");
}
- if (adminUser.getRoles().iterator().next().getAccessLevel() != ADMINROLE_ACCESSLEVEL) {
- throw new RuntimeException("Your '"+ADMIN_USERNAME+"' user isn't assigned to the admin role (access level "+ADMINROLE_ACCESSLEVEL+")");
+ if (adminUser.getRoles().iterator().next().getAccessLevel() != Role.ADMINROLE_ACCESSLEVEL) {
+ throw new RuntimeException("Your '"+User.ADMIN_USERNAME+"' user isn't assigned to the admin role (access level "+Role.ADMINROLE_ACCESSLEVEL+")");
}
return adminUser;
} catch (NoResultException ex) {
- throw new RuntimeException("You need to INSERT a user with username '"+ADMIN_USERNAME+"' into the database");
+ throw new RuntimeException("You need to INSERT a user with username '"+User.ADMIN_USERNAME+"' into the database");
}
}
@@ -66,10 +61,10 @@
public Role getGuestRole() {
try {
return (Role) entityManager
- .createQuery("select r from Role r where r.accessLevel = '"+GUESTROLE_ACCESSLEVEL+"'")
+ .createQuery("select r from Role r where r.accessLevel = '"+Role.GUESTROLE_ACCESSLEVEL+"'")
.getSingleResult();
} catch (NoResultException ex) {
- throw new RuntimeException("You need to INSERT a role with accesslevel '"+GUESTROLE_ACCESSLEVEL+"' (the guest role) into the database");
+ throw new RuntimeException("You need to INSERT a role with accesslevel '"+Role.GUESTROLE_ACCESSLEVEL+"' (the guest role) into the database");
}
}
@@ -77,10 +72,10 @@
public Role getAdminRole() {
try {
return (Role) entityManager
- .createQuery("select r from Role r where r.accessLevel = '"+ADMINROLE_ACCESSLEVEL+"'")
+ .createQuery("select r from Role r where r.accessLevel = '"+Role.ADMINROLE_ACCESSLEVEL+"'")
.getSingleResult();
} catch (NoResultException ex) {
- throw new RuntimeException("You need to INSERT a role with accesslevel '"+ADMINROLE_ACCESSLEVEL+"' (the admin role) into the database");
+ throw new RuntimeException("You need to INSERT a role with accesslevel '"+Role.ADMINROLE_ACCESSLEVEL+"' (the admin role) into the database");
}
}
@@ -118,7 +113,7 @@
.getResultList();
if (roles.size() < 2)
throw new RuntimeException("You need to INSERT at least two roles into the database, " +
- "with access level '"+GUESTROLE_ACCESSLEVEL+"' and '"+ADMINROLE_ACCESSLEVEL+"'");
+ "with access level '"+Role.GUESTROLE_ACCESSLEVEL+"' and '"+Role.ADMINROLE_ACCESSLEVEL+"'");
}
return roles;
}
@@ -163,7 +158,7 @@
Role.AccessLevel newAccessLevel =
new Role.AccessLevel(
role.getAccessLevel(),
- role.getAccessLevel() == ADMINROLE_ACCESSLEVEL
+ role.getAccessLevel() == Role.ADMINROLE_ACCESSLEVEL
? "Owner, " + role.getDisplayName()
: role.getDisplayName()
);
1.1 date: 2007/12/19 04:29:26; author: cbauer; state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/WikiNodeDAO.java
Index: WikiNodeDAO.java
===================================================================
package org.jboss.seam.wiki.core.dao;
import org.hibernate.Session;
import org.hibernate.transform.ResultTransformer;
import org.jboss.seam.Component;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.log.Log;
import org.jboss.seam.wiki.core.model.*;
import org.jboss.seam.wiki.core.nestedset.NestedSetNode;
import org.jboss.seam.wiki.core.nestedset.query.NestedSetDuplicator;
import org.jboss.seam.wiki.core.nestedset.query.NestedSetNodeWrapper;
import org.jboss.seam.wiki.core.nestedset.query.NestedSetQueryBuilder;
import org.jboss.seam.wiki.core.nestedset.query.NestedSetResultTransformer;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.NoResultException;
import java.util.*;
/**
* DAO for nodes, transparently respects security access levels.
* <p>
* All node access should go through this component, this component knows
* about access levels because it relies on a restricted (filtered) Entitymanager.
*
* @author Christian Bauer
*
*/
@Name("wikiNodeDAO")
@AutoCreate
public class WikiNodeDAO {
@Logger
static Log log;
// Most of the DAO methods use this
@In protected EntityManager restrictedEntityManager;
// Some run unrestricted (e.g. internal unique key validation of wiki names)
// Make sure that these methods do not return detached objects!
@In
protected EntityManager entityManager;
public void makePersistent(WikiNode node) {
entityManager.persist(node);
}
public WikiNode findWikiNode(Long nodeId) {
try {
return (WikiNode) restrictedEntityManager
.createQuery("select n from WikiNode n where n.id = :id")
.setParameter("id", nodeId)
.setHint("org.hibernate.comment", "Find wikinode by id")
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
public Long findChildrenCount(WikiNode node) {
try {
return (Long) restrictedEntityManager
.createQuery("select count(n) from WikiNode n where n.parent = :parent")
.setParameter("parent", node)
.setHint("org.hibernate.comment", "Find number of wikinode children")
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
public List<WikiNode> findChildren(WikiNode node, String orderByProperty, boolean orderAscending, long firstResult, long maxResults) {
// Sanitize input
orderByProperty = orderByProperty.replaceAll("[^a-zA-Z0-9]", "");
StringBuilder queryString = new StringBuilder();
queryString.append("select n from WikiNode n where n.parent = :parent").append(" ");
queryString.append("order by n.").append(orderByProperty).append(" ").append(orderAscending ? "asc" : "desc");
return restrictedEntityManager
.createQuery(queryString.toString())
.setHint("org.hibernate.comment", "Find wikinode children order by "+orderByProperty)
.setParameter("parent", node)
.setFirstResult(new Long(firstResult).intValue())
.setMaxResults(new Long(maxResults).intValue())
.getResultList();
}
public List<WikiDirectory> findChildWikiDirectories(WikiDirectory dir) {
return restrictedEntityManager
.createQuery("select d from WikiDirectory d where d.parent = :parent")
.setHint("org.hibernate.comment", "Find wikinode children directories")
.setParameter("parent", dir)
.getResultList();
}
public WikiComment findWikiComment(Long commentId) {
try {
return (WikiComment) restrictedEntityManager
.createQuery("select c from WikiComment c where c.id = :id")
.setParameter("id", commentId)
.setHint("org.hibernate.comment", "Find comment by id")
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
public List<WikiComment> findWikiCommentsThreaded(WikiDocument document) {
return findWikiComments(document, true, false);
}
public List<WikiComment> findWikiCommentsFlat(WikiDocument document, boolean orderbyDateAscending) {
return findWikiComments(document, false, true);
}
private List<WikiComment> findWikiComments(WikiDocument document, final boolean threaded, boolean unthreadedAscending) {
StringBuilder queryString = new StringBuilder();
NestedSetQueryBuilder queryBuilder = new NestedSetQueryBuilder(new WikiComment(), false, true);
queryString.append("select ").append(queryBuilder.getSelectLevelClause()).append(", ");
queryString.append(queryBuilder.getSelectNodeClause()).append(" ");
queryString.append("from ").append(queryBuilder.getFromClause()).append(" ");
queryString.append("where ").append(queryBuilder.getWhereClause(false)).append(" ");
queryString.append("and ").append(NestedSetQueryBuilder.NODE2_ALIAS).append(".nodeInfo.nsThread in ");
queryString.append("(select c3.nodeInfo.nsThread from WikiComment c3 where c3.parent = :doc)").append(" ");
queryString.append("group by ").append(queryBuilder.getGroupByClause()).append(" ");
queryString.append("order by ");
if (threaded) {
queryString.append(NestedSetQueryBuilder.NODE_ALIAS).append(".nodeInfo.nsThread asc").append(", ");
queryString.append(queryBuilder.getOrderByClause());
} else {
queryString.append(NestedSetQueryBuilder.NODE_ALIAS).append(".createdOn ").append(unthreadedAscending ? "asc" : "desc");
}
org.hibernate.Query nsQuery = getSession(true).createQuery(queryString.toString());
nsQuery.setParameter("doc", document);
nsQuery.setComment("Find wikicomments (tree)");
nsQuery.setResultTransformer(
new ResultTransformer() {
public Object transformTuple(Object[] objects, String[] aliases) {
Long level = (Long)objects[0];
WikiComment c = (WikiComment)objects[1];
if (threaded) c.setLevel(level);
return c;
}
public List transformList(List list) {
return list;
}
}
);
return nsQuery.list();
}
public WikiFile findWikiFile(Long fileId) {
try {
return (WikiFile) restrictedEntityManager
.createQuery("select f from WikiFile f where f.id = :id")
.setParameter("id", fileId)
.setHint("org.hibernate.comment", "Find wikifile by id")
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
public WikiFile findWikiFileInArea(Long areaNumber, String wikiname) {
return findWikiFileInArea(areaNumber, wikiname, restrictedEntityManager);
}
public WikiFile findWikiFileInArea(Long areaNumber, String wikiname, EntityManager em) {
try {
return (WikiFile) em
.createQuery("select f from WikiFile f where f.areaNumber = :areaNumber and f.wikiname = :wikiname")
.setParameter("areaNumber", areaNumber)
.setParameter("wikiname", wikiname)
.setHint("org.hibernate.comment", "Find wikifile in area")
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
public WikiDocument findWikiDocument(Long documentId) {
try {
return (WikiDocument) restrictedEntityManager
.createQuery("select d from WikiDocument d where d.id = :id")
.setParameter("id", documentId)
.setHint("org.hibernate.comment", "Find document by id")
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
// Access restricted version of directory.getDefaultFile()
public WikiFile findDefaultWikiFile(WikiDirectory directory) {
if (directory == null) return null;
try {
return (WikiFile) restrictedEntityManager
.createQuery("select d.defaultFile from WikiDirectory d where d = :dir")
.setParameter("dir", directory)
.setHint("org.hibernate.comment", "Find default file")
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
// Access restricted version of directory.getDefaultFile(), also narrows it down to a document (see WikiRequestResolver)
public WikiDocument findDefaultDocument(WikiDirectory directory) {
if (directory == null) return null;
try {
return (WikiDocument) restrictedEntityManager
.createQuery("select doc from WikiDocument doc, WikiDirectory d where d = :dir and doc.id = d.defaultFile.id")
.setParameter("dir", directory)
.setHint("org.hibernate.comment", "Find default doc")
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
public List<WikiDocument> findWikiDocuments(WikiDirectory directory) {
return restrictedEntityManager.createQuery("select d from WikiDocument d where d.parent = :dir order by d.createdOn asc")
.setParameter("dir", directory)
.setHint("org.hibernate.comment", "Find documents of directory")
.getResultList();
}
public WikiDocument findWikiDocumentInArea(Long areaNumber, String wikiname) {
return findWikiDocumentInArea(areaNumber, wikiname, restrictedEntityManager);
}
public WikiDocument findWikiDocumentInArea(Long areaNumber, String wikiname, EntityManager em) {
try {
return (WikiDocument) em
.createQuery("select d from WikiDocument d where d.areaNumber = :areaNumber and d.wikiname = :wikiname")
.setParameter("areaNumber", areaNumber)
.setParameter("wikiname", wikiname)
.setHint("org.hibernate.comment", "Find document in area")
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
public List<WikiDocument> findWikiDocumentsOrderByLastModified(int maxResults) {
//noinspection unchecked
return (List<WikiDocument>)restrictedEntityManager
.createQuery("select d from WikiDocument d where d.lastModifiedOn is not null order by d.lastModifiedOn desc")
.setHint("org.hibernate.comment", "Find documents order by lastModified")
.setMaxResults(maxResults)
.getResultList();
}
public WikiUpload findWikiUpload(Long uploadId) {
try {
return (WikiUpload) restrictedEntityManager
.createQuery("select u from WikiUpload u where u.id = :id")
.setParameter("id", uploadId)
.setHint("org.hibernate.comment", "Find upload by id")
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
public List<WikiUpload> findWikiUploads(WikiDirectory directory) {
return restrictedEntityManager.createQuery("select u from WikiUpload u where u.parent = :dir order by u.createdOn asc")
.setParameter("dir", directory)
.setHint("org.hibernate.comment", "Find uploads of directory")
.getResultList();
}
public WikiDirectory findWikiDirectory(Long directoryId) {
try {
return (WikiDirectory) restrictedEntityManager
.createQuery("select d from WikiDirectory d where d.id = :id")
.setParameter("id", directoryId)
.setHint("org.hibernate.comment", "Find directory by id")
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
public WikiDirectory findWikiDirectoryInArea(Long areaNumber, String wikiname) {
return findWikiDirectoryInArea(areaNumber, wikiname, restrictedEntityManager);
}
public WikiDirectory findWikiDirectoryInArea(Long areaNumber, String wikiname, EntityManager em) {
try {
return (WikiDirectory) em
.createQuery("select d from WikiDirectory d where d.areaNumber = :areaNumber and d.wikiname = :wikiname")
.setParameter("areaNumber", areaNumber)
.setParameter("wikiname", wikiname)
.setHint("org.hibernate.comment", "Find directory in area")
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
public WikiDirectory findArea(String wikiname) {
try {
return (WikiDirectory) restrictedEntityManager
.createQuery("select d from WikiDirectory d, WikiDirectory r where r.parent is null and d.parent = r and d.wikiname = :wikiname")
.setParameter("wikiname", wikiname)
.setHint("org.hibernate.comment", "Find area by wikiname")
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
public WikiDirectory findArea(Long areaNumber) {
try {
return (WikiDirectory) restrictedEntityManager
.createQuery("select d from WikiDirectory d, WikiDirectory r where r.parent is null and d.parent = r and d.areaNumber = :areaNumber")
.setParameter("areaNumber", areaNumber)
.setHint("org.hibernate.comment", "Find area by area number")
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
// Returns a detached object
public WikiFile findHistoricalFile(String entityName, Long historyId) {
WikiFile historicalFile = (WikiFile)getSession(true).get(entityName, historyId);
getSession(true).evict(historicalFile);
return historicalFile;
}
public List<WikiFile> findHistoricalFiles(WikiFile file) {
if (file == null || file.getId() == null) return null;
return getSession(true).createQuery("select f from " + file.getHistoricalEntityName() + " f where f.id = :fileId order by f.revision desc")
.setParameter("fileId", file.getId())
.list();
}
public Long findNumberOfHistoricalFiles(WikiFile file) {
if (file == null || file.getId() == null) return 0l;
return (Long)getSession(true).createQuery("select count(f) from " + file.getHistoricalEntityName() + " f where f.id = :fileId")
.setParameter("fileId", file.getId())
.uniqueResult();
}
public void persistHistoricalFile(WikiFile historicalFile) {
if (historicalFile.getHistoricalEntityName() != null) {
log.debug("persisting historical file: " + historicalFile + " as revision: " + historicalFile.getRevision());
// Use the nonrestricted persistence context, which should be safe here so we can flush it again
// TODO: I wish Hibernate/JBoss weren't so retarted about getting a StatelessSession when you need one...
getSession(false).persist(historicalFile.getHistoricalEntityName(), historicalFile);
getSession(false).flush();
getSession(false).evict(historicalFile);
}
}
public void removeHistoricalFiles(WikiFile file) {
if (file == null || file.getId() == null) return;
((WikiFile)getSession(true).load(WikiFile.class, file.getId())).setRevision(0);
getSession(true).flush();
getSession(true).createQuery("delete from " + file.getHistoricalEntityName() + " f where f.id = :fileId")
.setParameter("fileId", file.getId())
.executeUpdate();
}
// Multi-row constraint validation
public boolean isUniqueWikiname(Long areaNumber, WikiNode node) {
WikiNode foundNode = findWikiDocumentInArea(areaNumber, node.getWikiname(), entityManager);
if (foundNode == null) {
foundNode = findWikiDirectoryInArea(areaNumber, node.getWikiname(), entityManager);
}
return foundNode == null || node.getId() != null && node.getId().equals(foundNode.getId());
}
public boolean isUniqueWikiname(Long areaNumber, String wikiname) {
WikiNode foundNode = findWikiDocumentInArea(areaNumber, wikiname, entityManager);
if (foundNode == null) {
foundNode = findWikiDirectoryInArea(areaNumber, wikiname, entityManager);
}
return foundNode == null;
}
public List<WikiMenuItem> findMenuItems(WikiDirectory parentDir) {
return restrictedEntityManager.createQuery("select m from WikiMenuItem m where m.directory.parent = :parent order by m.displayPosition asc")
.setParameter("parent", parentDir)
.getResultList();
}
public NestedSetNodeWrapper<WikiDirectory> findMenuItemTree(WikiDirectory startDir, Long maxDepth, Long flattenToLevel, boolean showAdminOnly) {
NestedSetNodeWrapper<WikiDirectory> startNodeWrapper = new NestedSetNodeWrapper<WikiDirectory>(startDir, getComparatorDisplayPosition());
NestedSetResultTransformer<WikiDirectory> transformer =
new NestedSetResultTransformer<WikiDirectory>(startNodeWrapper, flattenToLevel);
transformer.getAdditionalProjections().put("displayPosition", "m.displayPosition");
// Make hollow copies for menu display so that changes to the model in the persistence context don't appear
transformer.setNestedSetDuplicator(
new NestedSetDuplicator<WikiDirectory>() {
public WikiDirectory duplicate(WikiDirectory original) {
WikiDirectory copy = new WikiDirectory();
copy.flatCopy(original, false);
copy.setId(original.getId());
copy.setParent(original.getParent());
return copy;
}
}
);
appendNestedSetNodes(transformer, maxDepth, showAdminOnly, "WikiMenuItem m", "m.id = n1.id");
return startNodeWrapper;
}
public NestedSetNodeWrapper<WikiDirectory> findWikiDirectoryTree(WikiDirectory startDir, Long maxDepth, Long flattenToLevel, boolean showAdminOnly) {
NestedSetNodeWrapper<WikiDirectory> startNodeWrapper = new NestedSetNodeWrapper<WikiDirectory>(startDir, getComparatorWikiDirectoryName());
NestedSetResultTransformer<WikiDirectory> transformer = new NestedSetResultTransformer<WikiDirectory>(startNodeWrapper, flattenToLevel);
appendNestedSetNodes(transformer, maxDepth, showAdminOnly, null);
return startNodeWrapper;
}
public <N extends NestedSetNode> void appendNestedSetNodes(NestedSetResultTransformer<N> transformer,
Long maxDepth,
boolean showAdminOnly,
String selectionFragment,
String... restrictionFragment) {
N startNode = transformer.getRootWrapper().getWrappedNode();
log.debug("appending nested set nodes to node: " + startNode + ", " + startNode.getNodeInfo());
NestedSetQueryBuilder builder = new NestedSetQueryBuilder(startNode, false);
StringBuilder queryString = new StringBuilder();
queryString.append("select").append(" ");
queryString.append(builder.getSelectLevelClause()).append(", ");
queryString.append(builder.getSelectNodeClause()).append(" ");
for (Map.Entry<String, String> entry : transformer.getAdditionalProjections().entrySet()) {
queryString.append(", ").append(entry.getValue()).append(" as ").append(entry.getKey()).append(" ");
}
queryString.append("from ").append(builder.getFromClause());
if (selectionFragment != null) {
queryString.append(", ").append(selectionFragment);
}
queryString.append(" where ").append(builder.getWhereClause()).append(" ");
if (showAdminOnly) {
queryString.append("and ").append(NestedSetQueryBuilder.NODE_ALIAS).append(".createdBy = :adminUser").append(" ");
}
for (String fragment: restrictionFragment) {
queryString.append("and ").append(fragment).append(" ");
}
queryString.append("group by ").append(builder.getGroupByClause()).append(" ");
for (Map.Entry<String, String> entry : transformer.getAdditionalProjections().entrySet()) {
queryString.append(", ").append(entry.getValue()).append(" ");
}
if (maxDepth != null) {
queryString.append("having count(").append(NestedSetQueryBuilder.NODE_ALIAS).append(".id) <= :maxDepth").append(" ");
}
queryString.append("order by ").append(builder.getOrderByClause());
org.hibernate.Query nestedSetQuery = getSession(true).createQuery(queryString.toString());
nestedSetQuery.setParameter("nsThread", startNode.getNodeInfo().getNsThread());
nestedSetQuery.setParameter("nsLeft", startNode.getNodeInfo().getNsLeft());
nestedSetQuery.setParameter("nsRight", startNode.getNodeInfo().getNsRight());
if (showAdminOnly) nestedSetQuery.setParameter("adminUser", Component.getInstance("adminUser"));
if (maxDepth != null) nestedSetQuery.setParameter("maxDepth", maxDepth);
nestedSetQuery.setComment("Appending nested set nodes to startnode: " + startNode.getId());
nestedSetQuery.setCacheable(true);
nestedSetQuery.setResultTransformer(transformer);
nestedSetQuery.list(); // Append all children hierarchically to the transformers rootWrapper
}
public Comparator<NestedSetNodeWrapper<WikiDirectory>> getComparatorWikiDirectoryName() {
// Needs to be equals() safe (SortedSet):
// - compare by name, if equal
// - compare by id
return
new Comparator<NestedSetNodeWrapper<WikiDirectory>>() {
public int compare(NestedSetNodeWrapper<WikiDirectory> o1, NestedSetNodeWrapper<WikiDirectory> o2) {
WikiDirectory node1 = o1.getWrappedNode();
WikiDirectory node2 = o2.getWrappedNode();
if (node1.getName().compareTo(node2.getName()) != 0) {
return node1.getName().compareTo(node2.getName());
}
return node1.getId().compareTo(node2.getId());
}
};
}
public Comparator<NestedSetNodeWrapper<WikiDirectory>> getComparatorDisplayPosition() {
// Needs to be equals() safe (SortedSet):
// - compare by display position, if equal
// - compare by name, if equal
// - compare by id
return
new Comparator<NestedSetNodeWrapper<WikiDirectory>>() {
public int compare(NestedSetNodeWrapper<WikiDirectory> o1, NestedSetNodeWrapper<WikiDirectory> o2) {
WikiDirectory node1 = o1.getWrappedNode();
Long node1DisplayPosition = (Long)o1.getAdditionalProjections().get("displayPosition");
WikiDirectory node2 = o2.getWrappedNode();
Long node2DisplayPosition = (Long)o2.getAdditionalProjections().get("displayPosition");
if (node1DisplayPosition.compareTo(node2DisplayPosition) != 0) {
return node1DisplayPosition.compareTo(node2DisplayPosition);
} else if (node1.getName().compareTo(node2.getName()) != 0) {
return node1.getName().compareTo(node2.getName());
}
return node1.getId().compareTo(node2.getId());
}
};
}
private Session getSession(boolean restricted) {
if (restricted) {
return ((Session)((org.jboss.seam.persistence.EntityManagerProxy) restrictedEntityManager).getDelegate());
} else {
return ((Session)((org.jboss.seam.persistence.EntityManagerProxy) entityManager).getDelegate());
}
}
}
More information about the jboss-cvs-commits
mailing list