private void mapResource()

in remote-content-api/document-aggregator/src/main/java/org/apache/sling/documentaggregator/impl/DocumentAggregatorImpl.java [60:122]


    private void mapResource(@NotNull Resource r, @NotNull DocumentTree.DocumentNode dest, 
        DocumentAggregator.Options opt, String documentResourceType, Annotations documentAnnot, boolean recurse) {

        final Annotations resourceAnnot = annotationsRegistry.getAnnotations(r.getResourceType());
        final DocumentTree.DocumentNode debug = opt.debug ? dest.addChild("sling:dmap:debug") : null;
        if(debug != null) {
            debug.addValue("sling:dmap:path", r.getPath());
            debug.addValue("sling:dmap:resourceType", r.getResourceType());
            debug.addValue("sling:dmap:documentAnnot", documentAnnot.toString());
            debug.addValue("sling:dmap:resourceAnnot", resourceAnnot.toString());
        }
    
        for(String name : documentAnnot.excludeNodeNames()) {
            if(name.equals(r.getName())) {
                if(debug != null) {
                    debug.addValue("sling:dmap:excluded", documentAnnot.toString());
                }
                log.debug("Resource {} excluded by node name ({})", r.getPath(), documentAnnot);
                return;
            }
        }

        log.debug("Mapping Resource {} as {}: {}", r.getPath(), r.getResourceType(), documentAnnot);
        propertiesMapper.mapProperties(dest, r, documentAnnot);

        // Resolve by path if specified
        // TODO detect cycles which might lead to infinite loops
        resourceAnnot.resolveByPathPropertyNames().forEach(derefPathPropertyName -> {
            log.debug("Resolving by path {} on {}", r.getPath(), derefPathPropertyName);
            final ValueMap vm = r.adaptTo(ValueMap.class);
            final String derefPath = vm == null ? null : vm.get(derefPathPropertyName, String.class);
            if(derefPath != null) {
                final Resource dereferenced = r.getResourceResolver().getResource(derefPath);
                if(dereferenced != null) {
                    final DocumentTree.DocumentNode derefNode = dest.addChild("sling:dmap:resolved");
                    derefNode.addValue("sling:dmap:resolvedFrom", derefPathPropertyName);
                    derefNode.addValue("sling:dmap:resolvePath", derefPath);
                    mapResource(dereferenced, derefNode, opt, documentResourceType, documentAnnot, recurse);
                } else if(debug != null) {
                    debug.addValue("Resolve by path " + derefPathPropertyName, "not found:" + derefPath);
                }
            }
        });

        // TODO detect too much recursion?
        if(recurse) {
            log.debug("Recursing into {}", r.getPath());
            for(Resource child : r.getChildren()) {
                final boolean visit = resourceAnnot.visitChildResource(child.getName());
                log.debug("child resource {} visit decision {}", child.getName(), visit);
                if(!visit) {
                    continue;
                }
                final String childResourceType = child.getResourceType();
                if(annotationsRegistry.getAnnotations(childResourceType).visitContent()) {
                    final DocumentTree.DocumentNode childDest = dest.addChild(child.getName());
                    mapResource(child, childDest, opt, childResourceType, documentAnnot, true);
                }
            }
        } else if(log.isDebugEnabled()) {
            log.debug("NOT recursing into {}", r.getPath());
        }
    }