2

Problem Statement:

Imagine a nested object like below:

class Company{
...
List<Department> departments;
}

class Department{
...
List<Employee> employees;
}

class Employee{
String name;
...
}

A company has many departments, and each department has many employees.

Json body is unmarshalled by a library, to create the Java object Company as shown above.

Suppose I had an employee with name:"John", I am looking for an api, which when I pass in the hash of Employee object or the attribute name returns a Path to that attribute.

search(Object attributeName, Object attributeValue) i.e search("name", "John") should return company.departments[0].employees[5]

Is there a good open source library exposing similar api or what is the best method around to walk over a complex object graph

JSR 303 Hibernate Validator, which adds property path automatically to a ConstraintViolation doesn't expose the behavior on how it gets property path from complex object graphs via any object

Kindly advice if anyone has run through a similar need

Hardy
  • 18,659
  • 3
  • 49
  • 65
hackmabrain
  • 457
  • 1
  • 6
  • 21
  • What are you gonna do later with this result `company.departments[0].employees[5]`? Only print it in text form or iterate on it somehow or smth else? – Andriy Kryvtsun Mar 09 '16 at 15:37
  • I just need it in text form, which would be some additional metadata I want to send back to the user. Use case is we have custom business logic where we return 400's bad request to the user, we want to send back the path to the attribute in the deeply nested object graph where we believe the there is a field mismatch or an incorrect value sent in. – hackmabrain Mar 09 '16 at 19:08

2 Answers2

2

I haven't seen a library that does exactly this, but you can modify the code from my object iterator blog to do this.

https://blog.stackhunter.com/2014/07/09/convert-java-objects-to-string-with-the-iterator-pattern/

The iterator navigates an object graph to produce output like the following, but you can make it do anything -- including searching for a key-value pair.

com.stackhunter.example.employee.Department@129719f4
  deptId = 5775
  employeeList = java.util.ArrayList@7037717a
employeeList[0] = com.stackhunter.example.employee.Employee@17a323c0
  firstName = Bill
  id = 111
  lastName = Gates
employeeList[1] = com.stackhunter.example.employee.Employee@57801e5f
  firstName = Howard
  id = 222
  lastName = Schultz
employeeList[2] = com.stackhunter.example.employee.Manager@1c4a1bda
  budget = 75000.0
  firstName = Jeff
  id = 333
  lastName = Bezos
  name = Sales
[I@39df3255
  object[0] = 111
  object[1] = 222
  object[2] = 333

Happy coding!

Dele Taylor
  • 300
  • 5
  • 11
1

You can use SOJO (Simplified Old Java Objects).

According to theirs documentation i think PathRecordWalkerInterceptor is what you are search:

Car car = new Car("Ferrari");
ObjectGraphWalker walker = new ObjectGraphWalker();
PathRecordWalkerInterceptor interceptor = new PathRecordWalkerInterceptor();
walker.addInterceptor(interceptor);

walker.walk(car);
Map visitedPathes = interceptor.getAllRecordedPathes();
Hubbitus
  • 5,161
  • 3
  • 41
  • 47