org.daisy.pipeline.braille.common.WithSideEffect Maven / Gradle / Ivy
The newest version!
package org.daisy.pipeline.braille.common;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.AbstractIterator;
import com.google.common.collect.ImmutableList;
public abstract class WithSideEffect implements Function {
private T value = null;
private boolean computed = false;
private boolean absent = true;
public final T apply(W world) throws NoSuchElementException {
if (!computed) {
sideEffectsBuilder = new ImmutableList.Builder>();
firstWorld = world;
try {
value = _apply();
absent = false; }
finally {
sideEffects = sideEffectsBuilder.build();
sideEffectsBuilder = null;
firstWorld = null;
computed = true; }}
else
for (Function super W,?> sideEffect : sideEffects)
sideEffect.apply(world);
if (absent)
throw new NoSuchElementException();
return value;
}
protected abstract T _apply() throws NoSuchElementException;
private List> sideEffects;
private ImmutableList.Builder> sideEffectsBuilder;
private W firstWorld;
protected final V __apply(final Function super W,? extends V> withSideEffect) {
sideEffectsBuilder.add(withSideEffect);
return withSideEffect.apply(firstWorld);
}
/* -- */
/* of */
/* -- */
public static WithSideEffect of(final T value) {
return new WithSideEffect() {
public T _apply() {
return value;
}
};
}
/* ------------ */
/* fromNullable */
/* ------------ */
public static WithSideEffect fromNullable(final T value) {
return new WithSideEffect() {
public T _apply() {
if (value == null)
throw new NoSuchElementException();
return value;
}
};
}
/* ================== */
/* UTILS */
/* ================== */
public static abstract class util {
/* -------- */
/* Function */
/* -------- */
public static abstract class Function implements com.google.common.base.Function> {
public abstract T _apply(F from);
public final WithSideEffect apply(final F from) {
return new WithSideEffect() {
public T _apply() {
synchronized(Function.this) {
current = this;
try {
return Function.this._apply(from); }
finally {
current = null; }
}
}
};
}
private WithSideEffect current;
protected final V __apply(final com.google.common.base.Function super W,? extends V> withSideEffect) {
return current.__apply(withSideEffect);
}
}
/* -------- */
/* Iterable */
/* -------- */
public static interface Iterable extends com.google.common.base.Function> {}
/* --------- */
/* Iterables */
/* --------- */
public static abstract class Iterables {
/* empty */
public static Iterable empty() {
return of(Optional.>absent().asSet());
}
/* of */
public static Iterable of(WithSideEffect element) {
return of(Optional.of(element).asSet());
}
public static Iterable of(java.lang.Iterable> iterable) {
return new Of(iterable);
}
protected static class Of implements Iterable {
protected final java.lang.Iterable> iterable;
protected Of(java.lang.Iterable> iterable) {
this.iterable = iterable;
}
public java.lang.Iterable apply(final W world) {
return new java.lang.Iterable() {
public Iterator iterator() {
return new AbstractIterator() {
private Iterator> from = iterable.iterator();
protected T computeNext() {
while (true) {
WithSideEffect next;
try {
next = from.next(); }
catch (NoSuchElementException e) {
return endOfData(); }
try {
return next.apply(world); }
catch (NoSuchElementException e) {
continue; }}
}
};
}
};
}
}
/* transform */
public static Iterable transform(final Iterable from, final com.google.common.base.Function function) {
return new Iterable() {
public java.lang.Iterable apply(W world) {
return com.google.common.collect.Iterables.transform(from.apply(world), function);
}
};
}
public static Iterable transform(final Iterable from, final Function function) {
return new Iterable() {
public java.lang.Iterable apply(W world) {
return of(
com.google.common.collect.Iterables.transform(from.apply(world), function)
).apply(world);
}
};
}
public static Iterable transform(final java.lang.Iterable from, final Function function) {
return of(
com.google.common.collect.Iterables.transform(from, function)
);
}
/* concat */
public static Iterable concat(final java.lang.Iterable extends Iterable> inputs) {
return new Concat() {
protected Iterator extends Iterable> iterator(W world) {
return inputs.iterator();
}
};
}
public static Iterable concat(final Iterable extends Iterable,W> inputs) {
return new Concat() {
protected Iterator extends Iterable> iterator(W world) {
return inputs.apply(world).iterator();
}
};
}
protected static abstract class Concat implements Iterable {
protected abstract Iterator extends Iterable> iterator(W world);
public java.lang.Iterable apply(final W world) {
return new java.lang.Iterable() {
public Iterator iterator() {
return new AbstractIterator() {
Iterator extends Iterable> iterableIterator = Concat.this.iterator(world);
Iterator current;
protected T computeNext() {
while (current == null || !current.hasNext()) {
if (!iterableIterator.hasNext())
return endOfData();
current = iterableIterator.next().apply(world).iterator(); }
return current.next();
}
};
}
};
}
}
}
}
}