001package org.dcm4che3.conf.core; 002 003import org.dcm4che3.conf.core.api.Configuration; 004import org.dcm4che3.conf.core.api.ConfigurationException; 005import org.dcm4che3.conf.core.api.Path; 006import org.dcm4che3.conf.core.api.internal.ConfigProperty; 007import org.dcm4che3.conf.core.api.internal.ConfigReflection; 008import org.dcm4che3.conf.core.util.ConfigNodeTraverser; 009import org.slf4j.Logger; 010import org.slf4j.LoggerFactory; 011 012import java.util.List; 013import java.util.Map; 014 015/** 016 * Ensures that extensions are not deleted, even if they are unknown to the caller of persistNode 017 */ 018public class ExtensionMergingConfiguration extends DelegatingConfiguration { 019 020 private static Logger log = LoggerFactory.getLogger(ExtensionMergingConfiguration.class); 021 022 protected List<Class> allExtensionClasses; 023 024 public ExtensionMergingConfiguration(Configuration delegate, List<Class> allExtensionClasses) { 025 super(delegate); 026 this.allExtensionClasses = allExtensionClasses; 027 } 028 029 @Override 030 public void persistNode(Path path, Map<String, Object> configNode, Class configurableClass) throws ConfigurationException { 031 032 // make sure we don't delete the extensions we are not aware of 033 034 if (configurableClass != null) { 035 Object currentConfigurationNode = super.getConfigurationNode(path, configurableClass); 036 037 ConfigNodeTraverser.dualTraverseNodeTypesafe(configNode, currentConfigurationNode, ConfigReflection.getDummyPropertyForClass(configurableClass), allExtensionClasses, new ConfigNodeTraverser.ConfigNodesTypesafeFilter() { 038 @Override 039 public void beforeNodes(Map<String, Object> containerNode1, Map<String, Object> containerNode2, Class containerNodeClass, ConfigProperty property) throws ConfigurationException { 040 041 if (property.isExtensionsProperty()) { 042 //Preserve each key of the current configuration that do not belong to the new configuration 043 Map<String, Object> extensionsMap1 = (Map<String, Object>) containerNode1.get(property.getAnnotatedName()); 044 Map<String, Object> extensionsMap2 = (Map<String, Object>) containerNode2.get(property.getAnnotatedName()); 045 046 if(extensionsMap1 == null && extensionsMap2 == null) return; 047 048 if(extensionsMap1 == null){ 049 containerNode1.put(property.getAnnotatedName(), extensionsMap2); 050 return; 051 } 052 053 if(extensionsMap2 == null) return; 054 055 for (String key : extensionsMap2.keySet()) { 056 if(!extensionsMap1.containsKey(key)){ 057 extensionsMap1.put(key,extensionsMap2.get(key)); 058 } 059 } 060 } 061 } 062 }); 063 } 064 super.persistNode(path, configNode, configurableClass); 065 } 066}