// This software is released into the Public Domain. See copying.txt for details.
package org.openstreetmap.osmosis.apidb.v0_6.impl;
import java.util.ArrayList;
import java.util.List;
import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer;
import org.openstreetmap.osmosis.core.domain.v0_6.Entity;
import org.openstreetmap.osmosis.core.domain.v0_6.EntityType;
import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator;
import org.openstreetmap.osmosis.core.store.PeekableIterator;
/**
* Reads a history stream and groups all changes for a single entity into lists.
*/
public class EntityHistoryListReader implements ReleasableIterator<List<ChangeContainer>> {
private PeekableIterator<ChangeContainer> sourceIterator;
/**
* Creates a new instance.
*
* @param sourceIterator
* An iterator containing full entity history ordered by type, identifier and
* version.
*/
public EntityHistoryListReader(ReleasableIterator<ChangeContainer> sourceIterator) {
this.sourceIterator = new PeekableIterator<ChangeContainer>(sourceIterator);
}
/**
* {@inheritDoc}
*/
@Override
public boolean hasNext() {
return sourceIterator.hasNext();
}
/**
* {@inheritDoc}
*/
@Override
public List<ChangeContainer> next() {
List<ChangeContainer> changeList;
Entity peekEntity;
long currentId;
EntityType currentEntityType;
// Get the next change from the underlying stream.
peekEntity = sourceIterator.peekNext().getEntityContainer().getEntity();
currentId = peekEntity.getId();
currentEntityType = peekEntity.getType();
// Loop until all history values for the current element are exhausted.
changeList = new ArrayList<ChangeContainer>();
while (sourceIterator.hasNext()) {
ChangeContainer tmpChangeContainer = sourceIterator.peekNext();
// Break out of the loop when we reach the next entity in the stream.
if (currentId != tmpChangeContainer.getEntityContainer().getEntity().getId()
|| !currentEntityType.equals(tmpChangeContainer.getEntityContainer().getEntity().getType())) {
break;
}
// We want the value that we have already peeked from the iterator, so remove it from the iterator.
sourceIterator.next();
// Add the change to the result list.
changeList.add(tmpChangeContainer);
}
return changeList;
}
/**
* {@inheritDoc}
*/
@Override
public void remove() {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*/
@Override
public void close() {
sourceIterator.close();
}
}