fri.util.database.jpa.tree
Interface TreeDao<N extends TreeNode>

All Known Subinterfaces:
TemporalTreeDao<N>
All Known Implementing Classes:
AbstractTreeDao, ClosureTableTreeDao, NestedSetsTreeDao, TemporalClosureTableTreeDao, TemporalNestedSetsTreeDao

public interface TreeDao<N extends TreeNode>

Tree DAO provides hierarchical access to records in a JPA database layer. There can be more than one tree in a database table. A record can not be in several trees at the same time. A record can have one parent or no parent (root), but not several parents. Normally there is no record that is not in a tree, except it is a root without children.

This interface abstracts the functionality of a tree DAO so that the underlying implementation can be replaced. In this library two such DAOs are implemented, one for a nested-sets-tree, one for a closure-table-tree.

For more information see Bill Karwin slides "Models for Hierarchical Data", page 40, and Bill Karwin slides "SQL Antipatterns strike back", page 68.

Author:
Fritz Ritzberger, 19.10.2012

Nested Class Summary
static interface TreeDao.CopiedNodeRenamer<N extends TreeNode>
          Implementers have the opportunity to edit copied nodes before they are inserted.
 
Field Summary
static int UNDEFINED_POSITION
          The position parameter to express "append to end of parent's child list", for add, move, copy.
 
Method Summary
 N addChild(N parent, N child)
          Adds to end of children of given parent.
 N addChildAt(N parent, N child, int position)
          Adds at specified position to children of given parent.
 N addChildBefore(N sibling, N child)
          Adds to children before given sibling, sibling is pushed backwards in children list.
 void checkUniqueConstraint(N cloneOfExistingNodeWithNewValues, N root, N originalNode)
          Checks unique constraint(s) for passed entity before an update of unique properties.
 N copy(N node, N parent, N copiedNodeTemplate)
          Copies the given node to end of children list of parent.
 N copyBefore(N node, N sibling, N copiedNodeTemplate)
          Copies the given node to position of given sibling, pushing sibling backwards in list.
 N copyTo(N node, N parent, int position, N copiedNodeTemplate)
          Copies the given node to given position in children list of parent.
 N copyToBeRoot(N child, N copiedNodeTemplate)
          Copies a tree to be a root.
 N createRoot(N root)
          Creates a tree root node.
 java.util.List<N> find(N parent, java.util.Map<java.lang.String,java.lang.Object> criteria)
          Convenience finder method.
 N find(java.io.Serializable id)
           
 java.util.List<N> findDirectChildren(java.util.List<N> treeCacheable)
          Finds direct children in a cached list of tree nodes, parent is first in that cached list.
 java.util.List<N> findSubTree(N parent, java.util.List<N> treeCacheable)
          Finds a sub-tree list in a cached list of tree nodes under given parent.
 int getChildCount(N parent)
           
 java.util.List<N> getChildren(N parent)
          Gives the children of passed parent.
 int getLevel(N node)
           
 N getParent(N node)
           
 java.util.List<N> getPath(N node)
           
 N getRoot(N node)
           
 java.util.List<N> getRoots()
           
 java.util.List<N> getTree(N parent)
          Reads a tree or sub-tree, including all children.
 java.util.List<N> getTreeCacheable(N parent)
          Reads a tree or sub-tree, including all children, which can be cached and passed back into findSubTree() or findDirectChildren().
 boolean isChildOf(N child, N parent)
           
 boolean isEqualToOrChildOf(N child, N parent)
           
 boolean isLeaf(N node)
           
 boolean isPersistent(N entity)
           
 boolean isRoot(N entity)
           
 void move(N node, N newParent)
          Moves the given node to end of children list of parent.
 void moveBefore(N node, N sibling)
          Moves the given node to position of given sibling, pushing sibling backwards in list.
 void moveTo(N node, N parent, int position)
          Moves the given node to given position in children list of parent.
 void moveToBeRoot(N child)
          Moves a sub-tree to be a root.
 void remove(N node)
          Removes the tree under given node, including the node.
 void removeAll()
          Removes all roots, including the nodes below them.
 void setCheckUniqueConstraintOnUpdate(boolean checkUniqueConstraintOnUpdate)
          Setting this to true will call unique constraint(s) even on update().
 void setCopiedNodeRenamer(TreeDao.CopiedNodeRenamer<N> copiedNodeRenamer)
          Sets a CopiedNodeRenamer for copy actions in trees guarded by unique constraint(s).
 void setUniqueTreeConstraint(UniqueTreeConstraint<N> uniqueTreeConstraint)
          Optionally lets set unique constraint(s).
 int size(N tree)
           
 void update(N entity)
          Updates the given persistent object.
 

Field Detail

UNDEFINED_POSITION

static final int UNDEFINED_POSITION
The position parameter to express "append to end of parent's child list", for add, move, copy.

See Also:
Constant Field Values
Method Detail

isPersistent

boolean isPersistent(N entity)
Returns:
true if passed entity is already persistent, i.e. its getId() is not null.

find

N find(java.io.Serializable id)
Returns:
the object by identity (primary key) from database.

update

void update(N entity)
            throws UniqueConstraintViolationException
Updates the given persistent object. This performs explicit constraint checking when checkUniqueConstraintsOnUpdate is true (default is false).

Throws:
UniqueConstraintViolationException - when given entity is not unique.
java.lang.IllegalArgumentException - when given node is not yet persistent.

isRoot

boolean isRoot(N entity)
Returns:
true if passed node is persistent and a root.

createRoot

N createRoot(N root)
                              throws UniqueConstraintViolationException
Creates a tree root node.

Throws:
UniqueConstraintViolationException - when uniqueness would be violated.
java.lang.IllegalArgumentException - when root is already persistent.

size

int size(N tree)
Returns:
the count of all nodes of any depth below given node, including itself.

getRoots

java.util.List<N> getRoots()
Returns:
all tree root nodes.

removeAll

void removeAll()
Removes all roots, including the nodes below them. Thus clears the table.


getTree

java.util.List<N> getTree(N parent)
Reads a tree or sub-tree, including all children. The result is NOT EXPECTED to be used with findSubTree() or findDirectChildren()!

Parameters:
parent - the parent of the tree to read, can also be root of the tree.
Returns:
all tree nodes under given parent, including parent.

getTreeCacheable

java.util.List<N> getTreeCacheable(N parent)
Reads a tree or sub-tree, including all children, which can be cached and passed back into findSubTree() or findDirectChildren(). Mind that any cached tree could be out-of-sync with database when another client performs changes.

Parameters:
parent - the parent of the tree to read, can also be root of the tree.
Returns:
all tree nodes under given parent, including parent, in depth-first order.

findSubTree

java.util.List<N> findSubTree(N parent,
                              java.util.List<N> treeCacheable)
Finds a sub-tree list in a cached list of tree nodes under given parent. The subNodes list was returned from a call to getTreeCacheable(). Mind that any cached tree could be out-of-sync with database when another client performs changes.

Parameters:
parent - the parent node to search a sub-tree for, contained somewhere in the given list of nodes.
treeCacheable - a list of nodes from which to extract a sub-tree, also containing given parent.
Returns:
a list of nodes under the passed parent node.

findDirectChildren

java.util.List<N> findDirectChildren(java.util.List<N> treeCacheable)
Finds direct children in a cached list of tree nodes, parent is first in that cached list. The subNodes list was returned from a call to getTreeCacheable() or findSubTree(). Mind that any cached tree could be out-of-sync with database when another client performs changes.

Parameters:
treeCacheable - a list of nodes from which to extract the direct child list, parent at head of list.
Returns:
a list of direct children of the the parent which is first in list.

isLeaf

boolean isLeaf(N node)
Returns:
true when given node has no children, i.e. is not a container-node.

getChildCount

int getChildCount(N parent)
Returns:
the number of direct children of given parent node.

getChildren

java.util.List<N> getChildren(N parent)
Gives the children of passed parent. This method reads the full subtree under parent. Removing from returned list will not remove that child from tree but cause an exception.

Returns:
the ordered list of direct children under given parent.

getRoot

N getRoot(N node)
Returns:
the root node of given node. Root has itself as root.

getParent

N getParent(N node)
Returns:
the parent node of given node. Root has null as parent.

getPath

java.util.List<N> getPath(N node)
Returns:
all parent nodes of given node, i.e. its path from root to (exclusive) node. Root will return an empty list.

getLevel

int getLevel(N node)
Returns:
the depth of given node. Root has level 0.

isEqualToOrChildOf

boolean isEqualToOrChildOf(N child,
                           N parent)
Returns:
true when child is in the tree under parent, or parent is equal to child, else false.

isChildOf

boolean isChildOf(N child,
                  N parent)
Returns:
true when child is in the tree under parent and not parent, else false.

addChild

N addChild(N parent,
           N child)
                            throws UniqueConstraintViolationException
Adds to end of children of given parent.

Throws:
UniqueConstraintViolationException - when uniqueness would be violated.

addChildAt

N addChildAt(N parent,
             N child,
             int position)
                              throws UniqueConstraintViolationException
Adds at specified position to children of given parent.

Parameters:
position - -1 for append, else target position in child list.
Throws:
UniqueConstraintViolationException - when uniqueness would be violated.

addChildBefore

N addChildBefore(N sibling,
                 N child)
                                  throws UniqueConstraintViolationException
Adds to children before given sibling, sibling is pushed backwards in children list.

Throws:
UniqueConstraintViolationException - when uniqueness would be violated.

remove

void remove(N node)
Removes the tree under given node, including the node. Node can also be a root.


move

void move(N node,
          N newParent)
          throws UniqueConstraintViolationException
Moves the given node to end of children list of parent. When source is identical with target, nothing happens.

Throws:
UniqueConstraintViolationException
java.lang.IllegalArgumentException - when target is below source.

moveTo

void moveTo(N node,
            N parent,
            int position)
            throws UniqueConstraintViolationException
Moves the given node to given position in children list of parent. When source is identical with target, nothing happens.

Throws:
UniqueConstraintViolationException
java.lang.IllegalArgumentException - when target is below source.

moveBefore

void moveBefore(N node,
                N sibling)
                throws UniqueConstraintViolationException
Moves the given node to position of given sibling, pushing sibling backwards in list. When source is identical with target, nothing happens.

Throws:
UniqueConstraintViolationException
java.lang.IllegalArgumentException - when target is below source.

moveToBeRoot

void moveToBeRoot(N child)
                  throws UniqueConstraintViolationException
Moves a sub-tree to be a root. This means it is removed from its previous root. When child is already a root, nothing happens.

Throws:
UniqueConstraintViolationException - when unique constraint(s) for roots would be violated.
java.lang.IllegalArgumentException - when passed node is not yet persistent.

copy

N copy(N node,
       N parent,
       N copiedNodeTemplate)
                        throws UniqueConstraintViolationException
Copies the given node to end of children list of parent. When source is identical with target, the node will be be copied to the position of its originator.

Parameters:
node - the node to be copied.
copiedNodeTemplate - a template for the copied node containing altered properties, can be null.
Throws:
UniqueConstraintViolationException - when uniqueness would be violated.
java.lang.IllegalArgumentException - when target is below source.

copyTo

N copyTo(N node,
         N parent,
         int position,
         N copiedNodeTemplate)
                          throws UniqueConstraintViolationException
Copies the given node to given position in children list of parent. When source is identical with target, the node will be be copied to the position of its originator.

Parameters:
node - the node to be copied.
parent - the parent-node of the children the node should be copied into.
position - the 0-n index the node should obtain within children of parent.
copiedNodeTemplate - a template for the copied node containing altered properties, can be null.
Throws:
UniqueConstraintViolationException - when uniqueness would be violated.
java.lang.IllegalArgumentException - when target is below source.

copyBefore

N copyBefore(N node,
             N sibling,
             N copiedNodeTemplate)
                              throws UniqueConstraintViolationException
Copies the given node to position of given sibling, pushing sibling backwards in list. When source is identical with target, the node will be be copied to the position of its originator.

Parameters:
node - the node to be copied.
sibling - the target node the copied node should push backwards in children list.
copiedNodeTemplate - a template for the copied node containing altered properties, can be null.
Throws:
UniqueConstraintViolationException - when uniqueness would be violated.
java.lang.IllegalArgumentException - when target is below source.

copyToBeRoot

N copyToBeRoot(N child,
               N copiedNodeTemplate)
                                throws UniqueConstraintViolationException
Copies a tree to be a root. This means it is removed from its previous root. When child is already a root, the node will be be copied to be another root.

Parameters:
child - the node to copy to be a root.
copiedNodeTemplate - a template for the copied node containing altered properties, can be null.
Throws:
UniqueConstraintViolationException - when unique constraint(s) for roots would be violated.
java.lang.IllegalArgumentException - when passed node is not yet persistent.

setCopiedNodeRenamer

void setCopiedNodeRenamer(TreeDao.CopiedNodeRenamer<N> copiedNodeRenamer)
Sets a CopiedNodeRenamer for copy actions in trees guarded by unique constraint(s). Mind that, once set, this will edit every following copy-action!

Parameters:
copiedNodeRenamer - the editor to be applied for following copy action, can be null.

find

java.util.List<N> find(N parent,
                       java.util.Map<java.lang.String,java.lang.Object> criteria)
Convenience finder method. All criteria will be AND'ed.

Parameters:
parent - the parent under which to search, can be null.
criteria - a name/value mapping for the nodes to be found under given tree.
Returns:
tree nodes with given criteria.

setUniqueTreeConstraint

void setUniqueTreeConstraint(UniqueTreeConstraint<N> uniqueTreeConstraint)
Optionally lets set unique constraint(s).

Parameters:
uniqueTreeConstraint - the constraint checker implementation, or null to switch off checking.

setCheckUniqueConstraintOnUpdate

void setCheckUniqueConstraintOnUpdate(boolean checkUniqueConstraintOnUpdate)
Setting this to true will call unique constraint(s) even on update(). Default is false, because it is assumed that caller itself does a check by calling dao.checkUniqueConstraint() before updating.

Parameters:
checkUniqueConstraintOnUpdate - the behavior to be set.

checkUniqueConstraint

void checkUniqueConstraint(N cloneOfExistingNodeWithNewValues,
                           N root,
                           N originalNode)
                           throws UniqueConstraintViolationException
Checks unique constraint(s) for passed entity before an update of unique properties. Assuming that there is a unique property name in entity, this method MUST be called BEFORE entity.setName(name) is called, else entity will get dirty and will be flushed by the JPA layer before the constraint checking query can be launched. For that purpose you must create a clone (template) of the node pending to be updated, and set the new value of the property into the clone.

Parameters:
cloneOfExistingNodeWithNewValues - non-persistent clone of the entity to be checked, containing at least the properties the constraint will check.
root - the root where insert or update will happen, null when node is (or will be) be a root.
originalNode - the original node to be inserted or updated, null when node is not yet persistent.
Throws:
UniqueConstraintViolationException - when uniqueness would be violated.