Пройдите по графу сложных объектов в 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();