This is an automated email from the ASF dual-hosted git repository.
davidb pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-cpconverter.git
The following commit(s) were added to refs/heads/master by this push:
new 98f31c5 SLING-9881 - adding typehandling for sling:OsgiConfig nodes &
corresponding test
new 4691dba Merge pull request #32 from DominikSuess/issue/SLING-9881
98f31c5 is described below
commit 98f31c5c8ef4ee17c8a6128a5e779d85977d3a19
Author: Dominik Suess <[email protected]>
AuthorDate: Wed Nov 11 10:14:19 2020 +0100
SLING-9881 - adding typehandling for sling:OsgiConfig nodes & corresponding
test
---
.../handlers/XmlConfigurationEntryHandler.java | 84 ++++++++++++++++++++--
.../handlers/ConfigurationEntryHandlerTest.java | 62 +++++++++++-----
...sermapping.impl.ServiceUserMapperImpl.typed.xml | 25 +++++++
3 files changed, 148 insertions(+), 23 deletions(-)
diff --git
a/src/main/java/org/apache/sling/feature/cpconverter/handlers/XmlConfigurationEntryHandler.java
b/src/main/java/org/apache/sling/feature/cpconverter/handlers/XmlConfigurationEntryHandler.java
index 9e4c1b6..d023ac9 100644
---
a/src/main/java/org/apache/sling/feature/cpconverter/handlers/XmlConfigurationEntryHandler.java
+++
b/src/main/java/org/apache/sling/feature/cpconverter/handlers/XmlConfigurationEntryHandler.java
@@ -17,14 +17,24 @@
package org.apache.sling.feature.cpconverter.handlers;
import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Calendar;
import java.util.Dictionary;
import java.util.Hashtable;
+import java.util.List;
+import javax.jcr.PropertyType;
+
+import org.apache.jackrabbit.util.ISO8601;
import org.apache.jackrabbit.vault.util.DocViewProperty;
import org.apache.sling.feature.cpconverter.shared.AbstractJcrNodeParser;
+import org.codehaus.plexus.util.StringUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+
public final class XmlConfigurationEntryHandler extends
AbstractConfigurationEntryHandler {
public XmlConfigurationEntryHandler() {
@@ -42,7 +52,7 @@ public final class XmlConfigurationEntryHandler extends
AbstractConfigurationEnt
}
}
- private static final class JcrConfigurationHandler extends
AbstractJcrNodeParser<Dictionary<String, Object>> {
+ protected static final class JcrConfigurationHandler extends
AbstractJcrNodeParser<Dictionary<String, Object>> {
private static final String SLING_OSGICONFIG = "sling:OsgiConfig";
@@ -65,13 +75,73 @@ public final class XmlConfigurationEntryHandler extends
AbstractConfigurationEnt
if (attributeValue != null && !attributeValue.isEmpty()) {
DocViewProperty property =
DocViewProperty.parse(attributeQName, attributeValue);
-
+ Object value = property.values;
+ List<String> strValues =
Arrays.asList(property.values);
+ switch (property.type) {
+ case PropertyType.DATE:
+ // Date was never properly supported as osgi
configs don't support dates so converting to millis
+ // Scenario should just be theoretical
+ attributeQName += ":Long";
+ value = Lists.transform(strValues, new
Function<String, Long>() {
+ public Long apply(String s) {
+ Long res = null;
+ if (s != null) {
+ Calendar cal = ISO8601.parse(s);
+ if (cal != null) {
+ res = cal.getTimeInMillis();
+ }
+ }
+ return res;
+ }
+ }).toArray();
+ break;
+ case PropertyType.DOUBLE:
+ attributeQName += ":Double";
+ value = Lists.transform(strValues, new
Function<String, Double>() {
+ public Double apply(String s) {
+ Double res = null;
+ if (StringUtils.isNotEmpty(s)) {
+ res = Double.parseDouble(s);
+ }
+ return res;
+ }
+ }).toArray();
+ break;
+ case PropertyType.LONG:
+ attributeQName += ":Long";
+ value = Lists.transform(strValues, new
Function<String, Long>() {
+ public Long apply(String s) {
+ Long res = null;
+ if (StringUtils.isNotEmpty(s)) {
+ res = Long.parseLong(s);
+ }
+ return res;
+ }
+ }).toArray();
+ break;
+ case PropertyType.BOOLEAN:
+ attributeQName += ":Boolean";
+ value = Lists.transform(strValues, new
Function<String, Boolean>() {
+ public Boolean apply(String s) {
+ Boolean res = null;
+ if (s != null) {
+ res = Boolean.valueOf(s);
+ }
+ return res;
+ }
+ }).toArray();
+ break;
+ }
+ if(property.isMulti) {
+ attributeQName+="[]";
+ } else {
+ // first element to be used in case of singlevalue
+ value = ((Object[])value)[0];
+ }
+
+
if (property.values.length > 0) {
- if (property.isMulti) {
- configuration.put(attributeQName,
property.values);
- } else {
- configuration.put(attributeQName,
property.values[0]);
- }
+ configuration.put(attributeQName, value);
}
}
}
diff --git
a/src/test/java/org/apache/sling/feature/cpconverter/handlers/ConfigurationEntryHandlerTest.java
b/src/test/java/org/apache/sling/feature/cpconverter/handlers/ConfigurationEntryHandlerTest.java
index 7351f22..4c57c05 100644
---
a/src/test/java/org/apache/sling/feature/cpconverter/handlers/ConfigurationEntryHandlerTest.java
+++
b/src/test/java/org/apache/sling/feature/cpconverter/handlers/ConfigurationEntryHandlerTest.java
@@ -26,6 +26,8 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
+import java.io.StringWriter;
+import java.io.Writer;
import java.util.Arrays;
import java.util.Collection;
@@ -39,6 +41,7 @@ import org.apache.sling.feature.Feature;
import
org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter;
import org.apache.sling.feature.cpconverter.features.DefaultFeaturesManager;
import org.apache.sling.feature.cpconverter.features.FeaturesManager;
+import org.apache.sling.feature.io.json.ConfigurationJSONWriter;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -50,6 +53,7 @@ public class ConfigurationEntryHandlerTest {
private static final String EXPECTED_PID =
"org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl";
private static final String REPOINIT_PID =
"org.apache.sling.jcr.repoinit.RepositoryInitializer";
private static final String REPOINIT_TESTCONFIG_PATH =
"/jcr_root/apps/asd/config.author/" + REPOINIT_PID + "-test.config";
+ private static final String TYPED_TESTCONFIG_PATH =
"/jcr_root/apps/asd/config/" + EXPECTED_PID + ".typed.xml";
private static final String EXPECTED_REPOINIT = "create service user
test-user\n" +
" set ACL for test-user\n" +
" allow jcr:read on /conf\n" +
@@ -59,20 +63,36 @@ public class ConfigurationEntryHandlerTest {
" allow jcr:read on /conf\n" +
" end";
+ private static final String EXPECTED_TYPED_CONFIG = "{\n" +
+ "
\"org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.typed\": {\n"
+
+ " \"test.longproperty:Long\":123,\n" +
+ " \"user.mapping[]\":[\n" +
+ " \"com.adobe.acs.acs-aem-samples-bundle=admin\",\n" +
+ "
\"com.adobe.acs.acs-aem-samples-bundle:sample-service=oauthservice\"\n" +
+ " ],\n" +
+ " \"test.booleanproperty:Boolean\":true,\n" +
+ " \"test.dateproperty:Long\":1604743842669,\n" +
+ " \"user.default\":\"admin\",\n" +
+ " \"test.doubleproperty:Double\":1.23\n" +
+ " }\n" +
+ "}";
private final String resourceConfiguration;
private final int expectedConfigurationsSize;
+ private final int expectedConfigurationsEntrySize;
private final AbstractConfigurationEntryHandler configurationEntryHandler;
private final String expectedRunMode;
public ConfigurationEntryHandlerTest(String resourceConfiguration,
int expectedConfigurationsSize,
+ int expectedConfigurationsEntrySize,
AbstractConfigurationEntryHandler
configurationEntryHandler,
String expectedRunMode) {
this.resourceConfiguration = resourceConfiguration;
this.expectedConfigurationsSize = expectedConfigurationsSize;
+ this.expectedConfigurationsEntrySize = expectedConfigurationsEntrySize;
this.configurationEntryHandler = configurationEntryHandler;
this.expectedRunMode = expectedRunMode;
}
@@ -121,8 +141,15 @@ public class ConfigurationEntryHandlerTest {
if (configuration.getPid().contains(".empty")) {
assertTrue(configuration.getProperties().isEmpty());
} else {
- assertEquals("Unmatching size: " +
configuration.getProperties().size(), 2, configuration.getProperties().size());
+ assertEquals("Unmatching size: " +
configuration.getProperties().size(), expectedConfigurationsEntrySize,
configuration.getProperties().size());
}
+ // type & value check for typed configuration
+ if (this.resourceConfiguration.equals(TYPED_TESTCONFIG_PATH)) {
+ Writer writer = new StringWriter();
+ ConfigurationJSONWriter.write(writer, configurations);
+ assertEquals(EXPECTED_TYPED_CONFIG, writer.toString());
+ }
+
}
}
@@ -131,29 +158,32 @@ public class ConfigurationEntryHandlerTest {
String path = "/jcr_root/apps/asd/config/";
return Arrays.asList(new Object[][] {
- { path + EXPECTED_PID + ".empty.cfg", 1, new
PropertiesConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".cfg", 1, new
PropertiesConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".empty.cfg", 1, 2, new
PropertiesConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".cfg", 1, 2, new
PropertiesConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".empty.cfg.json", 1, new
JsonConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".cfg.json", 1, new
JsonConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".empty.cfg.json", 1, 2, new
JsonConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".cfg.json", 1, 2, new
JsonConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".empty.config", 1, new
ConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".config", 1, new
ConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".empty.config", 1, 2, new
ConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".config", 1, 2, new
ConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".empty.xml", 1, new
XmlConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".xml", 1, new
XmlConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".empty.xml", 1, 2, new
XmlConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".xml", 1, 2, new
XmlConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".empty.config.xml", 1, new
XmlConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".config.xml", 1, new
XmlConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".empty.config.xml", 1, 2, new
XmlConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".config.xml", 1, 2, new
XmlConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".empty.xml.cfg", 1, new
PropertiesConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".xml.cfg", 1, new
PropertiesConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".empty.xml.cfg", 1, 2, new
PropertiesConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".xml.cfg", 1, 2, new
PropertiesConfigurationEntryHandler(), null },
// runmode aware folders
- { "/jcr_root/apps/asd/config.author/" + EXPECTED_PID + ".config",
1, new ConfigurationEntryHandler(), "author" },
- { REPOINIT_TESTCONFIG_PATH, 0, new ConfigurationEntryHandler() ,
"author"},
- { "/jcr_root/apps/asd/config.publish/" + EXPECTED_PID + ".config",
1, new ConfigurationEntryHandler(), "publish" }
+ { "/jcr_root/apps/asd/config.author/" + EXPECTED_PID + ".config",
1, 2, new ConfigurationEntryHandler(), "author" },
+ { REPOINIT_TESTCONFIG_PATH, 0, 2, new ConfigurationEntryHandler()
, "author"},
+ { "/jcr_root/apps/asd/config.publish/" + EXPECTED_PID + ".config",
1, 2, new ConfigurationEntryHandler(), "publish" },
+
+ //test typed config
+ { TYPED_TESTCONFIG_PATH, 1, 6, new XmlConfigurationEntryHandler(),
null }
});
}
diff --git
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.typed.xml
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.typed.xml
new file mode 100644
index 0000000..91ed2cf
--- /dev/null
+++
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.typed.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
+ jcr:primaryType="sling:OsgiConfig"
+ user.default="admin"
+ test.longproperty="{Long}123"
+ test.doubleproperty="{Double}1.23"
+ test.dateproperty="{Date}2020-11-07T10:10:42.669"
+ test.booleanproperty="{Boolean}true"
+
user.mapping="[com.adobe.acs.acs-aem-samples-bundle=admin,com.adobe.acs.acs-aem-samples-bundle:sample-service=oauthservice]"/>