BeanHelper.javaorg.apache.commons.lang3.ArrayUtils — Конкатенация массивов для сбора полей/методов по иерархии классовorg.apache.commons.lang3.StringUtils — Манипуляции со строками (capitalize, uncapitalize, split)java.lang.annotation.Annotation — Обнаружение аннотаций на поляхjava.lang.reflect.* — Основной API рефлексии Java: Field, Method, Constructor, Modifier, Array, InvocationTargetExceptionjava.util.* — Коллекции, итераторы, хэш-карты для кэшированияorg.slf4j.Logger — Логирование ошибок при сбоях рефлексииBeanHelper использует пять статических синхронизированных кэшей для избежания повторных вызовов рефлексии, которые дороги в Java. Это критически важно для страниц списков Wicket, где BeanHelper вызывается для каждой ячейки в сортируемой таблице данных.
| Кэш | Ключ | Значение | Преимущество |
|---|---|---|---|
declaredFieldsCache | Class | Field[] | Избегает повторного сканирования иерархии классов для полей |
declaredMethodsCache | Class | Method[] | Избегает повторного сканирования иерархии классов для методов |
declaredFieldAnnotationsCache | "класс:имяполя" | Annotation[] | Избегает повторного разрешения аннотированных полей (критично для сортировки колонок Wicket) |
getterMethodsCache | "класс:имяполя" | Method | Избегает повторного поиска методов getter |
declaredGetterMethodsCache | String | Method[] | Объявлен, но, похоже, не используется в предоставленном коде — может заполняться в другом месте |
determinePropertyName(Method) — Удаляет префикс get/set/is/has и приводит первый символ к нижнему региструdetermineGetter(Class, имяполя, onlyPublicGetter) — Находит метод getter (getX(), isX() для boolean, hasX() для boolean), обрабатывает bridge-методы (не возвращает синтетические bridge-методы)determineSetter(Class, имяполя) — Находит setter с одним параметромdeterminePropertyType(Class, имяполя) — Получает возвращаемый тип getter (тип свойства)getDeclaredAnnotations(Class, имяполя) поддерживает пути к вложенным свойствам (разделённые точкой, например, "address.city.name") путём обхода цепочки полей через рефлексию для поиска аннотаций конечного поля. Это необходимо для таблиц данных Wicket, которые отображают вложенные свойства объектов с сортируемыми колонками.
getProperty(Object, String) — Вызывает getter для beansetProperty(Object, String, Object) — Вызывает settergetIndexedProperty(Object, "prop[3]") — Поддерживает индексированный доступ к коллекциям/массивамgetNestedProperty(Object, "a.b.c") — Обходит путь свойства, разделённый точками, корректно обрабатывая null (возвращает null, если любой промежуточный элемент равен null)Копирует указанные свойства из исходного объекта в целевой, возвращая true, если какое-либо свойство фактически изменилось. Поддерживает:
Arrays.equals()Objects.equals() (безопасно для null)getAllDeclaredFields(Class) — Возвращает все поля, включая унаследованные, обходя цепочку суперклассовgetAllDeclaredMethods(Class) — Возвращает все методы, включая унаследованныеgetDeclaredPropertyFields(Class) — Возвращает только нетранзиентные, нестатические, нефинальные поля (фактические постоянные свойства)getFieldValue(Object, Class/String, имяполя) — Читает значение поля через рефлексию (setAccessible для приватных полей)newInstance(Class, ...) — Несколько перегрузок для рефлексивного создания объектов с различными сигнатурами конструкторовinvoke(Object, Method, args) — Общий вызов метода с обработкой ошибокФлаг TEST_MODE (управляется enterTestMode()/exitTestMode()) подавляет логирование ошибок во время выполнения тестов. Это позволяет тестам выполнять операции рефлексии, которые, как ожидается, завершатся ошибкой, не засоряя журналы тестов трассировками стека. Методы logInstantiationException() учитывают этот флаг.
determineGetter() пропускает bridge-методы (синтетические методы, создаваемые компилятором для стирания обобщённых типов), чтобы вернуть фактически реализованный методgetNestedProperty() возвращает null в любой точке цепочки, где промежуточное значение равно null, вместо выброса NPEnewInstance() вызывает constructor.setAccessible(true) для создания экземпляров классов с приватными конструкторамиcommons-beanutils в сборке Gradle, BeanHelper реализует собственное разрешение свойств вместо прямого использования Apache BeanUtils — вероятно, для контроля производительности и кэшированияisEqualList() (пакетно-приватный) выполняет поэлементное сравнение с использованием итераторов, а не equals(). Это означает, что равенство коллекций основано на идентичности/равенстве элементов на соответствующих позициях, а не на равенстве множеств — два списка с одинаковыми элементами в разном порядке не считаются равными.868d6abb7 2025 -> 2026 63081666f Заголовки исходных файлов: 2024 -> 2025. a73905c14 Исправление опечаток в каталогах projectforge*/ Найдено с помощью codespell 694987647 Миграция в процессе... (все тесты всех пакетов: OK). ae50b2522 BeanHelper.getProperty теперь поддерживает вложенные свойства с помощью нового PropertyUtils. b6092df09 Авторское право 2023 -> 2024 ab45d51fa Авторское право 2001-2022 -> 2001-2023. 0203e3261 AbstractListPage: длительные запросы: изменение порядка сортировки показывает список результатов без кнопки поиска. BeanHelper: множество кэшей для более быстрой сортировки в списках результатов Wicket.