filebot/source/net/filebot/util/PreferencesMap.java

302 lines
5.9 KiB
Java

package net.filebot.util;
import static net.filebot.Logging.*;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import com.cedarsoftware.util.io.JsonReader;
import com.cedarsoftware.util.io.JsonWriter;
public class PreferencesMap<T> implements Map<String, T> {
private final Preferences prefs;
private final Adapter<T> adapter;
public PreferencesMap(Preferences prefs, Adapter<T> adapter) {
this.prefs = prefs;
this.adapter = adapter;
}
@Override
public T get(Object key) {
return adapter.get(prefs, key.toString());
}
@Override
public T put(String key, T value) {
adapter.put(prefs, key, value);
// don't know previous entry
return null;
}
@Override
public T remove(Object key) {
adapter.remove(prefs, key.toString());
// don't know removed entry
return null;
}
public String[] keys() {
try {
return adapter.keys(prefs);
} catch (BackingStoreException e) {
throw new RuntimeException(e);
}
}
@Override
public void clear() {
for (String key : keys()) {
adapter.remove(prefs, key);
}
}
@Override
public boolean containsKey(Object key) {
if (key instanceof String) {
return Arrays.asList(keys()).contains(key);
}
return false;
}
@Override
public boolean containsValue(Object value) {
for (String key : keys()) {
if (value.equals(get(key)))
return true;
}
return false;
}
@Override
public Set<Entry<String, T>> entrySet() {
Set<Map.Entry<String, T>> entries = new LinkedHashSet<Map.Entry<String, T>>();
for (String key : keys()) {
entries.add(new PreferencesEntry<T>(prefs, key, adapter));
}
return entries;
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public Set<String> keySet() {
return new LinkedHashSet<String>(Arrays.asList(keys()));
}
@Override
public void putAll(Map<? extends String, ? extends T> map) {
for (Map.Entry<? extends String, ? extends T> entry : map.entrySet()) {
put(entry.getKey(), entry.getValue());
}
}
@Override
public int size() {
return keys().length;
}
@Override
public Collection<T> values() {
List<T> values = new ArrayList<T>();
for (String key : keys()) {
values.add(get(key));
}
return values;
}
public static PreferencesMap<String> map(Preferences prefs) {
return map(prefs, new StringAdapter());
}
public static <T> PreferencesMap<T> map(Preferences prefs, Adapter<T> adapter) {
return new PreferencesMap<T>(prefs, adapter);
}
public static interface Adapter<T> {
public String[] keys(Preferences prefs) throws BackingStoreException;
public T get(Preferences prefs, String key);
public void put(Preferences prefs, String key, T value);
public void remove(Preferences prefs, String key);
}
public static abstract class AbstractAdapter<T> implements Adapter<T> {
@Override
public abstract T get(Preferences prefs, String key);
@Override
public abstract void put(Preferences prefs, String key, T value);
@Override
public String[] keys(Preferences prefs) throws BackingStoreException {
return prefs.keys();
}
@Override
public void remove(Preferences prefs, String key) {
prefs.remove(key);
}
}
public static class StringAdapter extends AbstractAdapter<String> {
@Override
public String get(Preferences prefs, String key) {
return prefs.get(key, null);
}
@Override
public void put(Preferences prefs, String key, String value) {
prefs.put(key, value);
}
}
public static class SimpleAdapter<T> extends AbstractAdapter<T> {
private final Constructor<T> constructor;
public SimpleAdapter(Class<T> type) {
try {
constructor = type.getConstructor(String.class);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
@Override
public T get(Preferences prefs, String key) {
String value = prefs.get(key, null);
if (value != null) {
try {
return constructor.newInstance(value);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return null;
}
@Override
public void put(Preferences prefs, String key, T value) {
prefs.put(key, value.toString());
}
public static <T> SimpleAdapter<T> forClass(Class<T> type) {
return new SimpleAdapter<T>(type);
}
}
public static class JsonAdapter<T> extends AbstractAdapter<T> {
private Class<T> type;
public JsonAdapter(Class<T> type) {
this.type = type;
}
@Override
public T get(Preferences prefs, String key) {
String json = prefs.get(key, null);
if (json != null) {
try {
return type.cast(JsonReader.jsonToJava(json));
} catch (Exception e) {
debug.log(Level.WARNING, e, e::getMessage);
}
}
return null;
}
@Override
public void put(Preferences prefs, String key, T value) {
prefs.put(key, JsonWriter.objectToJson(value));
}
}
public static class PreferencesEntry<T> implements Entry<String, T> {
private final String key;
private final Preferences prefs;
private final Adapter<T> adapter;
private T defaultValue = null;
public PreferencesEntry(Preferences prefs, String key, Adapter<T> adapter) {
this.key = key;
this.prefs = prefs;
this.adapter = adapter;
}
@Override
public String getKey() {
return key;
}
@Override
public T getValue() {
T value = adapter.get(prefs, key);
return value != null ? value : defaultValue;
}
@Override
public T setValue(T value) {
adapter.put(prefs, key, value);
return null;
}
public PreferencesEntry<T> defaultValue(T defaultValue) {
this.defaultValue = defaultValue;
return this;
}
public void remove() {
adapter.remove(prefs, key);
}
public void flush() {
try {
prefs.flush();
} catch (Exception e) {
debug.log(Level.WARNING, e.getMessage(), e);
}
}
}
}