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/03 13:58:25 UTC
[sling-whiteboard] 02/02: Change to ResourceConverter
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 <bd...@apache.org>
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