* 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