* added FunctionIterator
* added Preferences Wrapper (Map, List)
This commit is contained in:
parent
89e5310ec6
commit
21b5dc3fab
|
@ -0,0 +1,24 @@
|
||||||
|
|
||||||
|
package net.sourceforge.tuned;
|
||||||
|
|
||||||
|
|
||||||
|
public class ExceptionUtil {
|
||||||
|
|
||||||
|
public static Throwable getRootCause(Throwable t) {
|
||||||
|
while (t.getCause() != null) {
|
||||||
|
t = t.getCause();
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static RuntimeException asRuntimeException(Throwable t) {
|
||||||
|
if (t instanceof RuntimeException) {
|
||||||
|
return (RuntimeException) t;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RuntimeException(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
|
||||||
|
package net.sourceforge.tuned;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
|
||||||
|
public class FunctionIterator<S, T> implements Iterator<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Function transforms one Object into another.
|
||||||
|
*
|
||||||
|
* @param <S> type of source Objects
|
||||||
|
* @param <T> type Objects are transformed into
|
||||||
|
*/
|
||||||
|
public static interface Function<S, T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given sourceValue into any kind of Object.
|
||||||
|
*
|
||||||
|
* @param sourceValue - the Object to transform
|
||||||
|
* @return the transformed version of the object
|
||||||
|
*/
|
||||||
|
public T evaluate(S sourceValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Iterator<S> sourceIterator;
|
||||||
|
private final Function<S, T> function;
|
||||||
|
|
||||||
|
|
||||||
|
public FunctionIterator(Iterable<S> source, Function<S, T> function) {
|
||||||
|
this(source.iterator(), function);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public FunctionIterator(Iterator<S> iterator, Function<S, T> function) {
|
||||||
|
this.sourceIterator = iterator;
|
||||||
|
this.function = function;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
try {
|
||||||
|
return peekNext() != null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T next() {
|
||||||
|
if (!hasNext())
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
|
||||||
|
try {
|
||||||
|
return peekNext();
|
||||||
|
} finally {
|
||||||
|
cache = null;
|
||||||
|
currentException = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private T cache = null;
|
||||||
|
private RuntimeException currentException = null;
|
||||||
|
|
||||||
|
|
||||||
|
private T peekNext() {
|
||||||
|
while (cache == null && (sourceIterator.hasNext() || currentException != null)) {
|
||||||
|
if (currentException != null)
|
||||||
|
throw currentException;
|
||||||
|
|
||||||
|
try {
|
||||||
|
cache = transform(sourceIterator.next());
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
currentException = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private T transform(S sourceValue) {
|
||||||
|
return function.evaluate(sourceValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The remove operation is not supported by this implementation of <code>Iterator</code>.
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException if this method is invoked.
|
||||||
|
* @see java.util.Iterator
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
|
||||||
|
package net.sourceforge.tuned;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.AbstractList;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
|
import net.sourceforge.tuned.PreferencesMap.Adapter;
|
||||||
|
|
||||||
|
|
||||||
|
public class PreferencesList<T> extends AbstractList<T> {
|
||||||
|
|
||||||
|
private final PreferencesMap<T> prefs;
|
||||||
|
|
||||||
|
|
||||||
|
public PreferencesList(PreferencesMap<T> preferencesMap) {
|
||||||
|
this.prefs = preferencesMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T get(int index) {
|
||||||
|
return prefs.get(key(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String key(int index) {
|
||||||
|
return Integer.toString(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return prefs.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(T e) {
|
||||||
|
prefs.put(key(size()), e);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T remove(int index) {
|
||||||
|
|
||||||
|
int lastIndex = size() - 1;
|
||||||
|
|
||||||
|
List<T> shiftList = new ArrayList<T>(subList(index, lastIndex + 1));
|
||||||
|
|
||||||
|
T value = shiftList.remove(0);
|
||||||
|
|
||||||
|
prefs.remove(key(lastIndex));
|
||||||
|
|
||||||
|
for (T element : shiftList) {
|
||||||
|
set(index, element);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T set(int index, T element) {
|
||||||
|
if (index < 0 || index >= size())
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
|
||||||
|
return prefs.put(key(index), element);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
prefs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void set(List<T> data) {
|
||||||
|
clear();
|
||||||
|
addAll(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static <T> PreferencesList<T> map(Preferences prefs, Class<T> type) {
|
||||||
|
return new PreferencesList<T>(PreferencesMap.map(prefs, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static <T> PreferencesList<T> map(Preferences prefs, Adapter<T> adapter) {
|
||||||
|
return new PreferencesList<T>(PreferencesMap.map(prefs, adapter));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,316 @@
|
||||||
|
|
||||||
|
package net.sourceforge.tuned;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.prefs.BackingStoreException;
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
|
|
||||||
|
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) {
|
||||||
|
if (key instanceof String) {
|
||||||
|
return adapter.get(prefs, (String) key);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Key must be a String");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T put(String key, T value) {
|
||||||
|
adapter.put(prefs, key, value);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return always null
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public T remove(Object key) {
|
||||||
|
if (key instanceof String) {
|
||||||
|
prefs.remove((String) key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String[] keys() {
|
||||||
|
try {
|
||||||
|
return prefs.keys();
|
||||||
|
} catch (BackingStoreException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
try {
|
||||||
|
prefs.clear();
|
||||||
|
} catch (BackingStoreException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void set(Map<String, T> data) {
|
||||||
|
clear();
|
||||||
|
putAll(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@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<Map.Entry<String, T>> entrySet() {
|
||||||
|
Set<Map.Entry<String, T>> entries = new LinkedHashSet<Map.Entry<String, T>>();
|
||||||
|
|
||||||
|
for (String key : keys()) {
|
||||||
|
entries.add(new Entry(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> keySet() {
|
||||||
|
return new HashSet<String>(Arrays.asList(keys()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putAll(Map<? extends String, ? extends T> map) {
|
||||||
|
for (String key : map.keySet()) {
|
||||||
|
put(key, map.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class Entry implements Map.Entry<String, T> {
|
||||||
|
|
||||||
|
private final String key;
|
||||||
|
|
||||||
|
|
||||||
|
public Entry(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T getValue() {
|
||||||
|
return get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T setValue(T value) {
|
||||||
|
return put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> PreferencesMap<T> map(Preferences prefs, Class<T> type) {
|
||||||
|
Adapter<T> adapter;
|
||||||
|
|
||||||
|
if (type == String.class) {
|
||||||
|
// prefer StringAdapter, because SimpleAdapter would use the copy constructor of String, instead of returning the values directly
|
||||||
|
adapter = (Adapter<T>) new StringAdapter();
|
||||||
|
} else {
|
||||||
|
adapter = new SimpleAdapter(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return map(prefs, adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static <T> PreferencesMap<T> map(Preferences prefs, Adapter<T> adapter) {
|
||||||
|
return new PreferencesMap<T>(prefs, adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static interface Adapter<T> {
|
||||||
|
|
||||||
|
public T get(Preferences prefs, String key);
|
||||||
|
|
||||||
|
|
||||||
|
public void put(Preferences prefs, String key, T value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class StringAdapter implements Adapter<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> implements Adapter<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 stringValue = prefs.get(key, null);
|
||||||
|
|
||||||
|
if (stringValue == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return constructor.newInstance(stringValue);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
throw ExceptionUtil.asRuntimeException(e.getCause());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void put(Preferences prefs, String key, T value) {
|
||||||
|
prefs.put(key, value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class SerializableAdapter<T extends Serializable> implements Adapter<T> {
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public T get(Preferences prefs, String key) {
|
||||||
|
byte[] bytes = prefs.getByteArray(key, null);
|
||||||
|
|
||||||
|
if (bytes == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes));
|
||||||
|
Object object = in.readObject();
|
||||||
|
in.close();
|
||||||
|
|
||||||
|
return (T) object;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void put(Preferences prefs, String key, T value) {
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
try {
|
||||||
|
ObjectOutputStream out = new ObjectOutputStream(buffer);
|
||||||
|
out.writeObject(value);
|
||||||
|
out.close();
|
||||||
|
|
||||||
|
prefs.putByteArray(key, buffer.toByteArray());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue