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

org.daisy.pipeline.braille.common.TransformProvider Maven / Gradle / Ivy

package org.daisy.pipeline.braille.common;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;

import com.google.common.base.Function;
import com.google.common.collect.AbstractIterator;
import static com.google.common.collect.Iterables.transform;

import org.daisy.pipeline.braille.common.util.Locales;
import org.daisy.pipeline.braille.common.Provider;
import org.daisy.pipeline.braille.common.Query.MutableQuery;
import static org.daisy.pipeline.braille.common.Query.util.mutableQuery;
import static org.daisy.pipeline.braille.common.util.Locales.parseLocale;
import static org.daisy.pipeline.braille.common.util.Strings.join;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public interface TransformProvider extends Provider, Contextual> {
	
	/* ================== */
	/*       UTILS        */
	/* ================== */
	
	public static abstract class util {
		
		/* ------ */
		/* cast() */
		/* ------ */
		
		@SuppressWarnings(
			"unchecked" // safe cast
		)
		public static  TransformProvider cast(TransformProvider provider) {
			return (TransformProvider)provider;
		}
		
		/* --------- */
		/* memoize() */
		/* --------- */
		
		public interface MemoizingProvider
			extends Provider.util.MemoizingProvider, TransformProvider {}
		
		public static  MemoizingProvider memoize(TransformProvider provider) {
			return new MemoizeFromProvider(provider);
		}
		
		public static abstract class Memoize
				extends Provider.util.Memoize implements MemoizingProvider {
			
			private Map> providerCache = new HashMap>();
			
			public Memoize() {
				providerCache.put(null, this);
			}
			
			protected abstract TransformProvider _withContext(Logger context);
			
			public final TransformProvider withContext(Logger context) {
				if (providerCache.containsKey(context))
					return providerCache.get(context);
				TransformProvider provider = new DerivativeProvider(_withContext(context));
				providerCache.put(context, provider);
				return provider;
			}
			
			private class DerivativeProvider
					extends Provider.util.Memoize
					implements TransformProvider {
				private final TransformProvider provider;
				private DerivativeProvider(TransformProvider provider) {
					this.provider = provider;
				}
				public Iterable _get(Query query) {
					return provider.get(query);
				}
				public TransformProvider withContext(Logger context) {
					return Memoize.this.withContext(context);
				}
			}
		}
		
		private static class MemoizeFromProvider extends Memoize {
			private final TransformProvider provider;
			private MemoizeFromProvider(TransformProvider provider) {
				this.provider = provider;
			}
			protected Iterable _get(Query query) {
				return provider.get(query);
			}
			protected TransformProvider _withContext(Logger context) {
				return provider.withContext(context);
			}
			@Override
			public String toString() {
				return "memoize( " + provider + " )";
			}
		}
		
		/* ---------- */
		/* dispatch() */
		/* ---------- */
		
		public static abstract class Dispatch
				extends Provider.util.Dispatch implements TransformProvider {
			
			private final Logger context;
			
			public Dispatch(Logger context) {
				this.context = context;
			}
			
			protected abstract Iterable> _dispatch();
			
			public final Iterable> dispatch() {
				return transform(
					_dispatch(),
					new Function,Provider>() {
						public Provider apply(TransformProvider provider) {
							return provider.withContext(context); }});
			}
		}
		
		@SuppressWarnings(
			"unchecked" // safe cast to Iterable>
		)
		public static  TransformProvider dispatch(Iterable> dispatch) {
			return new DispatchFromProviderIterable((Iterable>)dispatch, null);
		}
		
		private static class DispatchFromProviderIterable extends Dispatch {
			private final Iterable> dispatch;
			private DispatchFromProviderIterable(Iterable> dispatch, Logger context) {
				super(context);
				this.dispatch = dispatch;
			}
			protected Iterable> _dispatch() {
				return dispatch;
			}
			public TransformProvider withContext(Logger context) {
				return new DispatchFromProviderIterable(dispatch, context);
			}
			@Override
			public String toString() {
				return "dispatch( " + join(_dispatch(), ", ") + " )";
			}
		}
		
		/* --------- */
		/* partial() */
		/* --------- */
		
		public static  TransformProvider partial(Query query, TransformProvider provider) {
			return new Partial(query, provider);
		}
		
		private static class Partial implements TransformProvider {
			private final Query partialQuery;
			private final TransformProvider provider;
			public Partial(Query partialQuery, TransformProvider provider) {
				this.partialQuery = partialQuery;
				this.provider = provider;
			}
			public final Iterable get(Query query) {
				return provider.get(mutableQuery().addAll(partialQuery).addAll(query));
			}
			public TransformProvider withContext(Logger context) {
				return new Partial(partialQuery, provider.withContext(context));
			}
			@Override
			public String toString() {
				return "partial( " + partialQuery + ", " + provider + " )";
			}
		}
		
		/* ------------------------ */
		/* logCreate(), logSelect() */
		/* ------------------------ */
		
		public static  T logCreate(T t, Logger context) {
			context.debug("Created " + t);
			return t;
		}
		
		public static  Iterable logSelect(final Query query,
		                                                          final TransformProvider provider,
		                                                          final Logger context) {
			return new Iterable() {
				public Iterator iterator() {
					return new AbstractIterator() {
						Iterator i = provider.get(query).iterator();
						boolean first = true;
						public T computeNext() {
							if (!i.hasNext()) {
								if (first)
									context.trace("No match for query " + query);
								return endOfData(); }
							T t = i.next();
							context.debug("Selected " + t + " for query " + query);
							first = false;
							return t;
						}
					};
				}
			};
		}
		
		/* ------------ */
		/* varyLocale() */
		/* ------------ */
		
		public static  TransformProvider varyLocale(TransformProvider delegate) {
			return new VaryLocale(delegate, null);
		}
		
		private static class VaryLocale
				extends Provider.util.VaryLocale implements TransformProvider {
			
			private final TransformProvider delegate;
			private final Logger context;
			private VaryLocale(TransformProvider delegate, Logger context) {
				this.delegate = delegate;
				this.context = context;
			}
			public Iterable _get(Query query) {
				return delegate.withContext(context).get(query);
			}
			public Locale getLocale(Query query) {
				if (query.containsKey("document-locale"))
					try {
						return parseLocale(query.getOnly("document-locale").getValue().get()); }
					catch (IllegalArgumentException e) {
						logger.warn("Invalid locale", e);
						return null; }
				else
					return null;
			}
			public Query assocLocale(Query query, Locale locale) {
				MutableQuery q = mutableQuery(query);
				q.removeAll("document-locale");
				q.add("document-locale", locale.toLanguageTag());
				return q.asImmutable();
			}
			public TransformProvider withContext(Logger context) {
				return new VaryLocale(delegate, context);
			}
			@Override
			public String toString() {
				return "varyLocale( " + delegate + " )";
			}
		}
		
		private static final Logger logger = LoggerFactory.getLogger(TransformProvider.class);
		
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy