package org.oddjob.beanbus.destinations;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.oddjob.arooa.deploy.annotations.ArooaHidden;
import org.oddjob.beanbus.AbstractDestination;
import org.oddjob.beanbus.BusConductor;
import org.oddjob.beanbus.BusCrashException;
import org.oddjob.beanbus.BusEvent;
import org.oddjob.beanbus.BusFilter;
import org.oddjob.beanbus.TrackingBusListener;
/**
* @oddjob.description Provide batching of beans.
*
* @oddjob.example
*
* Create Batches of 2 beans.
*
* {@oddjob.xml.resource org/oddjob/beanbus/destinations/BatcherExample.xml}
*
* @author rob
*
* @param <T> The type of bean being batched.
*/
public class Batcher<T> extends AbstractDestination<T>
implements BusFilter<T, Collection<T>> {
private static final Logger logger = Logger.getLogger(Batcher.class);
private String name;
private int batchSize;
private Collection<? super Collection<T>> to;
private volatile List<T> batch;
private int count;
private BusConductor busConductor;
private final TrackingBusListener busListener =
new TrackingBusListener() {
@Override
public void busStarting(BusEvent event) throws BusCrashException {
count = 0;
}
@Override
public void tripBeginning(BusEvent event) throws BusCrashException {
batch = new ArrayList<T>();
}
@Override
public void tripEnding(BusEvent event) throws BusCrashException {
dispatch();
}
};
@Override
public boolean add(T bean) {
batch.add(bean);
++count;
if (batch.size() == batchSize) {
try {
busConductor.cleanBus();
} catch (BusCrashException e) {
throw new RuntimeException(e);
}
}
return true;
}
/**
* Dispatch the beans. Called when a batch is ready of a trip
* is ending.
*/
protected void dispatch() {
int batchSize = batch.size();
if (batchSize == 0) {
return;
}
if (to == null) {
logger.info("Discarding batch of " + batchSize +
" beans because there is no destination.");
}
else {
logger.info("Dipatching batch of " + batchSize +
" beans.");
to.add(batch);
}
}
@ArooaHidden
@Inject
public void setBeanBus(BusConductor busConductor) {
this.busConductor = busConductor;
busListener.setBusConductor(busConductor);
}
public int getCount() {
return count;
}
public int getSize() {
Collection<?> batch = this.batch;
if (batch == null) {
return 0;
}
else {
return batch.size();
}
}
@Override
public boolean isEmpty() {
return getSize() == 0;
}
public int getBatchSize() {
return batchSize;
}
public void setBatchSize(int batchSize) {
this.batchSize = batchSize;
}
public Collection<? super Collection<T>> getTo() {
return to;
}
@Override
public void setTo(Collection<? super Collection<T>> next) {
this.to = next;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
if (name == null) {
return getClass().getSimpleName();
}
else {
return name;
}
}
}