* added FunctionIterator

* added Preferences Wrapper (Map, List)
This commit is contained in:
Reinhard Pointner 2008-06-09 18:36:05 +00:00
parent 89e5310ec6
commit 21b5dc3fab
4 changed files with 537 additions and 0 deletions

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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));
}
}

View File

@ -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);
}
}
}
}