[Prev] Thread [Next]  |  [Prev] Date [Next]

[hibernate-dev] [BV] Path, string or object model Emmanuel Bernard Wed Jun 17 13:00:19 2009

Please review and comment.

Begin forwarded message:

From: Emmanuel Bernard <[EMAIL PROTECTED]>
Date:  June 17, 2009 14:41:03  EDT
Subject: Re: Path, string or object model

Here is the solution I cooked. I think it's acceptable but add some complexity in the ConstraintValidatorContext API (see other email). Please review (pay special attention to the examples).

A Path represents the path and is the one accepted by the path consuming APIs. A Path is an Iterable of Nodes.

 * Represent a navigation path from an object to another.
 * Each path element is represented by a Node.
 * The path corresponds to the succession of nodes
 * in the order they are retured by the Iterator
 * @author Emmanuel Bernard
public interface Path extends Iterable<Node> {

A node represent a path element.

 * Represents an element of a navigation path
 * @author Emmanuel Bernard
public interface Node {
         * Property name the node represents
         * or null if the leaf node and representing an entity
         * (in particular the node representing the root object
         * has its name null)
        String getName();

         * True if the node represents an object contained in an Iterable
         * or in a Map.
        boolean isInIterable();

         * The index the node is placed in if contained
         * in an array or List. Null otherwise.
        Integer getIndex();

         * The key the node is placed in if contained
         * in a Map. Null otherwise.
        Object getKey();

A few interesting points:
 - the index / key is hosted by the node after the collection node

Here are a few examples and their Node equivalent

0: Node(name:null, isInIterable:false, index:null, key:null)

0: Node(name:email, isInIterable:false, index:null, key:null)

0: Node(name:addresses, isInIterable:false, index:null, key:null)

"addresses["home"]" represent the bean level of an Address object
0: Node(name:addresses, isInIterable:false, index:null, key:null)
1: Node(name:null, isInIterable:true, index:null, key:home)

0: Node(name:addresses, isInIterable:false, index:null, key:null)
1: Node(name:city, isInIterable:true, index:null, key:home)

0: Node(name:billingAddresses, isInIterable:false, index:null, key:null)
1: Node(name:country, isInIterable:true, index:3, key:null)
2: Node(name:name, isInIterable:false, index:null, key:null)

ConstraintViolation renders a Path

public interface ConstraintViolation<T> {
    Path getPropertyPath();

TraversableResolver accepts a path

public interface TraversableResolver {
        boolean isReachable(Object traversableObject,
                                                  String traversableProperty,
                                                  Class<?> rootBeanType,
                                                  Path pathToTraversableObject,
                                                  ElementType elementType);

PS: should String traversableProperty be Node traversableProperty ?

On  May 27, 2009, at 12:19, Emmanuel Bernard wrote:

In several areas we do describe path:
 - ConstraintViolation
- ConstraintValidatorContext (with addError(String, String) which allows to concatenate substrings

So far we use the notion of string to represent it
 - address.name
 - cards[3].color
 - addresses["home"].city

I have added the idea of using [] for simple Iterable objects (ie non indexed, like a Set)
 - accounts[].balance

Anybody objects to that?

Second point
Do we want to replace this String approach with a path object mode?

path are today strings with dot separating properties. But it break when Set or Iterable are used.
We could replace that with
--- First strawman, must evolve --
class PathElement {
  String getName();
  PathElement getParentPath();
  boolean isIterable();
  boolean isIndexed();
  Object getIndex();
  //TODO int getIndex()?

// not happy about that as it is only useful for Constraintciolation
  PathElement getChild();

PathElement would be used for Constraintvuilation, maybe CVContext etc

can this be refactored using inheritance + generics to have an IndexedPathElement only when it matters (probably no unfortunately)

- less string manipulation by the user and the TraversableResolver implementation - the map index no longer rely on "[" + toString() + "]" and is likely more easily handled

- ConstraintValidatorContext becomes more complex as it needs to expose some kind of path element builder. - we would like need to standardize some kind of String serialization anyway
 - I don't see Pros as huge advantages


hibernate-dev mailing list