+ void update(Map<String, String> configuration) {
+ synchronized (levels) {
+ updatingConfiguration = true;
+
+ Map<String, Level> backup = new TreeMap<>(levels);
+
+ boolean fullReset = configuration.containsKey(DEFAULT_LEVEL_PROPERTY);
+ try {
+ properties: for (String property : configuration.keySet()) {
+ if (!property.startsWith(LEVEL_PROPERTY_PREFIX))
+ continue properties;
+ String levelStr = configuration.get(property);
+ Level level = Level.valueOf(levelStr);
+ levels.put(property.substring(LEVEL_PROPERTY_PREFIX.length()), level);
+ }
+
+ if (fullReset) {
+ Iterator<Map.Entry<String, Level>> it = levels.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<String, Level> entry = it.next();
+ String name = entry.getKey();
+ if (!configuration.containsKey(LEVEL_PROPERTY_PREFIX + name)) {
+ it.remove();
+ }
+ }
+// for (String name : levels.keySet()) {
+// if (!configuration.containsKey(LEVEL_PROPERTY_PREFIX + name)) {
+// levels.remove(name);
+// }
+// }
+ Level newDefaultLevel = Level.valueOf(configuration.get(DEFAULT_LEVEL_PROPERTY));
+ levels.put(DEFAULT_LEVEL_NAME, newDefaultLevel);
+ // TODO notify everyone?
+ }
+ assert levels.containsKey(DEFAULT_LEVEL_NAME);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ levels.clear();
+ levels.putAll(backup);
+ }
+ updatingConfiguration = false;
+ levels.notifyAll();
+ }
+
+ }
+
+ Map<String, Level> getLevels() {
+ return Collections.unmodifiableNavigableMap(levels);
+ }
+