11

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.

Guillaume
  • 5,488
  • 11
  • 47
  • 83

5 Answers5

2

As it happens, I have done such a thing. Not really a library, but it could grow into one easily.

But I stumbled upon this since I was looking for something better. I can't give it out, and it definetely isn't yet in a state where I would do this, but maybe such a thing should come to live as OS?

What I have lets me traverse and modify an object graph type-safe, instance-by-instance, optionally duplicating it such that the original remains untouched. Java BTW. What also works a bit is grasping relationships in the graph (the edges, if you want).

What I could envision is a clear-cut definition of operations (such as modify, extend, duplicate, collapse, traverse) and respective implemetations. Orthogonal aspects such as identifyig subgraphs would be properly factored out.

Anyone interested in such a project please respond, maybe we can get something started.

Simon Thum
  • 576
  • 4
  • 15
2

I've been looking for the same thing, and found this.

http://code.google.com/p/behaim/

user456837
  • 183
  • 7
1

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
  • 54,009
  • 15
  • 113
  • 152
  • 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 Jul 29 '10 at 11:40
  • 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 Jul 29 '10 at 11:50
  • 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 Jul 29 '10 at 12:27
1

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

Jatin
  • 709
  • 4
  • 5
  • 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 Jul 29 '10 at 12:37
1

It might be worth trying an graph database like Neo4j or TitanDB. It will let you affect visitation by using queries to cross-cut your data set and explore relationships.

Both of these have extensive Java APIs to facilitate data loading and querying.

Alain O'Dea
  • 21,033
  • 1
  • 58
  • 84