All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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 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 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 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> inputs) {
				return new Concat() {
					protected Iterator> iterator(W world) {
						return inputs.iterator();
					}
				};
			}
			
			public static  Iterable concat(final Iterable,W> inputs) {
				return new Concat() {
					protected Iterator> iterator(W world) {
						return inputs.apply(world).iterator();
					}
				};
			}
			
			protected static abstract class Concat implements Iterable {
				protected abstract Iterator> iterator(W world);
				public java.lang.Iterable apply(final W world) {
					return new java.lang.Iterable() {
						public Iterator iterator() {
							return new AbstractIterator() {
								Iterator> 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();
								}
							};
						}
					};
				}
			}
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy