| /* |
| * 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.testing.mock.caconfig; |
| |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.stream.Collectors; |
| |
| import org.apache.sling.api.resource.Resource; |
| import org.apache.sling.caconfig.management.ConfigurationManager; |
| import org.apache.sling.caconfig.management.multiplexer.ConfigurationPersistenceStrategyMultiplexer; |
| import org.apache.sling.caconfig.spi.ConfigurationCollectionPersistData; |
| import org.apache.sling.caconfig.spi.ConfigurationPersistData; |
| import org.apache.sling.testing.mock.sling.context.SlingContextImpl; |
| import org.jetbrains.annotations.NotNull; |
| |
| /** |
| * Writes context-aware configuration contains in maps and nested maps via {@link ConfigurationManager} to repository. |
| */ |
| class ConfigurationPersistHelper { |
| |
| private final ConfigurationManager configManager; |
| private final ConfigurationPersistenceStrategyMultiplexer configurationPersistenceStrategy; |
| private final Resource contextResource; |
| |
| /** |
| * @param context Sling context |
| * @param contextPath Context path |
| */ |
| ConfigurationPersistHelper(@NotNull SlingContextImpl context, @NotNull String contextPath) { |
| configManager = context.getService(ConfigurationManager.class); |
| configurationPersistenceStrategy = context.getService(ConfigurationPersistenceStrategyMultiplexer.class); |
| contextResource = context.resourceResolver().getResource(contextPath); |
| if (contextResource == null) { |
| throw new IllegalArgumentException("No resource found at" + contextPath); |
| } |
| } |
| |
| /** |
| * Writes configuration parameters using the primary configured persistence |
| * provider. |
| * @param configName Config name |
| * @param values Configuration values |
| */ |
| void writeConfiguration(@NotNull String configName, @NotNull Map<String, Object> values) { |
| // write properties of main configuration |
| ConfigurationDataParts parts = new ConfigurationDataParts(values); |
| configManager.persistConfiguration(contextResource, configName, new ConfigurationPersistData(parts.getValues())); |
| |
| // write nested configuration and nested configuration collections |
| for (Map.Entry<String,Map<String,Object>> nestedMap : parts.getMaps().entrySet()) { |
| writeConfiguration(getNestedConfigName(configName, nestedMap.getKey()), nestedMap.getValue()); |
| } |
| for (Map.Entry<String,Collection<Map<String,Object>>> nestedCollection : parts.getCollections().entrySet()) { |
| writeConfigurationCollection(getNestedConfigName(configName, nestedCollection.getKey()), nestedCollection.getValue()); |
| } |
| } |
| |
| /** |
| * Writes a collection of configuration parameters using the primary configured persistence provider. |
| * @param configName Config name |
| * @param values Configuration values |
| */ |
| void writeConfigurationCollection(@NotNull String configName, @NotNull Collection<@NotNull Map<String, Object>> values) { |
| // split each collection item map in it's parts |
| Map<String, ConfigurationDataParts> partsCollection = new HashMap<>(); |
| int index = 0; |
| for (Map<String, Object> map : values) { |
| partsCollection.put("item" + (index++), new ConfigurationDataParts(map)); |
| } |
| |
| // write properties of main configuration collection |
| List<ConfigurationPersistData> items = partsCollection.entrySet().stream() |
| .map(entry -> new ConfigurationPersistData(entry.getValue().getValues()).collectionItemName(entry.getKey())) |
| .collect(Collectors.toList()); |
| configManager.persistConfigurationCollection(contextResource, configName, |
| new ConfigurationCollectionPersistData(items)); |
| |
| // write nested configuration and nested configuration collections |
| for (Map.Entry<String, ConfigurationDataParts> entry : partsCollection.entrySet()) { |
| String itemName = entry.getKey(); |
| ConfigurationDataParts parts = entry.getValue(); |
| for (Map.Entry<String,Map<String,Object>> nestedMap : parts.getMaps().entrySet()) { |
| writeConfiguration(getNestedCollectionItemConfigName(configName, itemName, nestedMap.getKey()), nestedMap.getValue()); |
| } |
| for (Map.Entry<String,Collection<Map<String,Object>>> nestedCollection : parts.getCollections().entrySet()) { |
| writeConfigurationCollection(getNestedCollectionItemConfigName(configName, itemName, nestedCollection.getKey()), nestedCollection.getValue()); |
| } |
| } |
| } |
| |
| private String getNestedConfigName(@NotNull String configName, @NotNull String key) { |
| String nestedKey = configName + "/" + key; |
| String nestedConfigName = configurationPersistenceStrategy.getConfigName(nestedKey, null); |
| if (nestedConfigName == null) { |
| throw new IllegalArgumentException("Nested configuration not supported for " + nestedKey); |
| } |
| return nestedConfigName; |
| } |
| |
| private String getNestedCollectionItemConfigName(@NotNull String configName, @NotNull String itemName, @NotNull String key) { |
| String nestedKey = configName + "/" + itemName + "/" + key; |
| String nestedConfigName = configurationPersistenceStrategy.getCollectionItemConfigName(nestedKey, null); |
| if (nestedConfigName == null) { |
| throw new IllegalArgumentException("Nested configuration not supported for " + nestedKey); |
| } |
| return nestedConfigName; |
| } |
| |
| } |