This is an automated email from the ASF dual-hosted git repository.

bdelacretaz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git

commit 3eff62c8cba12b1d912eda7c35ae037d5d642fa0
Author: Bertrand Delacretaz <[email protected]>
AuthorDate: Thu May 6 18:25:40 2021 +0200

    Add sling:dmap:debug
---
 .../documentmapper/api/Annotations.java            | 50 +++++++++++++++----
 .../documentmapper/api/DocumentMapper.java         | 11 +++-
 .../documentmapper/impl/ContentDocumentMapper.java | 58 ++++++++++++++++------
 .../samples/graphql/DocumentDataFetcher.java       | 10 +---
 .../samples/graphql/DocumentsDataFetcher.java      | 17 ++++---
 .../annotations/AnnotationsRegistryImpl.java       | 23 ++++++---
 .../apps/samples/graphql/GQLschema.jsp             |  4 +-
 7 files changed, 124 insertions(+), 49 deletions(-)

diff --git 
a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/documentmapper/api/Annotations.java
 
b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/documentmapper/api/Annotations.java
index a0402a0..4f00c4f 100644
--- 
a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/documentmapper/api/Annotations.java
+++ 
b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/documentmapper/api/Annotations.java
@@ -34,10 +34,12 @@ public class Annotations {
     private boolean navigable;
     private boolean visitContent;
     private boolean documentRoot;
+    private String childSubstitutePath;
     private Pattern visitContentResourceNamePattern;
     private Pattern includePropertyPattern;
     private Pattern excludePropertyPattern;
-    private List<String> dereferenceByPathProperties;
+    private List<String> resolveByPathProperties;
+    private List<String> excludeNodeNames;
 
     private Annotations(String resourceType) {
         this.resourceType = resourceType;
@@ -46,7 +48,7 @@ public class Annotations {
     @Override
     public String toString() {
         return String.format(
-            "RT=%s N=%b VC=%b DR=%b VCRN=%s IP=%s EP=%s DR=%s",
+            "RT=%s N=%b VC=%b DR=%b VCRN=%s IP=%s EP=%s DR=%s ENN=%s",
             resourceType,
             navigable,
             visitContent,
@@ -54,7 +56,8 @@ public class Annotations {
             visitContentResourceNamePattern,
             includePropertyPattern,
             excludePropertyPattern,
-            dereferenceByPathProperties
+            resolveByPathProperties,
+            excludeNodeNames
         );
     }
 
@@ -89,14 +92,26 @@ public class Annotations {
         return result;
     }
 
-    public Collection<String> dereferenceByPathPropertyNames() {
-        if(dereferenceByPathProperties != null) {
-            return dereferenceByPathProperties;
+    public Collection<String> resolveByPathPropertyNames() {
+        if(resolveByPathProperties != null) {
+            return resolveByPathProperties;
         } else {
             return Collections.emptyList();
         }
     }
 
+    public Collection<String> excludeNodeNames() {
+        if(excludeNodeNames != null) {
+            return excludeNodeNames;
+        } else {
+            return Collections.emptyList();
+        }
+    }
+
+    public String childSubstitutePath() {
+        return childSubstitutePath;
+    }
+
     public static Builder forResourceType(String resourceType) {
         return new Builder(resourceType);
     }
@@ -137,16 +152,31 @@ public class Annotations {
             return this;
         }
 
-        public Builder withDereferenceByPathProperties(String ... names) {
-            if(target.dereferenceByPathProperties == null) {
-                target.dereferenceByPathProperties = new ArrayList<String>();
+        public Builder withResolveByPathPropertyNames(String ... names) {
+            if(target.resolveByPathProperties == null) {
+                target.resolveByPathProperties = new ArrayList<String>();
+            }
+            for(String name : names) {
+                target.resolveByPathProperties.add(name);
+            }
+            return this;
+        }
+
+        public Builder withExcludeNodeNames(String ... names) {
+            if(target.excludeNodeNames == null) {
+                target.excludeNodeNames = new ArrayList<String>();
             }
             for(String name : names) {
-                target.dereferenceByPathProperties.add(name);
+                target.excludeNodeNames.add(name);
             }
             return this;
         }
 
+        public Builder withChildSubstituePath(String path) {
+            target.childSubstitutePath = path;
+            return this;
+        }
+
         public Annotations build() {
             return target;
         }
diff --git 
a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/documentmapper/api/DocumentMapper.java
 
b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/documentmapper/api/DocumentMapper.java
index 94e47d8..31435d0 100644
--- 
a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/documentmapper/api/DocumentMapper.java
+++ 
b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/documentmapper/api/DocumentMapper.java
@@ -34,6 +34,15 @@ public interface DocumentMapper {
     interface UrlBuilder {
         String pathToUrl(String path);
     }
+
+    public static class Options {
+        public final boolean debug;
+        public final UrlBuilder urlBuilder;
+        public Options(boolean debug, UrlBuilder urlBuilder) {
+            this.debug = debug;
+            this.urlBuilder = urlBuilder;
+        }
+    }
     
-    void map(@NotNull Resource r, @NotNull MappingTarget.TargetNode 
destination, UrlBuilder urlb);
+    void map(@NotNull Resource r, @NotNull MappingTarget.TargetNode 
destination, Options opt);
 }
\ No newline at end of file
diff --git 
a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/documentmapper/impl/ContentDocumentMapper.java
 
b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/documentmapper/impl/ContentDocumentMapper.java
index 40cbfda..7561acc 100644
--- 
a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/documentmapper/impl/ContentDocumentMapper.java
+++ 
b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/documentmapper/impl/ContentDocumentMapper.java
@@ -41,32 +41,62 @@ public class ContentDocumentMapper implements 
DocumentMapper {
     private AnnotationsRegistry annotationsRegistry;
 
     @Override
-    public void map(@NotNull Resource r, @NotNull MappingTarget.TargetNode 
dest, UrlBuilder urlb) {
-        final String resourceType = r.getResourceType();
-        final Annotations annot = 
annotationsRegistry.getAnnotations(resourceType);
-        dest.addValue("path", r.getPath());
+    public void map(@NotNull Resource originalResource, @NotNull 
MappingTarget.TargetNode dest, DocumentMapper.Options opt) {
+        Annotations annot = 
annotationsRegistry.getAnnotations(originalResource.getResourceType());
+        dest.addValue("path", originalResource.getPath());
+        final String substPath = annot.childSubstitutePath();
+        Resource r = originalResource;
+        if(substPath != null) {
+            r = r.getChild(substPath);
+            if(r == null) {
+                throw new RuntimeException("Child " + substPath + " of 
resource " + originalResource.getPath() + "not found");
+            }
+            annot = annotationsRegistry.getAnnotations(r.getResourceType());
+        }
         log.debug("Top level Resource map {} as {}: {}", r.getPath(), 
r.getResourceType(), annot);
-        mapResource(r, dest, urlb, resourceType, annot, 
annot.isDocumentRoot());
+        mapResource(r, dest, opt, r.getResourceType(), annot, 
annot.isDocumentRoot());
     }
 
     private void mapResource(@NotNull Resource r, @NotNull 
MappingTarget.TargetNode dest, 
-        UrlBuilder urlb, String documentResourceType, Annotations 
documentAnnot, boolean recurse) {
+        DocumentMapper.Options opt, String documentResourceType, Annotations 
documentAnnot, boolean recurse) {
+
+        final Annotations resourceAnnot = 
annotationsRegistry.getAnnotations(r.getResourceType());
+        final MappingTarget.TargetNode 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);
-        final Annotations thisAnnot = 
annotationsRegistry.getAnnotations(r.getResourceType());
 
-        // Dereference by path if specified
+        // Resolve by path if specified
         // TODO detect cycles which might lead to infinite loops
-        
thisAnnot.dereferenceByPathPropertyNames().forEach(derefPathPropertyName -> {
-            log.debug("Dereferencing {} on {}", r.getPath(), 
derefPathPropertyName);
+        
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 MappingTarget.TargetNode derefNode = 
dest.addChild("dereferenced_by_" + derefPathPropertyName);
-                    mapResource(dereferenced, derefNode, urlb, 
documentResourceType, documentAnnot, recurse);
+                    final MappingTarget.TargetNode 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);
                 }
             }
         });
@@ -75,7 +105,7 @@ public class ContentDocumentMapper implements DocumentMapper 
{
         if(recurse) {
             log.debug("Recursing into {}", r.getPath());
             for(Resource child : r.getChildren()) {
-                final boolean visit = 
thisAnnot.visitChildResource(child.getName());
+                final boolean visit = 
resourceAnnot.visitChildResource(child.getName());
                 log.debug("child resource {} visit decision {}", 
child.getName(), visit);
                 if(!visit) {
                     continue;
@@ -83,7 +113,7 @@ public class ContentDocumentMapper implements DocumentMapper 
{
                 final String childResourceType = child.getResourceType();
                 
if(annotationsRegistry.getAnnotations(childResourceType).visitContent()) {
                     final MappingTarget.TargetNode childDest = 
dest.addChild(child.getName());
-                    mapResource(child, childDest, urlb, childResourceType, 
documentAnnot, true);
+                    mapResource(child, childDest, opt, childResourceType, 
documentAnnot, true);
                 }
             }
         } else if(log.isDebugEnabled()) {
diff --git 
a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/DocumentDataFetcher.java
 
b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/DocumentDataFetcher.java
index 69aa950..ff432e0 100644
--- 
a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/DocumentDataFetcher.java
+++ 
b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/DocumentDataFetcher.java
@@ -42,13 +42,6 @@ public class DocumentDataFetcher implements 
SlingDataFetcher<Object> {
     @Reference
     private DocumentMapper documentMapper;
 
-    static final UrlBuilder DUMMY_URL_BUILDER = new UrlBuilder() {
-        @Override
-        public String pathToUrl(String path) {
-            return getClass().getName();
-        }
-    };
-    
     @Override
     public @Nullable Object get(@NotNull SlingDataFetcherEnvironment e) throws 
Exception {
         final String path = e.getArgument("path");
@@ -56,13 +49,14 @@ public class DocumentDataFetcher implements 
SlingDataFetcher<Object> {
         final Map<String, Object> data = new HashMap<>();
         data.put("path", path);
         data.put("selectors", e.getArgument("selectors"));
+        final DocumentMapper.Options opt = new 
DocumentMapper.Options(e.getArgument("debug", true), new UrlBuilderStub());
 
         // Get the target Resource
         final Resource target = 
e.getCurrentResource().getResourceResolver().getResource(path);
 
         // Use DocumentMapper to build the body
         final MappingTarget.TargetNode body = mappingTarget.newTargetNode();
-        documentMapper.map(target, body, DUMMY_URL_BUILDER);
+        documentMapper.map(target, body, opt);
         body.close();
         data.put("body", body.adaptTo(Map.class));
         return data;
diff --git 
a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/DocumentsDataFetcher.java
 
b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/DocumentsDataFetcher.java
index 8f00320..581a905 100644
--- 
a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/DocumentsDataFetcher.java
+++ 
b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/DocumentsDataFetcher.java
@@ -45,22 +45,21 @@ public class DocumentsDataFetcher implements 
SlingDataFetcher<Object> {
     @Reference
     private DocumentMapper documentMapper;
 
-    private void addDocumentData(final Map<String, Object> data, String key, 
Resource r, DocumentMapper mapper) {
+    private void addDocumentData(final Map<String, Object> data, String key, 
Resource r, DocumentMapper mapper, DocumentMapper.Options opt) {
         final MappingTarget.TargetNode target = mappingTarget.newTargetNode();
-        mapper.map(r, target, new UrlBuilderStub());
+        mapper.map(r, target, opt);
         target.close();
         data.put(key, target.adaptTo(Map.class));
 
     }
 
-    private Map<String, Object> toDocument(Resource r) {
+    private Map<String, Object> toDocument(Resource r, DocumentMapper.Options 
opt) {
         final Map<String, Object> data = new HashMap<>();
         data.put("path", r.getPath());
 
-        // TODO how to find out whether those fields are actually needed
-        // or how to evaluate them lazily
-        addDocumentData(data, "body", r, documentMapper);
-        addDocumentData(data, "summary", r, documentMapper);
+        // TODO for now those are the same...
+        addDocumentData(data, "body", r, documentMapper, opt);
+        addDocumentData(data, "summary", r, documentMapper, opt);
 
         return data;
     }
@@ -70,6 +69,8 @@ public class DocumentsDataFetcher implements 
SlingDataFetcher<Object> {
         // Use a suffix as we might not keep these built-in language in the 
long term
         final String langSuffix = "2020";
 
+        final DocumentMapper.Options opt = new 
DocumentMapper.Options(e.getArgument("debug", true), new UrlBuilderStub());
+
         String lang = e.getArgument("lang", "xpath" + langSuffix);
         if(!lang.endsWith(langSuffix)) {
             throw new RuntimeException("Query langage must end with suffix " + 
langSuffix);
@@ -81,7 +82,7 @@ public class DocumentsDataFetcher implements 
SlingDataFetcher<Object> {
         final ResourceResolver resolver = 
e.getCurrentResource().getResourceResolver();
         final Iterator<Resource> it = resolver.findResources(query, lang);
         while(it.hasNext()) {
-            result.add(toDocument(it.next()));
+            result.add(toDocument(it.next(), opt));
         }
         return result;
     }
diff --git 
a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/annotations/AnnotationsRegistryImpl.java
 
b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/annotations/AnnotationsRegistryImpl.java
index 1750928..4915be7 100644
--- 
a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/annotations/AnnotationsRegistryImpl.java
+++ 
b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/annotations/AnnotationsRegistryImpl.java
@@ -50,28 +50,39 @@ public class AnnotationsRegistryImpl implements 
AnnotationsRegistry {
 
     @Activate
     public void activate() {
+        final String generalIgnoreProperties = 
"jcr:.*|cq:.*|crs:.*|tiff:.*|xmpMM:.*|xmp:.*|psAux:.*";
+        final String [] generalExcludeNodeNames = { "xmpMM:History", 
"xmpMM:DerivedFrom", "metadata" };
+
         add(
             Annotations.forResourceType("cq:Page")
             .withDocumentRoot(true)
+            .withChildSubstituePath("jcr:content")
             .withNavigable(true)
             .withVisitContent(true)
-            .withVisitContentChildResourceNamePattern("jcr:content")
-            .withIncludePropertyPattern("sling:ResourceType|cq:tags")
-            .withExcludePropertyPattern("jcr:.*|cq:.*")
+            
.withIncludePropertyPattern("sling:ResourceType|cq:tags|jcr:title|jcr:description")
+            .withExcludePropertyPattern(generalIgnoreProperties)
+            .withExcludeNodeNames(generalExcludeNodeNames)
         );
         add(
             Annotations.forResourceType("wknd/components/page")
             // TODO shall we only have "visit content"?
             .withDocumentRoot(true)
             .withVisitContent(true)
-            .withIncludePropertyPattern("sling:ResourceType|jcr:description")
-            .withExcludePropertyPattern("jcr:.*|cq:.*")
+            
.withIncludePropertyPattern("sling:ResourceType|jcr:title|jcr:description")
+            .withExcludePropertyPattern(generalIgnoreProperties)
+            .withExcludeNodeNames(generalExcludeNodeNames)
         );
         add(
             Annotations.forResourceType("wknd/components/image")
             .withVisitContent(true)
-            .withDereferenceByPathProperties("fileReference")
+            .withResolveByPathPropertyNames("fileReference")
+        );
+        add(
+            Annotations.forResourceType("wknd/components/contentfragment")
+            .withVisitContent(true)
+            .withResolveByPathPropertyNames("fragmentPath")
         );
+        
         /*
         add(
             Builder.forResourceType("sling:Folder")
diff --git 
a/remote-content-api/sample-graphql-api/src/main/resources/SLING-INF/initial-content/apps/samples/graphql/GQLschema.jsp
 
b/remote-content-api/sample-graphql-api/src/main/resources/SLING-INF/initial-content/apps/samples/graphql/GQLschema.jsp
index 425ff57..79361a2 100644
--- 
a/remote-content-api/sample-graphql-api/src/main/resources/SLING-INF/initial-content/apps/samples/graphql/GQLschema.jsp
+++ 
b/remote-content-api/sample-graphql-api/src/main/resources/SLING-INF/initial-content/apps/samples/graphql/GQLschema.jsp
@@ -22,8 +22,8 @@
 scalar Object
 
 type Query {
-  document(path : String, selectors : [String]) : Document 
@fetcher(name:"samples/document")
-  documents(lang: String, query : String, selectors : [String]) : [Document] 
@fetcher(name:"samples/documents")
+  document(path : String, selectors : [String], debug : Boolean) : Document 
@fetcher(name:"samples/document")
+  documents(lang: String, query : String, selectors : [String], debug : 
Boolean) : [Document] @fetcher(name:"samples/documents")
 }
 
 type Mutation {

Reply via email to