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

org.daisy.common.transform.InputValue Maven / Gradle / Ivy

The newest version!
package org.daisy.common.transform;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.function.Supplier;

import javax.xml.namespace.QName;

/**
 * A supplier of a XDM value (item or sequence of items). The items may be nodes (see {@link
 * XMLInputValue}), atomic values, or maps, and by extension arbitrary objects ("external" items).
 */
public class InputValue {

	private InputValue backingValue;
	private V object = null;
	private boolean objectSupplied = false;

	/**
	 * @param object A Java object that represents a single atomic value, sequence of atomic values,
	 *     map item, or other object (but not a node sequence).
	 *
	 *     

The object may be a plain old Java object, for example:

*
    *
  • {@link String}: a single xs:string atomic value
  • *
  • {@link Integer}: a single xs:integer atomic value
  • *
  • {@link QName}: a single xs:QName atomic value
  • *
  • {@link Iterator}{@code <}{@link Object}{@code >}: a sequence of atomic values
  • *
  • {@link Map}{@code <}{@link Object}{@code ,}{@link InputValue}{@code >}: a XDM map * (where the keys are single atomic values and the values are arbitrary values)
  • *
*

It may also be an object representing a non-XDM item.

*/ public InputValue(V value) { object = value; } protected InputValue() { } protected InputValue(InputValue value) { backingValue = value; } public V asObject() throws UnsupportedOperationException, NoSuchElementException { if (backingValue != null) return backingValue.asObject(); else if (object == null && !objectSupplied) throw new UnsupportedOperationException(); else if (valueSupplied()) throw new NoSuchElementException(); else { objectSupplied = true; V ret = object; object = null; return ret; } } @SuppressWarnings("unchecked") // safe cast public final T asObject(Class type) throws UnsupportedOperationException, NoSuchElementException { V o = asObject(); if (!type.isInstance(o)) throw new UnsupportedOperationException(); return (T)o; } @Override public String toString() { if (backingValue != null) return backingValue.toString(); else if (object != null) return object.toString(); else return super.toString(); } /** * Make multiples of this input. * * @param limit The maximum number of multiples that will be made. -1 means unlimited. */ public Mult> mult(int limit) { return new Mult>() { Iterable cache = cache( iteratorOf(InputValue.this::asObject), limit); int supplied = 0; public InputValue get() throws NoSuchElementException { if (supplied >= limit) { cache = null; throw new NoSuchElementException(); } supplied++; return new InputValue() { Iterable val = cache; @Override public V asObject() throws UnsupportedOperationException, NoSuchElementException { return val.iterator().next(); } }; } }; } protected boolean valueSupplied() { return objectSupplied; } /** * Cache a {@link Iterator}. Items are evicted after they have been supplied limit * times. Exceptions thrown by the input iterator are replayed. */ // FIXME: limit argument is not implemented yet protected static Iterable cache(Iterator iterator, int limit) { if (iterator == null) throw new IllegalArgumentException(); return new Iterable() { private final List cache = new ArrayList(); private RuntimeException exception = null; public final Iterator iterator() { return new Iterator() { private int index = 0; public boolean hasNext() { synchronized (cache) { if (index < cache.size()) return true; if (exception != null) throw exception; try { return iterator.hasNext(); } catch (RuntimeException e) { exception = e; throw e; } } } public T next() throws NoSuchElementException { synchronized (cache) { if (index < cache.size()) return cache.get(index++); if (exception != null) throw exception; try { T next = iterator.next(); cache.add(next); index++; return next; } catch (RuntimeException e) { exception = e; throw e; } } } public void remove() { throw new UnsupportedOperationException(); } }; } }; } protected static Iterator iteratorOf(Supplier supplier) { return new Iterator() { T next = null; boolean nextComputed = false; public boolean hasNext() { if (nextComputed) return true; try { next = supplier.get(); nextComputed = true; return true; } catch (NoSuchElementException e) { return false; } } public T next() { if (nextComputed) { nextComputed = false; return next; } return supplier.get(); } }; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy