Пройдите по графу сложных объектов в Java и получите индекс для атрибута (аналогично xpath)

Постановка задачи:

Представьте себе вложенный объект, как показано ниже:

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

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

class Employee{
String name;
...
}

В компании много отделов, и в каждом отделе много сотрудников.

Тело Json распаковывается библиотекой для создания объекта Java Company, как показано выше.

Предположим, у меня был сотрудник с именем "Джон", я ищу API, который, когда я передаю хэш объекта Employee или имя атрибута, возвращает путь к этому атрибуту.

search (Object attributeName, Object attributeValue), т.е. search("name", "John") должен возвращать company.departments[0].employees[5]

Есть ли хорошая библиотека с открытым исходным кодом, демонстрирующая подобный API, или как лучше обходить сложный граф объектов?

JSR 303 Hibernate Validator, который автоматически добавляет путь свойства в ConstraintViolation, не раскрывает поведение того, как он получает путь свойства из графов сложных объектов через любой объект

Добрый совет, если кто-нибудь сталкивался с подобной необходимостью

1 ответ

Я не видел библиотеку, которая делает именно это, но вы можете изменить код из моего блога итератора объектов, чтобы сделать это.

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

Итератор перемещается по графу объектов для получения вывода, подобного следующему, но вы можете заставить его делать все что угодно - включая поиск пары ключ-значение.

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

Удачного кодирования!

Вы можете использовать SOJO (Упрощенные Старые Объекты Java).

По их документации я думаю PathRecordWalkerInterceptor это то, что вы ищете:

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

walker.walk(car);
Map visitedPathes = interceptor.getAllRecordedPathes();
Другие вопросы по тегам