package org.stagemonitor.configuration.converter;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Pattern;
public class MapValueConverter<K, V> implements ValueConverter<Map<K, V>> {
private final ValueConverter<K> keyValueConverter;
private final ValueConverter<V> valueValueConverter;
private String valueSeparator;
private String entrySeparator;
public static final ValueConverter<Map<Pattern, String>> REGEX_MAP_VALUE_CONVERTER =
new MapValueConverter<Pattern, String>(RegexValueConverter.INSTANCE, StringValueConverter.INSTANCE);
public MapValueConverter(ValueConverter<K> keyValueConverter, ValueConverter<V> valueValueConverter) {
this(keyValueConverter, valueValueConverter, ":", ",");
}
public MapValueConverter(ValueConverter<K> keyValueConverter, ValueConverter<V> valueValueConverter, String valueSeparator, String entrySeparator) {
this.keyValueConverter = keyValueConverter;
this.valueValueConverter = valueValueConverter;
this.valueSeparator = valueSeparator;
this.entrySeparator = entrySeparator;
}
@Override
public Map<K, V> convert(String s) {
if (s == null || s.trim().isEmpty()) {
return Collections.emptyMap();
}
try {
String[] groups = s.trim().split(entrySeparator);
Map<K, V> map = new LinkedHashMap<K, V>(groups.length);
for (String group : groups) {
group = group.trim();
String[] keyValue = group.split(valueSeparator);
if (keyValue.length != 2) {
throw new IllegalArgumentException();
}
map.put(keyValueConverter.convert(keyValue[0].trim()), valueValueConverter.convert(keyValue[1].trim()));
}
return Collections.unmodifiableMap(map);
} catch (RuntimeException e) {
throw new IllegalArgumentException("Error while parsing map. " +
"Expected format <regex>: <name>[, <regex>: <name>]. Actual value: '" + s + ".'", e);
}
}
@Override
public String toString(Map<K, V> value) {
if (value == null) {
return null;
}
StringBuilder sb = new StringBuilder();
for (Iterator<Map.Entry<K, V>> iterator = value.entrySet().iterator(); iterator.hasNext(); ) {
Map.Entry<K, V> entry = iterator.next();
sb.append(keyValueConverter.toString(entry.getKey())).append(valueSeparator).append(' ').append(valueValueConverter.toString(entry.getValue()));
if (iterator.hasNext()) {
sb.append(entrySeparator).append('\n');
}
}
return sb.toString();
}
}