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/08/26 14:44:06 UTC
[sling-whiteboard] 02/02: Basic navigation,
properties filtering and api/metadata/content/children output
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 c74d4f6a3709d79479fc8a4300f885ce297c7221
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Wed Aug 26 16:43:46 2020 +0200
Basic navigation, properties filtering and api/metadata/content/children output
---
dokapi/.gitignore | 2 +
dokapi/pom.xml | 18 ++++-
.../sling/dokapi/impl/ChildrenProcessor.java | 49 +++++++++++++
.../apache/sling/dokapi/impl/ContentProcessor.java | 34 +++++++++
.../apache/sling/dokapi/impl/DokapiServlet.java | 64 +++++++++++++++++
.../apache/sling/dokapi/impl/JsonProcessor.java | 24 +++++++
.../sling/dokapi/impl/MetadataProcessor.java | 34 +++++++++
.../main/java/org/apache/sling/dokapi/impl/P.java | 76 ++++++++++++++++++++
.../apache/sling/dokapi/impl/PipelineContext.java | 81 ++++++++++++++++++++++
9 files changed, 381 insertions(+), 1 deletion(-)
diff --git a/dokapi/.gitignore b/dokapi/.gitignore
new file mode 100644
index 0000000..f87a37c
--- /dev/null
+++ b/dokapi/.gitignore
@@ -0,0 +1,2 @@
+conf/
+launcher/
diff --git a/dokapi/pom.xml b/dokapi/pom.xml
index 232a9fa..c6dcde1 100644
--- a/dokapi/pom.xml
+++ b/dokapi/pom.xml
@@ -82,7 +82,17 @@
<commandlineArgs>-s src/test/resources/features/feature-sling12.json -af src/test/resources/features/feature-dokapi-test.json</commandlineArgs>
</configuration>
</plugin>
- </plugins>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>launcher/**</exclude>
+ <exclude>conf/**</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+</plugins>
</build>
<dependencies>
@@ -119,6 +129,12 @@
<version>0.0.2</version>
<scope>runtime</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.commons.johnzon</artifactId>
+ <version>1.2.2</version>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/dokapi/src/main/java/org/apache/sling/dokapi/impl/ChildrenProcessor.java b/dokapi/src/main/java/org/apache/sling/dokapi/impl/ChildrenProcessor.java
new file mode 100644
index 0000000..7ba1fa7
--- /dev/null
+++ b/dokapi/src/main/java/org/apache/sling/dokapi/impl/ChildrenProcessor.java
@@ -0,0 +1,49 @@
+/*
+ * 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.dokapi.impl;
+
+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/dokapi/src/main/java/org/apache/sling/dokapi/impl/ContentProcessor.java b/dokapi/src/main/java/org/apache/sling/dokapi/impl/ContentProcessor.java
new file mode 100644
index 0000000..0f4c9f4
--- /dev/null
+++ b/dokapi/src/main/java/org/apache/sling/dokapi/impl/ContentProcessor.java
@@ -0,0 +1,34 @@
+/*
+ * 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.dokapi.impl;
+
+import org.apache.sling.api.resource.ValueMap;
+
+class ContentProcessor 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.content, key, P.convertName(key), vm);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/dokapi/src/main/java/org/apache/sling/dokapi/impl/DokapiServlet.java b/dokapi/src/main/java/org/apache/sling/dokapi/impl/DokapiServlet.java
new file mode 100644
index 0000000..346b7b9
--- /dev/null
+++ b/dokapi/src/main/java/org/apache/sling/dokapi/impl/DokapiServlet.java
@@ -0,0 +1,64 @@
+/*
+ * 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.dokapi.impl;
+
+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;
+import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
+import org.osgi.service.component.annotations.Component;
+
+/** Main Dokapi servlet */
+@Component(service = Servlet.class,
+ name="org.apache.sling.servlets.get.DefaultGetServlet",
+ property = {
+ "service.description=Sling Dokapi Servlet",
+ "service.vendor=The Apache Software Foundation",
+
+ "sling.servlet.resourceTypes=sling/servlet/default",
+ "sling.servlet.prefix:Integer=-1",
+
+ "sling.servlet.methods=GET",
+ "sling.servlet.methods=HEAD",
+ "sling.servlet.selectors=dkp",
+ "sling.servlet.extension=json",
+ })
+public class DokapiServlet extends SlingSafeMethodsServlet {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
+ final PipelineContext pc = new PipelineContext(request);
+ new MetadataProcessor().process(pc);
+ new ChildrenProcessor().process(pc);
+ new ContentProcessor().process(pc);
+ final JsonObject json = pc.build();
+
+ response.setCharacterEncoding("UTF-8");
+ response.setContentType("application/json");
+ response.getWriter().write(json.toString());
+ }
+}
\ No newline at end of file
diff --git a/dokapi/src/main/java/org/apache/sling/dokapi/impl/JsonProcessor.java b/dokapi/src/main/java/org/apache/sling/dokapi/impl/JsonProcessor.java
new file mode 100644
index 0000000..228b974
--- /dev/null
+++ b/dokapi/src/main/java/org/apache/sling/dokapi/impl/JsonProcessor.java
@@ -0,0 +1,24 @@
+/*
+ * 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.dokapi.impl;
+
+public interface JsonProcessor {
+ void process(PipelineContext pc);
+}
\ No newline at end of file
diff --git a/dokapi/src/main/java/org/apache/sling/dokapi/impl/MetadataProcessor.java b/dokapi/src/main/java/org/apache/sling/dokapi/impl/MetadataProcessor.java
new file mode 100644
index 0000000..9ed90f4
--- /dev/null
+++ b/dokapi/src/main/java/org/apache/sling/dokapi/impl/MetadataProcessor.java
@@ -0,0 +1,34 @@
+/*
+ * 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.dokapi.impl;
+
+import org.apache.sling.api.resource.ValueMap;
+
+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);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/dokapi/src/main/java/org/apache/sling/dokapi/impl/P.java b/dokapi/src/main/java/org/apache/sling/dokapi/impl/P.java
new file mode 100644
index 0000000..1f5bce6
--- /dev/null
+++ b/dokapi/src/main/java/org/apache/sling/dokapi/impl/P.java
@@ -0,0 +1,76 @@
+/*
+ * 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.dokapi.impl;
+
+import javax.json.Json;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObjectBuilder;
+
+import org.apache.sling.api.resource.ValueMap;
+
+class P {
+ 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) {
+ 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());
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ static void maybeAddOneOf(JsonObjectBuilder b, String propName, ValueMap vm, String [] props) {
+ for(String prop : NAME_PROPS) {
+ if(maybeAdd(b, prop, propName, vm)) {
+ break;
+ }
+ }
+ }
+
+ static boolean ignoreProperty(String key) {
+ return key.startsWith("jcr:");
+ }
+
+ static boolean ignoreResource(String name) {
+ return name.startsWith("rep:");
+ }
+
+ static String convertName(String in) {
+ return in.replace("sling:", "_");
+ }
+
+ static boolean isMetadata(String propName) {
+ return propName.startsWith("sling:");
+ }
+}
\ No newline at end of file
diff --git a/dokapi/src/main/java/org/apache/sling/dokapi/impl/PipelineContext.java b/dokapi/src/main/java/org/apache/sling/dokapi/impl/PipelineContext.java
new file mode 100644
index 0000000..06e6d8e
--- /dev/null
+++ b/dokapi/src/main/java/org/apache/sling/dokapi/impl/PipelineContext.java
@@ -0,0 +1,81 @@
+/*
+ * 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.dokapi.impl;
+
+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;
+
+public class PipelineContext {
+ private final SlingHttpServletRequest request;
+ public final Resource resource;
+ public final JsonObjectBuilder api;
+ public final JsonObjectBuilder metadata;
+ public final JsonObjectBuilder children;
+ public final JsonObjectBuilder content;
+
+ PipelineContext(SlingHttpServletRequest request) {
+ this.request = request;
+ resource = request.getResource();
+
+ // TODO should create these on demand
+ api = Json.createObjectBuilder();
+ metadata = Json.createObjectBuilder();
+ children = Json.createObjectBuilder();
+ content = Json.createObjectBuilder();
+
+ api.add("_url", pathToUrl(resource.getPath()));
+ if(resource.getParent() != null) {
+ api.add("_parentUrl", pathToUrl(resource.getParent().getPath()));
+ }
+ api.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, "api", api);
+ maybeAdd(b, "metadata", metadata);
+ maybeAdd(b, "content", content);
+ maybeAdd(b, "children", children);
+ return b.build();
+ }
+
+ String pathToUrl(String path) {
+ return String.format(
+ "%s://%s:%d%s.%s.%s",
+ request.getScheme(),
+ request.getServerName(),
+ request.getServerPort(),
+ path,
+ request.getRequestPathInfo().getSelectorString(),
+ request.getRequestPathInfo().getExtension()
+ );
+ }
+}
\ No newline at end of file