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 819c093aba5d31b5706b8b9ddafe77c536940825 Author: Bertrand Delacretaz <[email protected]> AuthorDate: Thu Sep 3 15:58:08 2020 +0200 Change to ResourceConverter --- .../hardcodedfirstshot/ContentProcessor.java | 90 +++---------- .../HardcodedFirstShotServlet.java | 2 - .../remotecontentapi/hardcodedfirstshot/P.java | 36 +++--- .../hardcodedfirstshot/PipelineContext.java | 2 +- .../resourceconverter/ResourceConverter.java | 140 +++++++++++++++++++++ 5 files changed, 178 insertions(+), 92 deletions(-) diff --git a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/hardcodedfirstshot/ContentProcessor.java b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/hardcodedfirstshot/ContentProcessor.java index b145517..31b2761 100644 --- a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/hardcodedfirstshot/ContentProcessor.java +++ b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/hardcodedfirstshot/ContentProcessor.java @@ -19,90 +19,34 @@ package org.apache.sling.remotecontentapi.hardcodedfirstshot; -import javax.json.Json; -import javax.json.JsonObjectBuilder; - import org.apache.sling.api.resource.Resource; -import org.apache.sling.api.resource.ValueMap; +import org.apache.sling.remotecontentapi.resourceconverter.ResourceConverter; class ContentProcessor implements JsonProcessor { - private static final int MAX_RECURSION = 99; - private static final String JCR_CONTENT = "jcr:content"; - - @Override - public void process(PipelineContext pc) { - processResource(pc, pc.content, pc.resource, true, MAX_RECURSION); - } + static class ConverterContext implements ResourceConverter.Context { + private final PipelineContext pc; - private boolean isNodeType(ValueMap vm, String nodeType) { - return vm == null ? false : nodeType.equals(vm.get("jcr:primaryType", String.class)); - } - - private boolean ignoreResource(Resource r) { - final String name = r.getName(); - if(name.startsWith("cq:")) { - return !name.equals("cq:tags"); - } - final ValueMap vm = r.adaptTo(ValueMap.class); - if(isNodeType(vm, "cq:Page")) { - return true; + ConverterContext(PipelineContext pc) { + this.pc = pc; } - return false; - } - private String convertPropertyName(String name) { - if(!name.contains(":")) { - return name; - } else if(name.equals("jcr:title")) { - return "title"; - } else if(name.equals("jcr:description")) { - return "description"; - } else if(name.equals("sling:resourceType")) { - return "_resourceType"; - } else { - return null; - } - } - - private void processResource(PipelineContext pc, JsonObjectBuilder json, Resource r, boolean contentRootMode, int maxRecursion) { - if(maxRecursion <= 0) { - return; - } - final ValueMap vm = r.adaptTo(ValueMap.class); - - if(isNodeType(vm, "nt:file")) { - json.add("url", pc.pathToUrlNoJsonExtension(r.getPath())); - return; - } - - if(vm != null) { - for(String key : vm.keySet()) { - final String newName = convertPropertyName(key); - if(newName != null) { - P.maybeAdd(json, key, newName, vm); - } + @Override + public String getUrlForPath(String path, boolean includeApiSelectorsAndExtension) { + if(includeApiSelectorsAndExtension) { + return pc.pathToUrl(path); + } else { + return pc.pathToUrlNoJsonExtension(path); } } - if(contentRootMode) { - final Resource content = r.getChild(JCR_CONTENT); - if(content != null) { - json.addAll(visitContentResource(pc, content, maxRecursion - 1)); - } - } else if(r.hasChildren()) { - final JsonObjectBuilder b = Json.createObjectBuilder(); - for(Resource child : r.getChildren()) { - if(!ignoreResource(child)) { - b.add(child.getName(), visitContentResource(pc, child, maxRecursion - 1)); - } - } - json.addAll(b); + @Override + public String getRelativePath(Resource r) { + return r.getPath().substring(pc.resource.getPath().length()); } } - private JsonObjectBuilder visitContentResource(PipelineContext pc, Resource r, int maxRecursion) { - final JsonObjectBuilder b = Json.createObjectBuilder(); - processResource(pc, b, r, false, maxRecursion - 1); - return b; + @Override + public void process(PipelineContext pc) { + pc.content.addAll(new ResourceConverter(pc.resource, new ConverterContext(pc)).getJson()); } } \ No newline at end of file diff --git a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/hardcodedfirstshot/HardcodedFirstShotServlet.java b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/hardcodedfirstshot/HardcodedFirstShotServlet.java index ce48ef7..5cec04d 100644 --- a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/hardcodedfirstshot/HardcodedFirstShotServlet.java +++ b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/hardcodedfirstshot/HardcodedFirstShotServlet.java @@ -21,9 +21,7 @@ package org.apache.sling.remotecontentapi.hardcodedfirstshot; import java.io.IOException; -import javax.json.Json; import javax.json.JsonObject; -import javax.json.JsonObjectBuilder; import javax.servlet.Servlet; import org.apache.sling.api.SlingHttpServletRequest; diff --git a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/hardcodedfirstshot/P.java b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/hardcodedfirstshot/P.java index 168833f..1c1b2ad 100644 --- a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/hardcodedfirstshot/P.java +++ b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/hardcodedfirstshot/P.java @@ -25,33 +25,37 @@ import javax.json.JsonObjectBuilder; import org.apache.sling.api.resource.ValueMap; -class P { +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" }; - static boolean maybeAdd(JsonObjectBuilder b, String propName, String jsonName, ValueMap vm) { + public static boolean maybeAdd(JsonObjectBuilder b, String propName, String jsonName, ValueMap vm) { if(vm.containsKey(propName)) { final Object value = vm.get(propName); if(value != null) { - if(value instanceof Object[]) { - final JsonArrayBuilder a = Json.createArrayBuilder(); - for(Object o : (Object[])value) { - a.add(o.toString()); - } - b.add(jsonName, a.build()); - } else { - b.add(jsonName, value.toString()); - } + addValue(b, jsonName, value); } return true; } return false; } - static void maybeAddOneOf(JsonObjectBuilder b, String propName, ValueMap vm, String [] props) { + public static void addValue(JsonObjectBuilder json, String key, Object value) { + if(value instanceof Object[]) { + final JsonArrayBuilder a = Json.createArrayBuilder(); + for(Object o : (Object[])value) { + a.add(o.toString()); + } + json.add(key, a.build()); + } else { + json.add(key, value.toString()); + } + } + + public static void maybeAddOneOf(JsonObjectBuilder b, String propName, ValueMap vm, String [] props) { for(String prop : props) { if(maybeAdd(b, prop, propName, vm)) { break; @@ -59,11 +63,11 @@ class P { } } - static boolean ignoreProperty(String key) { + public static boolean ignoreProperty(String key) { return key.startsWith("jcr:"); } - static boolean ignoreResource(String name) { + public static boolean ignoreResource(String name) { for(String prefix : IGNORE_RESOURCE_PREIX) { if(name.startsWith(prefix)) { return true; @@ -72,11 +76,11 @@ class P { return false; } - static String convertName(String in) { + public static String convertName(String in) { return in.replace("sling:", "_"); } - static boolean isMetadata(String propName) { + public static boolean isMetadata(String propName) { return propName.startsWith("sling:"); } } \ No newline at end of file diff --git a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/hardcodedfirstshot/PipelineContext.java b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/hardcodedfirstshot/PipelineContext.java index 7ae342d..ada2197 100644 --- a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/hardcodedfirstshot/PipelineContext.java +++ b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/hardcodedfirstshot/PipelineContext.java @@ -61,8 +61,8 @@ public class PipelineContext { final JsonObjectBuilder b = Json.createObjectBuilder(); maybeAdd(b, "navigation", navigation); maybeAdd(b, "metadata", metadata); - maybeAdd(b, "content", content); maybeAdd(b, "children", children); + maybeAdd(b, "content", content); return b.build(); } diff --git a/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/resourceconverter/ResourceConverter.java b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/resourceconverter/ResourceConverter.java new file mode 100644 index 0000000..466cb33 --- /dev/null +++ b/remote-content-api/src/main/java/org/apache/sling/remotecontentapi/resourceconverter/ResourceConverter.java @@ -0,0 +1,140 @@ +/* + * 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.resourceconverter; + +import java.util.Map; + +import javax.json.Json; +import javax.json.JsonObjectBuilder; + +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ValueMap; +import org.apache.sling.remotecontentapi.hardcodedfirstshot.P; + +public class ResourceConverter { + public static interface Context { + /** Return the full URL to access the given path */ + String getUrlForPath(String path, boolean includeApiSelectorsAndExtension); + + /** Return r's path relative to the Resource being rendered */ + String getRelativePath(Resource r); + } + + private final Context context; + private final Resource resource; + + static interface ResourceProcessor { + void process(JsonObjectBuilder json, Resource r); + } + + static interface PropertyProcessor { + void process(JsonObjectBuilder json, String key, Object value); + } + + static class DefaultResourceProcessor implements ResourceProcessor { + private final Resource contentRoot; + private final Context context; + + DefaultResourceProcessor(Context context, Resource contentRoot) { + this.contentRoot = contentRoot; + this.context = context; + } + + public void process(JsonObjectBuilder json, Resource r) { + final JsonObjectBuilder b = Json.createObjectBuilder(); + final ValueMap vm = r.adaptTo(ValueMap.class); + if(vm != null) { + final PropertyProcessor pp = new DefaultPropertyProcessor(); + for(Map.Entry<String, Object> entry : vm.entrySet()) { + pp.process(json, entry.getKey(), entry.getValue()); + } + } + + // Special treatment for nt:file nodes + if(isNodeType(vm, "nt:file")) { + json.add("url", context.getUrlForPath(r.getPath(), false)); + return; + } + + if(r.getPath().equals(contentRoot.getPath())) { + // At the root, recurse only in the jcr:content child + final Resource content = r.getChild("jcr:content"); + if(content != null) { + process(b, content); + } + } else if(r.hasChildren()) { + for(Resource child : r.getChildren()) { + process(b, child); + } + } + + if(r.getName().equals("jcr:content")) { + json.add("_components", b.build()); + } else if(vm!=null && vm.containsKey("sling:resourceType")) { + final JsonObjectBuilder comp = Json.createObjectBuilder(); + comp.add("_name", r.getName()); + comp.addAll(b); + json.add("_component", comp); + } else { + json.add(r.getName(), b.build()); + } + } + } + + private static boolean isNodeType(ValueMap vm, String nodeType) { + return vm == null ? false : nodeType.equals(vm.get("jcr:primaryType", String.class)); + } + + static class DefaultPropertyProcessor implements PropertyProcessor { + public void process(JsonObjectBuilder json, String key, Object value) { + if(value != null) { + final String newName = processName(key); + if(newName != null) { + P.addValue(json, newName, value); + } + } + } + + private String processName(String propertyName) { + if(!propertyName.contains(":")) { + return propertyName; + } else if(propertyName.equals("jcr:title")) { + return "title"; + } else if(propertyName.equals("jcr:description")) { + return "description"; + } else if(propertyName.equals("sling:resourceType")) { + return "_resourceType"; + } else { + return null; + } + } + } + + public ResourceConverter(Resource r, Context ctx) { + context = ctx; + resource = r; + } + + public JsonObjectBuilder getJson() { + final JsonObjectBuilder b = Json.createObjectBuilder(); + new DefaultResourceProcessor(context, resource).process(b, resource); + return b; + } +} \ No newline at end of file
