fri.util.database.jpa.tree
Class AbstractTreeDao<N extends TreeNode>

java.lang.Object
  extended by fri.util.database.jpa.tree.AbstractTreeDao<N>
Type Parameters:
N - the tree node type handled by this DAO.
All Implemented Interfaces:
TreeDao<N>
Direct Known Subclasses:
ClosureTableTreeDao, NestedSetsTreeDao

public abstract class AbstractTreeDao<N extends TreeNode>
extends java.lang.Object
implements TreeDao<N>

Common functionalities for a TreeDao implementation.

Mind that concurrency is not handled in any way. The caller is expected to provide a transaction around every DAO write-method. DAO write-methods execute more than one JPQL statement when called!

Author:
Fritz Ritzberger, 27.10.2012

Nested Class Summary
 
Nested classes/interfaces inherited from interface fri.util.database.jpa.tree.TreeDao
TreeDao.CopiedNodeRenamer<N extends TreeNode>
 
Field Summary
protected  DbSession session
           
 
Fields inherited from interface fri.util.database.jpa.tree.TreeDao
UNDEFINED_POSITION
 
Constructor Summary
protected AbstractTreeDao(DbSession session, java.lang.String nodeEntityName)
           
 
Method Summary
protected  void appendInvalidityCondition(java.lang.String tableAlias, java.lang.StringBuilder queryText, java.util.List<java.lang.Object> parameters)
          Temporal extension.
 void appendValidityCondition(java.lang.String tableAlias, java.lang.StringBuilder queryText, java.util.List<java.lang.Object> parameters)
          Temporal extension.
protected  void applyCopiedNodeRenamer(N node)
          Applies the currently set CopiedNodeRenamer if one was set.
protected  void assertUpdate(N node)
          Throws IllegalArgumentException when node is not persistent, because then it is not an UPDATE.
protected  void beforeFindQuery(java.lang.String tableAlias, java.lang.StringBuilder queryText, java.util.List<java.lang.Object> parameters, boolean whereWasAppended, boolean doNotApplyTemporalConditions, boolean invertTemporalConditions)
          Temporal extension.
protected  java.lang.String buildAliasedPropertyName(java.lang.String tableAlias, java.lang.String propertyName)
           
protected  java.lang.String buildIndexedPlaceHolder(java.util.List<java.lang.Object> parameters)
           
 void checkUniqueConstraint(N cloneOfExistingNodeWithNewValues, N root, N existingNode)
          Checks unique constraint(s) for passed entity before an update of unique properties.
protected  void checkUniqueness(java.util.List<N> nodes, TreeActionLocation<N> location)
          Utility method that calls the implementation when one was defined.
protected  void copyOrMovePreconditions(N relativeNode, N nodeToMove)
          Throws IllegalArgumentException when copy or move could not performed, checks if tree would be copied/moved into itself.
 boolean equal(N n1, N n2)
          Decides if two nodes are equal.
protected  UniqueTreeConstraint<N> getUniqueTreeConstraint()
           
protected  java.lang.String getValidFromPropertyName()
          Temporal extension.
protected  java.lang.String getValidToPropertyName()
          Temporal extension.
 boolean isPersistent(N entity)
          
 boolean isValid(Temporal node, java.util.Date validityDate)
          Temporal extension.
protected  java.lang.String nodeEntityName()
           
protected  java.lang.String pathEntityName()
           
protected  void refresh(java.util.List<?> nodesToRefresh)
          Updates nodes from database, overwriting pending local changes.
protected  java.lang.Object save(N node)
          Saves the given node to session.
 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).
protected  boolean shouldCheckUniqueConstraintOnUpdate()
           
protected  java.util.Date validFrom()
          Temporal extension.
protected  java.util.Date validTo()
          Temporal extension.
protected  java.util.Date validToOnRemove()
          Temporal extension.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface fri.util.database.jpa.tree.TreeDao
addChild, addChildAt, addChildBefore, copy, copyBefore, copyTo, copyToBeRoot, createRoot, find, find, findDirectChildren, findSubTree, getChildCount, getChildren, getLevel, getParent, getPath, getRoot, getRoots, getTree, getTreeCacheable, isChildOf, isEqualToOrChildOf, isLeaf, isRoot, move, moveBefore, moveTo, moveToBeRoot, remove, removeAll, size, update
 

Field Detail

session

protected final DbSession session
Constructor Detail

AbstractTreeDao

protected AbstractTreeDao(DbSession session,
                          java.lang.String nodeEntityName)
Method Detail

isPersistent

public boolean isPersistent(N entity)

Specified by:
isPersistent in interface TreeDao<N extends TreeNode>
Returns:
true if passed entity is already persistent, i.e. its getId() is not null.

save

protected java.lang.Object save(N node)
Saves the given node to session. To be overridden for additional actions on save.


equal

public boolean equal(N n1,
                     N n2)
Decides if two nodes are equal. Used by all implementations. Can handle nulls, returns true if n1 == n2. To be overridden. Is public to be reused also from UniqueTreeConstraint implementations.


setUniqueTreeConstraint

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

Specified by:
setUniqueTreeConstraint in interface TreeDao<N extends TreeNode>
Parameters:
uniqueTreeConstraint - the constraint checker implementation, or null to switch off checking.

setCheckUniqueConstraintOnUpdate

public 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.

Specified by:
setCheckUniqueConstraintOnUpdate in interface TreeDao<N extends TreeNode>
Parameters:
checkUniqueConstraintOnUpdate - the behavior to be set.

shouldCheckUniqueConstraintOnUpdate

protected final boolean shouldCheckUniqueConstraintOnUpdate()
Returns:
true when unique constraint should be checked on UPDATE, default false, as callers should check explicitly this by calling checkUniqueConstraint().

