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-org-apache-sling-capabilities.git
commit b8cac3213390833a89fd4f6724031dce1364bab9 Author: Bertrand Delacretaz <[email protected]> AuthorDate: Wed Oct 10 15:57:19 2018 +0200 Add SlingServletsSource --- pom.xml | 5 + .../defaultsources/SlingServletsSource.java | 123 +++++++++++++++++++++ .../internal/JSONCapabilitiesWriter.java | 4 + .../internal/CapabilitesServletTest.java | 2 +- .../internal/JSONCapabilitiesWriterTest.java | 4 +- 5 files changed, 135 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index d3a5d61..4908ea9 100644 --- a/pom.xml +++ b/pom.xml @@ -57,6 +57,11 @@ <dependencies> <dependency> <groupId>org.osgi</groupId> + <artifactId>org.osgi.service.metatype.annotations</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> <artifactId>org.osgi.service.component.annotations</artifactId> <scope>provided</scope> </dependency> diff --git a/src/main/java/org/apache/sling/capabilities/defaultsources/SlingServletsSource.java b/src/main/java/org/apache/sling/capabilities/defaultsources/SlingServletsSource.java new file mode 100644 index 0000000..9e00636 --- /dev/null +++ b/src/main/java/org/apache/sling/capabilities/defaultsources/SlingServletsSource.java @@ -0,0 +1,123 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ 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.capabilities.defaultsources; + +import java.util.HashMap; +import java.util.Map; +import javax.servlet.Servlet; +import org.apache.sling.capabilities.CapabilitiesSource; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.ServiceReference; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.metatype.annotations.AttributeDefinition; +import org.osgi.service.metatype.annotations.Designate; +import org.osgi.service.metatype.annotations.ObjectClassDefinition; + +@Component(service = CapabilitiesSource.class) +@Designate( + ocd = SlingServletsSource.Config.class, + factory = true +) +public class SlingServletsSource implements CapabilitiesSource { + + @ObjectClassDefinition( + name = "Sling Servlets Capabilities Source", + description = "Provides information about available Sling Servlets" + ) + public static @interface Config { + @AttributeDefinition( + name = "LDAP filter", + description = "OSGi LDAP filter to select servlets to consider for the provided capabilites" + ) + String servletsLdapFilter() default ""; + + @AttributeDefinition( + name = "Capabilities Namespace", + description = "Unique namespace that identifies this set of capabilities" + ) + String capabilitiesNamespace(); + } + + private String namespace; + private String ldapFilter; + private BundleContext bundleContext; + + private static final String SLING_SERVLET_PROPERTY_PREFIX = "sling.servlet."; + + @Activate + public void activate(Config cfg, ComponentContext ctx) { + this.bundleContext = ctx.getBundleContext(); + this.namespace = cfg.capabilitiesNamespace(); + this.ldapFilter = cfg.servletsLdapFilter(); + } + + @Override + public String getNamespace() { + return namespace; + } + + @Override + public Map<String, Object> getCapabilities() throws Exception { + final Map<String, Object> result = new HashMap<>(); + final ServiceReference [] refs = bundleContext.getServiceReferences(Servlet.class.getName(), ldapFilter); + if(refs != null) { + for(ServiceReference ref : refs) { + result.put(classOf(ref), getCapabilities(ref)); + } + } + return result; + } + + private static Map<String, Object> getCapabilities(ServiceReference ref) { + final Map<String, Object> result = new HashMap<>(); + for(String key : ref.getPropertyKeys()) { + if(key.startsWith(SLING_SERVLET_PROPERTY_PREFIX)) { + final Object value = ref.getProperty(key); + if(value != null) { + result.put(key, maybeConvertToSingleValue(value)); + } + } + }; + return result; + } + + /** Convert input to a single value if it's an array of size one */ + private static Object maybeConvertToSingleValue(Object input) { + Object result = input; + if(input instanceof Object[]) { + Object[] arr = (Object[])input; + if(arr.length == 1) { + result = arr[0]; + } + } + return result; + } + + private String classOf(ServiceReference ref) { + final Object service = bundleContext.getService(ref); + try { + return service.getClass().getName(); + } finally { + bundleContext.ungetService(ref); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/apache/sling/capabilities/internal/JSONCapabilitiesWriter.java b/src/main/java/org/apache/sling/capabilities/internal/JSONCapabilitiesWriter.java index 8a60004..abe5e35 100644 --- a/src/main/java/org/apache/sling/capabilities/internal/JSONCapabilitiesWriter.java +++ b/src/main/java/org/apache/sling/capabilities/internal/JSONCapabilitiesWriter.java @@ -32,6 +32,7 @@ import org.apache.sling.capabilities.CapabilitiesSource; class JSONCapabilitiesWriter { static final String CAPS_KEY = "org.apache.sling.capabilities"; + static final String DATA_KEY = "data"; /** Write JSON to the supplied Writer, using the supplied sources */ void writeJson(Writer w, Collection<CapabilitiesSource> sources) throws IOException { @@ -41,6 +42,8 @@ class JSONCapabilitiesWriter { jw.object(); jw.key(CAPS_KEY); jw.object(); + jw.key(DATA_KEY); + jw.object(); Map<String, Object> values = null; for(CapabilitiesSource s : sources) { @@ -68,5 +71,6 @@ class JSONCapabilitiesWriter { jw.endObject(); jw.endObject(); + jw.endObject(); } } \ No newline at end of file diff --git a/src/test/java/org/apache/sling/capabilities/internal/CapabilitesServletTest.java b/src/test/java/org/apache/sling/capabilities/internal/CapabilitesServletTest.java index e7909c5..42f148f 100644 --- a/src/test/java/org/apache/sling/capabilities/internal/CapabilitesServletTest.java +++ b/src/test/java/org/apache/sling/capabilities/internal/CapabilitesServletTest.java @@ -75,7 +75,7 @@ public class CapabilitesServletTest { // the JSON format details are tested elsewhere final JsonReader r = Json.createReader(new StringReader(resp.getOutputAsString())); final JsonObject rootJson = r.readObject(); - final JsonObject json = rootJson.getJsonObject(JSONCapabilitiesWriter.CAPS_KEY); + final JsonObject json = rootJson.getJsonObject(JSONCapabilitiesWriter.CAPS_KEY).getJsonObject("data"); assertEquals("VALUE_1_F", json.getJsonObject("F").getString("KEY_1_F")); assertEquals("VALUE_42_G", json.getJsonObject("G").getString("KEY_42_G")); } diff --git a/src/test/java/org/apache/sling/capabilities/internal/JSONCapabilitiesWriterTest.java b/src/test/java/org/apache/sling/capabilities/internal/JSONCapabilitiesWriterTest.java index 3fdb95a..d20ab91 100644 --- a/src/test/java/org/apache/sling/capabilities/internal/JSONCapabilitiesWriterTest.java +++ b/src/test/java/org/apache/sling/capabilities/internal/JSONCapabilitiesWriterTest.java @@ -44,7 +44,7 @@ public class JSONCapabilitiesWriterTest { final JsonReader r = Json.createReader(new StringReader(w.toString())); final JsonObject rootJson = r.readObject(); - final JsonObject json = rootJson.getJsonObject(JSONCapabilitiesWriter.CAPS_KEY); + final JsonObject json = rootJson.getJsonObject(JSONCapabilitiesWriter.CAPS_KEY).getJsonObject("data"); assertEquals("VALUE_0_A", json.getJsonObject("A").getString("KEY_0_A")); assertEquals("VALUE_1_A", json.getJsonObject("A").getString("KEY_1_A")); assertEquals("VALUE_0_B", json.getJsonObject("B").getString("KEY_0_B")); @@ -66,7 +66,7 @@ public class JSONCapabilitiesWriterTest { final JsonReader r = Json.createReader(new StringReader(w.toString())); final JsonObject rootJson = r.readObject(); - final JsonObject json = rootJson.getJsonObject(JSONCapabilitiesWriter.CAPS_KEY); + final JsonObject json = rootJson.getJsonObject(JSONCapabilitiesWriter.CAPS_KEY).getJsonObject("data"); assertEquals("VALUE_0_A", json.getJsonObject("A").getString("KEY_0_A")); assertEquals("java.lang.IllegalArgumentException:Simulating a problem", json.getJsonObject("EXCEPTION").getString("_EXCEPTION_")); assertEquals("VALUE_0_B", json.getJsonObject("B").getString("KEY_0_B"));
