You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2020/09/09 13:48:47 UTC

[sling-whiteboard] branch master updated: Move to processing rules

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


The following commit(s) were added to refs/heads/master by this push:
     new e296a36  Move to processing rules
e296a36 is described below

commit e296a36f48526c88b0b8b206ed4666b80d191b56
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Wed Sep 9 15:48:33 2020 +0200

    Move to processing rules
---
 .../rcaservlet/ChildrenProcessor.java              |  49 ---------
 .../rcaservlet/ContentProcessor.java               |  52 ---------
 .../sling/remotecontentapi/rcaservlet/P.java       |  10 +-
 .../JsonProcessor.java => xyz/ProcessingRule.java} |  10 +-
 .../xyz/ProcessingRuleSelector.java                | 117 +++++++++++++++++++++
 .../MetadataProcessor.java => xyz/UrlBuilder.java} |  37 +++++--
 .../sling/remotecontentapi/xyz/XyzContext.java     |  87 +++++++++++++++
 .../XyzServlet.java}                               |  35 +++---
 .../resources/SLING-INF/initial-content/ROOT.json  |   2 +-
 9 files changed, 259 insertions(+), 140 deletions(-)

diff --git a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/ChildrenProcessor.java b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/ChildrenProcessor.java
deleted file mode 100644
index 1ac5e11..0000000
--- a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/ChildrenProcessor.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.sling.remotecontentapi.rcaservlet;
-
-import javax.json.Json;
-import javax.json.JsonObjectBuilder;
-
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ValueMap;
-
-class ChildrenProcessor implements JsonProcessor {
-    @Override
-    public void process(PipelineContext pc) {
-        if(pc.resource.hasChildren()) {
-            for(Resource child: pc.resource.getChildren()) {
-                if(P.ignoreResource(child.getName())) {
-                    continue;
-                }
-                final JsonObjectBuilder childBuilder = Json.createObjectBuilder();
-                final ValueMap vm = child.adaptTo(ValueMap.class);
-                if(vm != null) {
-                    childBuilder.add("_path", child.getPath());
-                    childBuilder.add("_url", pc.pathToUrl(child.getPath()));
-                    P.maybeAdd(childBuilder, "sling:resourceType", "_resourceType", vm);
-                    P.maybeAddOneOf(childBuilder, "title", vm, P.TITLE_PROPS);
-                    P.maybeAddOneOf(childBuilder, "name", vm, P.NAME_PROPS);
-                }
-                pc.children.add(child.getName(), childBuilder.build());
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/ContentProcessor.java b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/ContentProcessor.java
deleted file mode 100644
index 32cb0b2..0000000
--- a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/ContentProcessor.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.sling.remotecontentapi.rcaservlet;
-
-import java.io.IOException;
-import java.io.StringReader;
-
-import javax.json.Json;
-import javax.json.JsonReader;
-
-import org.apache.sling.api.servlets.ServletResolver;
-import org.apache.sling.servlethelpers.internalrequests.ServletInternalRequest;
-
-class ContentProcessor implements JsonProcessor {
-
-    private final ServletResolver servletResolver;
-
-    ContentProcessor(ServletResolver servletResolver) {
-        this.servletResolver = servletResolver;
-    }
-
-    @Override
-    public void process(PipelineContext pc) throws IOException {
-        final String jsonResponse = new ServletInternalRequest(servletResolver, pc.resource)
-            .withSelectors("s:cagg")
-            .execute()
-            .getResponseAsString();
-
-        if(!jsonResponse.trim().isEmpty()) {
-            try (JsonReader parser = Json.createReader(new StringReader(jsonResponse))) {
-                pc.setContent(parser.readObject());
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/P.java b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/P.java
index fd275db..13a25d4 100644
--- a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/P.java
+++ b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/P.java
@@ -26,11 +26,11 @@ import javax.json.JsonObjectBuilder;
 import org.apache.sling.api.resource.ValueMap;
 
 public class P {
-    static final String [] IGNORE_RESOURCE_PREIX = { "jcr:", "rep:", "oak:" };
-    static final String [] TITLE_PROPS = { "jcr:title", "title" };
-    static final String [] NAME_PROPS = { "jcr:name", "name" };
-    static final String [] TEXT_PROPS = { "jcr:text", "text" };
-    static final String [] DESCRIPTION_PROPS = { "jcr:description", "description" };
+    public static final String [] IGNORE_RESOURCE_PREIX = { "jcr:", "rep:", "oak:" };
+    public static final String [] TITLE_PROPS = { "jcr:title", "title" };
+    public static final String [] NAME_PROPS = { "jcr:name", "name" };
+    public static final String [] TEXT_PROPS = { "jcr:text", "text" };
+    public static final String [] DESCRIPTION_PROPS = { "jcr:description", "description" };
 
     public static boolean maybeAdd(JsonObjectBuilder b, String propName, String jsonName, ValueMap vm) {
         if(vm.containsKey(propName)) {
diff --git a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/JsonProcessor.java b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/xyz/ProcessingRule.java
similarity index 78%
rename from remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/JsonProcessor.java
rename to remote-content-api/src/main/java/org/apache/sling/remotecontentapi/xyz/ProcessingRule.java
index 7aecc18..d18a7d8 100644
--- a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/JsonProcessor.java
+++ b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/xyz/ProcessingRule.java
@@ -17,8 +17,12 @@
  * under the License.
  */
 
-package org.apache.sling.remotecontentapi.rcaservlet;
+package org.apache.sling.remotecontentapi.xyz;
 
-public interface JsonProcessor {
-    void process(PipelineContext pc) throws Exception;
+import java.io.IOException;
+
+import javax.json.JsonObjectBuilder;
+
+interface ProcessingRule {
+    void process(JsonObjectBuilder b, UrlBuilder urlb) throws IOException;
 }
\ No newline at end of file
diff --git a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/xyz/ProcessingRuleSelector.java b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/xyz/ProcessingRuleSelector.java
new file mode 100644
index 0000000..08eda18
--- /dev/null
+++ b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/xyz/ProcessingRuleSelector.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.remotecontentapi.xyz;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import javax.json.Json;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonReader;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.servlets.ServletResolver;
+import org.apache.sling.remotecontentapi.rcaservlet.P;
+import org.apache.sling.servlethelpers.internalrequests.ServletInternalRequest;
+
+class ProcessingRuleSelector {
+    private final ServletResolver servletResolver;
+
+    enum RuleType {
+        METADATA, CHILDREN, CONTENT
+    };
+
+    static class DefaultMetadataRule implements ProcessingRule {
+        private final Resource resource;
+
+        DefaultMetadataRule(Resource r) {
+            resource = r;
+        }
+
+        @Override
+        public void process(JsonObjectBuilder b, UrlBuilder urlb) {
+            // nothing to for do for now
+        }
+    }
+
+    static class DefaultChildrenRule implements ProcessingRule {
+        private final Resource resource;
+
+        DefaultChildrenRule(Resource r) {
+            resource = r;
+        }
+
+        @Override
+        public void process(JsonObjectBuilder b, UrlBuilder urlb) {
+            for (Resource child : resource.getChildren()) {
+                if (P.ignoreResource(child.getName())) {
+                    continue;
+                }
+                final JsonObjectBuilder childBuilder = Json.createObjectBuilder();
+                final ValueMap vm = child.adaptTo(ValueMap.class);
+                if (vm != null) {
+                    childBuilder.add("_path", child.getPath());
+                    childBuilder.add("_url", urlb.pathToUrl(child.getPath()));
+                    P.maybeAdd(childBuilder, "sling:resourceType", "_resourceType", vm);
+                    P.maybeAddOneOf(childBuilder, "title", vm, P.TITLE_PROPS);
+                    P.maybeAddOneOf(childBuilder, "name", vm, P.NAME_PROPS);
+                }
+                b.add(child.getName(), childBuilder.build());
+            }
+        }
+    }
+
+    class DefaultContentRule implements ProcessingRule {
+        private final Resource resource;
+
+        DefaultContentRule(Resource r) {
+            resource = r;
+        }
+
+        @Override
+        public void process(JsonObjectBuilder b, UrlBuilder urlb) throws IOException {
+            final String jsonResponse = new ServletInternalRequest(servletResolver, resource)
+            .withSelectors("s:cagg")
+            .execute()
+            .getResponseAsString();
+
+        if(!jsonResponse.trim().isEmpty()) {
+            try (JsonReader parser = Json.createReader(new StringReader(jsonResponse))) {
+                b.add("xyz", parser.readObject());
+            }
+        }
+
+        }
+    }
+
+    ProcessingRuleSelector(ServletResolver sr) {
+        servletResolver = sr;
+    }
+
+    ProcessingRule getRule(RuleType t, Resource r) {
+        switch(t) {
+            case METADATA : return new DefaultMetadataRule(r);
+            case CHILDREN : return new DefaultChildrenRule(r);
+            case CONTENT : return new DefaultContentRule(r);
+        }
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/MetadataProcessor.java b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/xyz/UrlBuilder.java
similarity index 51%
rename from remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/MetadataProcessor.java
rename to remote-content-api/src/main/java/org/apache/sling/remotecontentapi/xyz/UrlBuilder.java
index 0811c75..6246729 100644
--- a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/MetadataProcessor.java
+++ b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/xyz/UrlBuilder.java
@@ -17,18 +17,33 @@
  * under the License.
  */
 
-package org.apache.sling.remotecontentapi.rcaservlet;
+package org.apache.sling.remotecontentapi.xyz;
 
-import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.SlingHttpServletRequest;
 
-class MetadataProcessor implements JsonProcessor {
-    @Override
-    public void process(PipelineContext pc) {
-        final ValueMap vm = pc.resource.adaptTo(ValueMap.class);
-        for(String key : vm.keySet()) {
-            if(!P.ignoreProperty(key) && P.isMetadata(key)) {
-                P.maybeAdd(pc.metadata, key, P.convertName(key), vm);
-            }
-        }
+class UrlBuilder {
+    private SlingHttpServletRequest request;
+
+    UrlBuilder(SlingHttpServletRequest request) {
+        this.request = request;
+    }
+
+    public String pathToUrlNoExtension(String path) {
+        return String.format(
+            "%s://%s:%d%s",
+            request.getScheme(),
+            request.getServerName(),
+            request.getServerPort(),
+            path
+        );
+    }
+
+    public String pathToUrl(String path) {
+        return String.format(
+            "%s.%s.%s",
+            pathToUrlNoExtension(path),
+            request.getRequestPathInfo().getSelectorString(),
+            request.getRequestPathInfo().getExtension()
+        );
     }
 }
\ No newline at end of file
diff --git a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/xyz/XyzContext.java b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/xyz/XyzContext.java
new file mode 100644
index 0000000..cf905e9
--- /dev/null
+++ b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/xyz/XyzContext.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.remotecontentapi.xyz;
+
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+
+class XyzContext {
+    private final SlingHttpServletRequest request;
+    public final Resource resource;
+    public final JsonObjectBuilder navigation;
+    public final JsonObjectBuilder metadata;
+    public final JsonObjectBuilder children;
+    public final JsonObjectBuilder content;
+
+    public XyzContext(SlingHttpServletRequest request) {
+        this.request = request;
+        resource = request.getResource();
+
+        navigation = Json.createObjectBuilder();
+        metadata = Json.createObjectBuilder();
+        children = Json.createObjectBuilder();
+        content = Json.createObjectBuilder();
+
+        navigation.add("self", pathToUrl(resource.getPath()));
+        if(resource.getParent() != null) {
+            navigation.add("parent", pathToUrl(resource.getParent().getPath()));
+        }
+        metadata.add("_id", resource.getPath());
+    }
+
+    private void maybeAdd(JsonObjectBuilder target, String key, JsonObjectBuilder src) {
+        final JsonObject jo = src.build();
+        if(!jo.isEmpty()) {
+            target.add(key, jo);
+        }
+    }
+
+    JsonObject build() {
+        final JsonObjectBuilder b = Json.createObjectBuilder();
+        maybeAdd(b, "navigation", navigation);
+        maybeAdd(b, "metadata", metadata);
+        maybeAdd(b, "children", children);
+        maybeAdd(b, "content", content);
+        return b.build();
+    }
+
+    public String pathToUrlNoJsonExtension(String path) {
+        return String.format(
+            "%s://%s:%d%s",
+            request.getScheme(),
+            request.getServerName(),
+            request.getServerPort(),
+            path
+        );
+    }
+
+    public String pathToUrl(String path) {
+        return String.format(
+            "%s.%s.%s",
+            pathToUrlNoJsonExtension(path),
+            request.getRequestPathInfo().getSelectorString(),
+            request.getRequestPathInfo().getExtension()
+        );
+    }
+}
\ No newline at end of file
diff --git a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/RemoteContentAccessServlet.java b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/xyz/XyzServlet.java
similarity index 68%
rename from remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/RemoteContentAccessServlet.java
rename to remote-content-api/src/main/java/org/apache/sling/remotecontentapi/xyz/XyzServlet.java
index 4e2f2a7..9f3ca5d 100644
--- a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/rcaservlet/RemoteContentAccessServlet.java
+++ b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/xyz/XyzServlet.java
@@ -17,28 +17,27 @@
  * under the License.
  */
 
-package org.apache.sling.remotecontentapi.rcaservlet;
+package org.apache.sling.remotecontentapi.xyz;
 
 import java.io.IOException;
 
 import javax.json.JsonObject;
 import javax.servlet.Servlet;
-import javax.servlet.http.HttpServletResponse;
 
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.servlets.ServletResolver;
 import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
 
-/** This is a first shot at this remote content API, that
- *  works well with the (simplistic) test content
- *  found under /content/articles
+/** Experimenting with dynamic generators, which might become
+ *  script-driven.
  */
 @Component(service = Servlet.class,
     property = {
-            "service.description=Sling Remote Content Access Servlet",
+            "service.description=Sling XYZ Servlet",
             "service.vendor=The Apache Software Foundation",
 
             "sling.servlet.resourceTypes=sling/servlet/default",
@@ -46,10 +45,10 @@ import org.osgi.service.component.annotations.Reference;
 
             "sling.servlet.methods=GET",
             "sling.servlet.methods=HEAD",
-            "sling.servlet.selectors=s:rca",
+            "sling.servlet.selectors=s:xyz",
             "sling.servlet.extension=json",
     })
-public class RemoteContentAccessServlet extends SlingSafeMethodsServlet {
+public class XyzServlet extends SlingSafeMethodsServlet {
     private static final long serialVersionUID = 1L;
 
     @Reference
@@ -57,18 +56,16 @@ public class RemoteContentAccessServlet extends SlingSafeMethodsServlet {
 
     @Override
     public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
-        final PipelineContext pc = new PipelineContext(request);
+        final XyzContext context = new XyzContext(request);
 
-        try {
-            new MetadataProcessor().process(pc);
-            new ChildrenProcessor().process(pc);
-            new ContentProcessor(servletResolver).process(pc);
-        } catch(IOException ioe) {
-            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ioe.getMessage());
-            return;
-        }
-        
-        final JsonObject json = pc.build();
+        final Resource r = request.getResource();
+        final UrlBuilder urlb = new UrlBuilder(request);
+        final ProcessingRuleSelector s = new ProcessingRuleSelector(servletResolver);
+        s.getRule(ProcessingRuleSelector.RuleType.METADATA, r).process(context.metadata, urlb);
+        s.getRule(ProcessingRuleSelector.RuleType.CHILDREN, r).process(context.children, urlb);
+        s.getRule(ProcessingRuleSelector.RuleType.CONTENT, r).process(context.content, urlb);
+
+        final JsonObject json = context.build();
 
         response.setCharacterEncoding("UTF-8");
         response.setContentType("application/json");
diff --git a/remote-content-api/src/main/resources/SLING-INF/initial-content/ROOT.json b/remote-content-api/src/main/resources/SLING-INF/initial-content/ROOT.json
index c0c1f5f..a5d2b28 100644
--- a/remote-content-api/src/main/resources/SLING-INF/initial-content/ROOT.json
+++ b/remote-content-api/src/main/resources/SLING-INF/initial-content/ROOT.json
@@ -1,4 +1,4 @@
 {
     "sling:resourceType" : "sling:redirect",
-    "sling:target" : "/content.s:rca.json"
+    "sling:target" : "/content.s:xyz.json"
 }
\ No newline at end of file