// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.pgsnapshot.v0_6.impl; import java.util.List; import java.util.NoSuchElementException; import org.openstreetmap.osmosis.core.database.FeaturePopulator; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.lifecycle.ReleasableContainer; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; /** * Provides a single iterator based on data provided by underlying iterators from each of the * underlying entity and feature iterators. Each underlying iterator provides one component of the * overall entity. * * @param <T> * The type of entity provided by this iterator. */ public class EntityReader<T extends Entity> implements ReleasableIterator<T> { private boolean nextValueLoaded; private ReleasableContainer releasableContainer; private ReleasableIterator<T> entityIterator; private List<FeaturePopulator<T>> featurePopulators; private T nextValue; /** * Creates a new instance. * * @param entityIterator * The entity source. * @param featurePopulators * Populators to add entity specific features to the generated entities. */ public EntityReader(ReleasableIterator<T> entityIterator, List<FeaturePopulator<T>> featurePopulators) { releasableContainer = new ReleasableContainer(); this.entityIterator = releasableContainer.add(entityIterator); for (FeaturePopulator<T> featurePopulator : featurePopulators) { releasableContainer.add(featurePopulator); } this.featurePopulators = featurePopulators; } /** * Consolidates the output of all readers so that entities are fully * populated. * * @return An entity record where the entity is fully populated. */ private T readNextEntity() { T entity; entity = entityIterator.next(); // Add entity type specific features to the entity. for (FeaturePopulator<T> populator : featurePopulators) { populator.populateFeatures(entity); } return entity; } /** * {@inheritDoc} */ public boolean hasNext() { if (!nextValueLoaded && entityIterator.hasNext()) { nextValue = readNextEntity(); nextValueLoaded = true; } return nextValueLoaded; } /** * {@inheritDoc} */ public T next() { T result; if (!hasNext()) { throw new NoSuchElementException(); } result = nextValue; nextValueLoaded = false; return result; } /** * {@inheritDoc} */ public void remove() { throw new UnsupportedOperationException(); } /** * {@inheritDoc} */ public void close() { releasableContainer.close(); } }