getUniqueTreeConstraint

protected final UniqueTreeConstraint<N> getUniqueTreeConstraint()
Returns:
the optional unique constraint implementation.

checkUniqueConstraint

public void checkUniqueConstraint(N cloneOfExistingNodeWithNewValues,
                                  N root,
                                  N existingNode)
                           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.

Specified by:
checkUniqueConstraint in interface TreeDao<N extends TreeNode>
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.
existingNode - the original node to be inserted or updated, null when node is not yet persistent.
Throws:
UniqueConstraintViolationException - when uniqueness would be violated.

checkUniqueness

protected void checkUniqueness(java.util.List<N> nodes,
                               TreeActionLocation<N> location)
                        throws UniqueConstraintViolationException
Utility method that calls the implementation when one was defined.

Parameters:
nodes - one or several nodes to insert or update. Updates should be tested with a clone, else JPA object would get dirty.
root - the root of the tree where to check, can be null for a uniqueness check among roots.
originalNode - the node to be updated, must be null for a new node to be inserted.
modificationLocation - insert/update location information, implementation-specific.
Throws:
UniqueConstraintViolationException - when constraint would be violated.

setCopiedNodeRenamer

public 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!

Specified by:
setCopiedNodeRenamer in interface TreeDao<N extends TreeNode>
Parameters:
copiedNodeRenamer - the editor to be applied for following copy action, can be null.

applyCopiedNodeRenamer

protected final void applyCopiedNodeRenamer(N node)
Applies the currently set CopiedNodeRenamer if one was set.


nodeEntityName

protected final java.lang.String nodeEntityName()
Returns:
the name of the JPQL node entity.

pathEntityName

protected java.lang.String pathEntityName()
Returns:
the name of the JPQL path entity, needed only in closure-table. Returns null, to be overridden.

assertUpdate

protected void assertUpdate(N node)
Throws IllegalArgumentException when node is not persistent, because then it is not an UPDATE.


copyOrMovePreconditions

protected void copyOrMovePreconditions(N relativeNode,
                                       N nodeToMove)
Throws IllegalArgumentException when copy or move could not performed, checks if tree would be copied/moved into itself.


refresh

protected void refresh(java.util.List<?> nodesToRefresh)
Updates nodes from database, overwriting pending local changes. Needed only when several TreeDao calls happen in same session. Override this to do nothing when your session is closed or cleared after any TreeDao call, this will save performance.

This is to be called for all nodes affected by an SQL or JPQL update statement. This method performs a flush() before refresh() to avoid inconsistencies.


beforeFindQuery

protected final void beforeFindQuery(java.lang.String tableAlias,
                                     java.lang.StringBuilder queryText,
                                     java.util.List<java.lang.Object> parameters,
                                     boolean whereWasAppended,
                                     boolean doNotApplyTemporalConditions,
                                     boolean invertTemporalConditions)
Temporal extension. Shared code. Called when querying valid nodes.


appendValidityCondition

public void appendValidityCondition(java.lang.String tableAlias,
                                    java.lang.StringBuilder queryText,
                                    java.util.List<java.lang.Object> parameters)
Temporal extension. Called when querying valid nodes. Appends the (temporal) validity check condition to passed JPQL statement. The appended text must NOT start or end with "AND". Override this to use other validity checks than valid-from and valid-to properties. This is public to be reused by UniqueTemporalTreeConstraint implementations.

Parameters:
tableAlias - the alias of the table containing the validTo property, without trailing dot, could be null.
queryText - the pending JPQL query text looking for valid nodes.
parameters - the positional arguments for the pending query.

appendInvalidityCondition

protected void appendInvalidityCondition(java.lang.String tableAlias,
                                         java.lang.StringBuilder queryText,
                                         java.util.List<java.lang.Object> parameters)
Temporal extension. Called when querying removed nodes. Appends the (temporal) invalidity check condition to passed JPQL statement. The appended text must NOT start with "and". Override this to use other validity checks than valid-to property.

Parameters:
tableAlias - the alias of the table containing the validTo property, without trailing dot, could be null.
queryText - the pending JPQL query text looking for invalid nodes.
parameters - the positional arguments for the pending query.

buildAliasedPropertyName

protected final java.lang.String buildAliasedPropertyName(java.lang.String tableAlias,
                                                          java.lang.String propertyName)
Returns:
"tableAlias.propertyName" when alias is not null, else "propertyName".

buildIndexedPlaceHolder

protected final java.lang.String buildIndexedPlaceHolder(java.util.List<java.lang.Object> parameters)
Returns:
"?5" when parameters.size() == 4.

validFrom

protected java.util.Date validFrom()
Temporal extension. This is called when querying. Override for specific temporal queries.

Returns:
by default new Date() which represents "now".

validTo

protected java.util.Date validTo()
Temporal extension. This is called when querying. Override for specific temporal queries.

Returns:
by default new Date() which represents "now".

validToOnRemove

protected java.util.Date validToOnRemove()
Temporal extension. This is called when historicizing a node.

Returns:
by default new Date() which represents "now".

isValid

public boolean isValid(Temporal node,
                       java.util.Date validityDate)
Temporal extension. This is called when deciding whether a node is valid at given date.

Returns:
true when node.validFrom is null or before or equal to given date, and node.validTo is null or after given date.

getValidFromPropertyName

protected java.lang.String getValidFromPropertyName()
Temporal extension. Override this in temporal DAOs. Throws RuntimeException.


getValidToPropertyName

protected java.lang.String getValidToPropertyName()
Temporal extension. Override this in temporal DAOs. Throws RuntimeException.