views:

62

answers:

3

Do you know a good java object graph visitor library?

I want to visit an object and its sub components and perform some actions when some conditions are matched.

Example usage:

  • on a huge domain object graph, reset each id to null
  • on a huge domain object graph, replace each Set with a TreeSet instance containing the same elements.

I want a library, not custom code because traversing an Object graph can be tricky. You have to handle collections, arrays, proxies, and so on... I have think about reuse part of XStream to achieve this, but it doesn't look so easy: Xstream visitor is more oriented on object transformation than object self modification.

+1  A: 

Why do you need a library in order to do that?

Given that you specify this is a domain object graph then why not define and implement relevant interfaces to allow your domain objects to be visited by different visitor implementations? One of the implementations could (as you specify) reset each ID to null.

Example

First define the interfaces to be implemented by objects that can be visited or act as visitors.

public interface Visitable {
  void visit(Visitor visitor);
}

public interface Visitor {
  void visitDomainObjectA(DomainObjectA obj);
  void visitDomainObjectB(DomainObjectB obj);
}

Now define two domain object classes, both of which can be visited.

public abstract class DomainObject implements Visitable {
  private Object id;

  public Object getId() { return this.id; }
  public void setId(Object id) { this.id = id; }
}

public class DomainObjectA extends DomainObject {
  public void visit(Visitor visitor) {
    visitor.visitDomainObjectA(this);
  }
}

public class DomainObjectB extends DomainObject {
  public void visit(Visitor visitor) {
    visitor.visitDomainObjectB(this);
  }
}

Now define a concrete Visitor implementation that does something useful:

public class MyVisitor implements Visitor {
  public void visitDomainObjectA(DomainObjectA doa) {
    doa.setId(null);
  }

  public void visitDomainObjectB(DomainObjectB dob) {
    doa.setId(UUID.randomUUID());
  }
}
Adamski
I've refined my question about your relevant answer. My domain is huge and my graphs are complexes. So I need something robust and already debugged and ready to use.
Guillaume
IMO you've made the problem tricky by trying to be uber-generic. What is the point in a library that can traverse *any* object graph (presumably by reflection) and then call *any method* on given objects? You effectively throw away any compile-time type safety. After all it could be argued that any OO application is simply traversing an object graph and calling methods on a subset of the objects.
Adamski
I don't want to be uber-generic. My domain is uber-complicated ;) And byt the way, it's the how serialization tools like XStream are working. And they work fine.
Guillaume
+1  A: 

How about marshalling your object graph into XML and using some standard XML handling/manipulation library?

Jatin
That's a good suggestion, but I want to avoid it if possible. It add some more steps that I wish I can avoid
Guillaume
What would those steps be?
Jatin
A: 

It might be worth trying an object database like NeoDatis. It will let you affect visitation by using queries to cross-cut your data set.

http://www.neodatis.org/5m-tutorial

Alain O'Dea