Created
July 13, 2012 10:40
-
-
Save mathieuancelin/3104192 to your computer and use it in GitHub Desktop.
A Java Cagette implementation based on Guava
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.google.common.base.Function; | |
import com.google.common.base.Optional; | |
import com.google.common.base.Predicate; | |
import com.google.common.collect.Collections2; | |
import com.google.common.collect.Iterables; | |
import com.google.common.collect.Lists; | |
import java.lang.reflect.Field; | |
import java.util.Collection; | |
import java.util.Collections; | |
import java.util.List; | |
import java.util.concurrent.atomic.AtomicLong; | |
public class Recipient { | |
public static enum Unit { INST } | |
public static interface Identifiable<ID> { | |
ID getId(); | |
} | |
public static interface Identifier<A, ID> { | |
public ID of(A obj); | |
} | |
public static interface Pagination {} | |
public static abstract class Page implements Pagination { | |
private final int page; | |
private final int size; | |
public Page(int page) { | |
this.page = page; | |
this.size = 25; | |
} | |
public Page(int page, int size) { | |
this.page = page; | |
this.size = size; | |
} | |
public int getPage() { return page; } | |
public int getSize() { return size; } | |
} | |
public static class Full extends Page { | |
public Full() { super(-1); } | |
} | |
public static final Pagination FULL = new Full(); | |
public static class Bocal<A, ID> { | |
private final Identifier<A, ID> identifier; | |
private final List<A> store = Lists.newArrayList(); | |
public static <ID, T extends Identifiable<ID>> Bocal<T, ID> identifiableBocal(final Class<T> clazz) { | |
return new Bocal<T, ID>(clazz); | |
} | |
public static <A, ID> Bocal<A, ID> identifiableBocal(Identifier<A, ID> identifier) { | |
return new Bocal<A, ID>(identifier); | |
} | |
public Bocal() { | |
// SO UGLY !!!! | |
this.identifier = new Identifier<A, ID>() { | |
private Class clazz; | |
private Field f; | |
@Override | |
public ID of(A obj) { | |
try { | |
if (clazz == null && f == null) { | |
clazz = obj.getClass(); | |
f = clazz.getDeclaredField("id"); | |
f.setAccessible(true); | |
} | |
return (ID) f.get(obj); | |
} catch (Exception e) { | |
throw new RuntimeException(e); | |
} | |
} | |
}; | |
} | |
Bocal(final Class<? extends Identifiable<ID>> clazz) { | |
this.identifier = new Identifier<A, ID>() { | |
public ID of(A obj) { | |
return clazz.cast(obj).getId(); | |
} | |
}; | |
} | |
public Bocal(Identifier<A, ID> identifier) { | |
this.identifier = identifier; | |
} | |
public Optional<A> findById(final ID id) { | |
return Optional.fromNullable(Iterables.getFirst( | |
Collections2.filter(store, new Predicate<A>() { | |
public boolean apply(A item) { | |
return identifier.of(item).equals(id); | |
} | |
}), null)); | |
} | |
public Collection<A> findAll(Pagination pagination) { | |
return paginate(store, pagination); | |
} | |
public Collection<A> findAll() { return paginate(store, FULL); } | |
public Collection<A> findBy(Predicate<A> p, Pagination pagination) { | |
return paginate(Collections2.filter(store, p), pagination); | |
} | |
public Collection<A> findBy(Predicate<A> p) { | |
return paginate(Collections2.filter(store, p), FULL); | |
} | |
public Optional<A> findOneBy(Predicate<A> p) { | |
return Optional.fromNullable(Iterables.getFirst(findBy(p), null)); | |
} | |
public void delete(ID id) { | |
findById(id).transform(new Function<A, Unit>() { | |
public Unit apply(A item) { | |
store.remove(item); | |
return Unit.INST; | |
} | |
}); | |
} | |
public void delete(List<ID> ids) { | |
for (ID id : ids) { | |
delete(id); | |
} | |
} | |
public void delete(final Predicate<A> p) { | |
for (A item : findBy(p)) { | |
delete(identifier.of(item)); | |
} | |
} | |
public A save(A item) { | |
delete(identifier.of(item)); | |
store.add(item); | |
return item; | |
} | |
public void save(List<A> items) { | |
for (A item : items) { | |
save(item); | |
} | |
} | |
public long count(Predicate<A> p) { return (long) findBy(p).size(); } | |
public void clear() { store.clear(); } | |
public void reset() { reset(Collections.<A>emptyList()); } | |
public void reset(Collection<A> withItems) { | |
clear(); | |
counter.set(0); | |
store.addAll(withItems); | |
} | |
public long size() { return store.size(); } | |
private Collection<A> paginate(Collection<A> items, Pagination pagination) { | |
for (Full full : caseClassOf(Full.class, pagination)) { | |
return items; | |
} | |
for (Page page : caseClassOf(Page.class, pagination)) { | |
return Lists.newArrayList( | |
Iterables.limit( | |
Iterables.skip(items, (page.getPage() - 1) | |
* page.getSize()), page.getSize())); | |
} | |
throw new RuntimeException("Should not happen !!!"); | |
} | |
private AtomicLong counter = new AtomicLong(0); | |
public Long autoIncrement() { return counter.getAndIncrement(); } | |
public String UUID() { return Long.toString(autoIncrement(), 24); } | |
} | |
private static <K> Iterable<K> caseClassOf(final Class<K> clazz, Object o) { | |
if (clazz.isInstance(o)) { return Collections.singleton(clazz.cast(o));} | |
return Collections.emptyList(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment