com.github.antelopeframework.dynamicproperty.DynamicPropertyUpdater Maven / Gradle / Ivy
The newest version!
package com.github.antelopeframework.dynamicproperty;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.commons.configuration.AbstractConfiguration;
import org.apache.commons.lang3.StringUtils;
import lombok.extern.slf4j.Slf4j;
/**
* Apply the {@link WatchedUpdateResult} to the configuration.
*
* If the result is a full result from source, each property in the result is
* added/set in the configuration. Any property that is in the configuration -
* but not in the result - is deleted if ignoreDeletesFromSource is false.
*
* If the result is incremental, properties will be added and changed from the
* partial result in the configuration. Deleted properties are deleted from
* configuration iff ignoreDeletesFromSource is false.
*/
@Slf4j
public class DynamicPropertyUpdater {
/**
* Updates the properties in the config param given the contents of the
* result param.
*
* @param result either an incremental or full set of data
* @param config underlying config map
* @param ignoreDeletesFromSource if true, deletes will be skipped
*/
public static void updateProperties(final WatchedUpdateResult result, final MapConfiguration config, final boolean ignoreDeletesFromSource) {
if (result == null || !result.hasChanges()) {
return;
}
log.debug("incremental result? [{}]", result.isIncremental());
log.debug("ignored deletes from source? [{}]", ignoreDeletesFromSource);
if (!result.isIncremental()) {
Map props = result.getComplete();
if (props == null) {
return;
}
for (Entry entry : props.entrySet()) {
addOrChangeProperty(entry.getKey(), entry.getValue(), config);
}
Set existingKeys = new HashSet();
for (Iterator i = config.getKeys(); i.hasNext();) {
existingKeys.add(i.next());
}
if (!ignoreDeletesFromSource) {
for (String key : existingKeys) {
if (!props.containsKey(key)) {
deleteProperty(key, config);
}
}
}
} else {
Map props = result.getAdded();
if (props != null) {
for (Entry entry : props.entrySet()) {
addOrChangeProperty(entry.getKey(), entry.getValue(), config);
}
}
props = result.getChanged();
if (props != null) {
for (Entry entry : props.entrySet()) {
addOrChangeProperty(entry.getKey(), entry.getValue(), config);
}
}
if (!ignoreDeletesFromSource) {
props = result.getDeleted();
if (props != null) {
for (String name : props.keySet()) {
deleteProperty(name, config);
}
}
}
}
}
/**
* Add or update the property in the underlying config depending on if it
* exists
*
* @param name
* @param newValue
* @param config
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
static void addOrChangeProperty(final String name, final Object newValue, final MapConfiguration config) {
// We do not want to abort the operation due to failed validation on one property
if (!config.containsKey(name)) {
log.debug("adding property key [{}], value [{}]", name, newValue);
config.addProperty(name, newValue);
} else {
Object oldValue = config.getProperty(name);
if (newValue != null) {
Object newValueArray;
if (oldValue instanceof CopyOnWriteArrayList&& AbstractConfiguration.getDefaultListDelimiter() != '\0') {
newValueArray = new CopyOnWriteArrayList<>();
String[] parts = StringUtils.split((String) newValue, AbstractConfiguration.getDefaultListDelimiter());
if (parts != null) {
for (String s : parts) {
if (StringUtils.isNotBlank(s)) {
((CopyOnWriteArrayList) newValueArray).add(s.trim());
}
}
}
} else {
newValueArray = newValue;
}
if (!newValueArray.equals(oldValue)) {
log.debug("updating property key [{}], value [{}]", name, newValue);
config.setProperty(name, newValue);
}
} else if (oldValue != null) {
log.debug("nulling out property key [{}]", name);
config.setProperty(name, null);
}
}
}
/**
* Delete a property in the underlying config
*
* @param key
* @param config
*/
static void deleteProperty(final String key, final MapConfiguration config) {
if (config.containsKey(key)) {
log.debug("deleting property key [" + key + "]");
config.clearProperty(key);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy