private void traverseObjectWithParents()

in compat/maven-compat/src/main/java/org/apache/maven/project/interpolation/StringSearchModelInterpolator.java [138:260]


        private void traverseObjectWithParents(Class<?> cls, Object target) throws ModelInterpolationException {
            if (cls == null) {
                return;
            }

            if (cls.isArray()) {
                evaluateArray(target);
            } else if (isQualifiedForInterpolation(cls)) {
                Field[] fields = FIELDS_BY_CLASS.computeIfAbsent(cls, k -> cls.getDeclaredFields());

                for (Field field : fields) {
                    Class<?> type = field.getType();
                    if (isQualifiedForInterpolation(field, type)) {
                        boolean isAccessible = field.isAccessible();
                        field.setAccessible(true);
                        try {
                            try {
                                if (String.class == type) {
                                    String value = (String) field.get(target);
                                    if (value != null) {
                                        String interpolated = modelInterpolator.interpolateInternal(
                                                value, valueSources, postProcessors, debugEnabled);

                                        if (!interpolated.equals(value)) {
                                            field.set(target, interpolated);
                                        }
                                    }
                                } else if (Collection.class.isAssignableFrom(type)) {
                                    Collection<Object> c = (Collection<Object>) field.get(target);
                                    if (c != null && !c.isEmpty()) {
                                        List<Object> originalValues = new ArrayList<>(c);
                                        try {
                                            c.clear();
                                        } catch (UnsupportedOperationException e) {
                                            if (debugEnabled && logger != null) {
                                                logger.debug("Skipping interpolation of field: " + field + " in: "
                                                        + cls.getName()
                                                        + "; it is an unmodifiable collection.");
                                            }
                                            continue;
                                        }

                                        for (Object value : originalValues) {
                                            if (value != null) {
                                                if (String.class == value.getClass()) {
                                                    String interpolated = modelInterpolator.interpolateInternal(
                                                            (String) value, valueSources, postProcessors, debugEnabled);

                                                    if (!interpolated.equals(value)) {
                                                        c.add(interpolated);
                                                    } else {
                                                        c.add(value);
                                                    }
                                                } else {
                                                    c.add(value);
                                                    if (value.getClass().isArray()) {
                                                        evaluateArray(value);
                                                    } else {
                                                        interpolationTargets.add(value);
                                                    }
                                                }
                                            } else {
                                                // add the null back in...not sure what else to do...
                                                c.add(value);
                                            }
                                        }
                                    }
                                } else if (Map.class.isAssignableFrom(type)) {
                                    Map<Object, Object> m = (Map<Object, Object>) field.get(target);
                                    if (m != null && !m.isEmpty()) {
                                        for (Map.Entry<Object, Object> entry : m.entrySet()) {
                                            Object value = entry.getValue();

                                            if (value != null) {
                                                if (String.class == value.getClass()) {
                                                    String interpolated = modelInterpolator.interpolateInternal(
                                                            (String) value, valueSources, postProcessors, debugEnabled);

                                                    if (!interpolated.equals(value)) {
                                                        try {
                                                            entry.setValue(interpolated);
                                                        } catch (UnsupportedOperationException e) {
                                                            if (debugEnabled && logger != null) {
                                                                logger.debug("Skipping interpolation of field: " + field
                                                                        + " (key: " + entry.getKey() + ") in: "
                                                                        + cls.getName()
                                                                        + "; it is an unmodifiable collection.");
                                                            }
                                                        }
                                                    }
                                                } else {
                                                    if (value.getClass().isArray()) {
                                                        evaluateArray(value);
                                                    } else {
                                                        interpolationTargets.add(value);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                } else {
                                    Object value = field.get(target);
                                    if (value != null) {
                                        if (field.getType().isArray()) {
                                            evaluateArray(value);
                                        } else {
                                            interpolationTargets.add(value);
                                        }
                                    }
                                }
                            } catch (IllegalArgumentException | IllegalAccessException e) {
                                throw new ModelInterpolationException(
                                        "Failed to interpolate field: " + field + " on class: " + cls.getName(), e);
                            }
                        } finally {
                            field.setAccessible(isAccessible);
                        }
                    }
                }

                traverseObjectWithParents(cls.getSuperclass(), target);
            }
        }