private void cascade()

in bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java [349:384]


        private void cascade(GroupStrategy groups, Consumer<ConstraintViolation<T>> sink) {
            descriptor.getConstrainedContainerElementTypes().stream()
                .filter(d -> d.isCascaded() || !d.getConstrainedContainerElementTypes().isEmpty())
                .flatMap(d -> ComposedD.unwrap(d, ContainerElementTypeD.class)).forEach(d -> {
                    final ValueExtractor<?> runtimeTypeValueExtractor =
                        context.getValidatorContext().getValueExtractors().find(context.runtimeKey(d.getKey()));
                    ExtractValues.extract(context, d.getKey(), runtimeTypeValueExtractor).stream()
                        .filter(e -> !e.isRecursive()).map(e -> new ContainerElementCascadeFrame(this, d, e))
                        .forEach(f -> f.recurse(groups, sink));
                });
            if (!descriptor.isCascaded()) {
                return;
            }
            if (descriptor instanceof PropertyDescriptor) {
                final TraversableResolver traversableResolver = validatorContext.getTraversableResolver();

                final Object traversableObject =
                    Optional.ofNullable(context.getParent()).map(GraphContext::getValue).orElse(null);

                final PathImpl pathToTraversableObject = context.getPath();
                final NodeImpl traversableProperty = pathToTraversableObject.removeLeafNode();

                try {
                    if (!traversableResolver.isCascadable(traversableObject, traversableProperty, getRootBeanClass(),
                        pathToTraversableObject, ((PropertyD<?>) descriptor).getElementType())) {
                        return;
                    }
                } catch (ValidationException ve) {
                    throw ve;
                } catch (Exception e) {
                    throw new ValidationException(e);
                }
            }
            multiplex().filter(context -> context.getValue() != null && !context.isRecursive())
                .map(context -> new BeanFrame<>(this, context)).forEach(b -> b.process(groups, sink));
        }