org.protempa.MultiplexingDataStreamingEventIterator Maven / Gradle / Ivy
/*
* #%L
* Protempa Framework
* %%
* Copyright (C) 2012 - 2013 Emory University
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package org.protempa;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import org.arp.javautil.arrays.Arrays;
import org.protempa.proposition.Proposition;
/**
* Iterator-like access to {@link DataStreamingEvent}s. This implementation
* groups (multiplexes) propositions retrieved from multiple
* {@link DataStreamingEventIterators} by key id. It assembles all of the
* propositions for a given key id with the help of a
* {@link PropositionDataStreamerProcessor}. After this assembly has been
* completed for each key id, the iterator calls the
* {@link PropositionDataStreamerProcessor}'s
* {@link PropositionDataStreamerProcessor#fireKeyCompleted} method with
* the key id and list of propositions. The iterator gets each assembled key id
* and proposition list from the {@link PropositionDataStreamerProcessor} to
* return to the caller. Subclasses of {@link PropositionDataStreamerProcessor}
* may specify additional processing to be performed on the key id and
* proposition list prior to returning them to the caller.
*
* @author Andrew Post
*/
public class MultiplexingDataStreamingEventIterator
implements DataStreamingEventIterator {
private static class MultiplexingDataStreamingEventHandler
implements DataStreamingEventHandler {
private DataStreamingEvent event;
@Override
public void handle(String keyId, List propositions) {
this.event =
new DataStreamingEvent<>(keyId, propositions);
}
}
private final MultiplexingDataStreamingEventHandler handler;
private DataStreamerIterator itr;
private final PropositionDataStreamerProcessor processor;
private final List extends DataStreamingEventIterator> itrs;
private DataStreamingEvent next;
/**
* Constructs the iterator with a list of the iterators to multiplex and
* a {@link PropositionDataStreamerProcessor} to help with
* multiplexing.
*
* @param itrs the {@link List>} to
* multiplex. Cannot be null
.
* @param processor the {@link PropositionDataStreamerProcessor}. Cannot be
* null
.
*/
MultiplexingDataStreamingEventIterator(
List extends DataStreamingEventIterator> itrs,
PropositionDataStreamerProcessor processor) {
if (itrs == null) {
throw new IllegalArgumentException("itrs cannot be null");
}
if (processor == null) {
throw new IllegalArgumentException("processor cannot be null");
}
this.itrs = itrs;
this.processor = processor;
this.handler = new MultiplexingDataStreamingEventHandler();
this.processor.setHandler(this.handler);
}
@Override
public boolean hasNext() throws DataSourceReadException {
if (this.next == null) {
if (this.itr == null) {
this.itr = new DataStreamerIterator(this.itrs);
}
boolean stopOnNext = false;
while (this.itr.hasNext() && !stopOnNext) {
if (processor.getKeyId() != null
&& !processor.getKeyId().equals(
this.itr.getNextKeyId())) {
stopOnNext = true;
}
processor.execute(this.itr.next());
if (this.handler.event != null) {
this.next = this.handler.event;
this.handler.event = null;
return true;
}
}
if (!stopOnNext) {
processor.finish();
if (this.handler.event != null) {
this.next = this.handler.event;
this.handler.event = null;
return true;
}
}
}
return this.next != null;
}
@Override
public DataStreamingEvent next()
throws DataSourceReadException {
if (hasNext()) {
DataStreamingEvent result = this.next;
this.next = null;
return result;
} else {
throw new NoSuchElementException("Past end of iterator");
}
}
/**
* Calls the underlying {@link DataStreamingEventIterator}s
* {@link DataStreamingEventIterator#close() } method.
*
* @throws DataSourceReadException
*/
@Override
public void close() throws DataSourceReadException {
List exceptions =
new ArrayList<>();
if (this.itr != null) {
this.itr.close();
}
this.processor.close();
for (DataStreamingEventIterator it : this.itrs) {
try {
it.close();
} catch (DataSourceReadException fe) {
exceptions.add(fe);
}
}
if (!exceptions.isEmpty()) {
List stes = new ArrayList<>();
for (Exception ex : exceptions) {
Arrays.addAll(stes, ex.getStackTrace());
}
DataSourceReadException ex = new DataSourceReadException(
exceptions.size() + " data source backend(s) failed");
ex.setStackTrace(stes.toArray(new StackTraceElement[stes.size()]));
throw ex;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy