// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.set.v0_6; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.set.v0_6.impl.DataPostboxChangeSink; import org.openstreetmap.osmosis.core.store.DataPostbox; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.MultiChangeSinkRunnableChangeSource; /** * Combines multiple change sources into a single data set. It is done by writing the contents of * each of the input sources to the sink in order. * * @author Brett Henderson */ public class ChangeAppender implements MultiChangeSinkRunnableChangeSource { private List<DataPostbox<ChangeContainer>> sources; private ChangeSink changeSink; /** * Creates a new instance. * * @param sourceCount * The number of sources to be appended. * @param inputBufferCapacity * The capacity of the buffer to use for each source, in objects. */ public ChangeAppender(int sourceCount, int inputBufferCapacity) { sources = new ArrayList<DataPostbox<ChangeContainer>>(sourceCount); for (int i = 0; i < sourceCount; i++) { sources.add(new DataPostbox<ChangeContainer>(inputBufferCapacity)); } } /** * {@inheritDoc} */ @Override public ChangeSink getChangeSink(int instance) { if (instance < 0 || instance >= sources.size()) { throw new OsmosisRuntimeException("Sink instance " + instance + " is not valid."); } return new DataPostboxChangeSink(sources.get(instance)); } /** * {@inheritDoc} */ @Override public int getChangeSinkCount() { return sources.size(); } /** * {@inheritDoc} */ @Override public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } /** * {@inheritDoc} */ @Override public void run() { try { Map<String, Object> metaData; metaData = new HashMap<String, Object>(); // Get the initialization data from each source in turn and merge // it. If the same data exists in multiple sources the last will // win. for (DataPostbox<ChangeContainer> source : sources) { metaData.putAll(source.outputInitialize()); } changeSink.initialize(metaData); // Write the data from each source to the sink in turn. for (DataPostbox<ChangeContainer> source : sources) { while (source.hasNext()) { changeSink.process(source.getNext()); } } changeSink.complete(); // Complete all input sources. for (DataPostbox<ChangeContainer> source : sources) { source.outputComplete(); } } finally { changeSink.close(); // Release all input sources. for (DataPostbox<ChangeContainer> source : sources) { source.outputRelease(); } } } }