package org.sculptor.shipping.statistics.serviceimpl; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import org.sculptor.framework.event.DynamicMethodDispatcher; import org.sculptor.framework.event.Event; import org.sculptor.framework.event.EventBus; import org.sculptor.framework.event.EventSubscriber; import org.sculptor.shipping.core.domain.ShipHasArrived; import org.sculptor.shipping.core.domain.ShipHasDepartured; import org.sculptor.shipping.core.domain.UnLocode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; /** * Implementation of Statistics. */ @Service("statistics") public class StatisticsImpl extends StatisticsImplBase { private static final Logger LOG = LoggerFactory.getLogger(StatisticsImpl.class); private final ConcurrentHashMap<UnLocode, AtomicInteger> shipsInPort = new ConcurrentHashMap<UnLocode, AtomicInteger>(); @Autowired @Qualifier("eventBus") private EventBus eventBus; public StatisticsImpl() { } public void somewhere() { eventBus.subscribe("shippingChannel", new EventSubscriber() { @Override public void receive(Event event) { System.out.println("Received: " + event); } }); } @Override public void receive(Event event) { DynamicMethodDispatcher.dispatch(this, event, "consume"); } @Override public void consume(ShipHasArrived event) { UnLocode key = event.getPort().getUnlocode(); int currentValue = addShipInPort(key, 1); LOG.info("### Ship {} arrived. Now there are {} ships in {}", event.getShip().getIdentifier(), currentValue, event.getPort().getUnlocode().getIdentifier()); } @Override public void consume(ShipHasDepartured event) { UnLocode key = event.getPort().getUnlocode(); int currentValue = addShipInPort(key, -1); LOG.info("### Ship {} departure. Now there are {} ships in {}", event.getShip().getIdentifier(), currentValue, event.getPort().getUnlocode().getIdentifier()); } private int addShipInPort(UnLocode key, int value) { int currentValue; AtomicInteger counter = shipsInPort.get(key); if (counter == null) { counter = new AtomicInteger(value); currentValue = counter.get(); AtomicInteger previous = shipsInPort.putIfAbsent(key, counter); if (previous != null) { currentValue = previous.addAndGet(value); } } else { currentValue = counter.addAndGet(value); } return currentValue; } @Override public void consume(Object any) { LOG.info("Ignored event: {}", any); } @Override public int getShipsInPort(UnLocode port) { AtomicInteger counter = shipsInPort.get(port); if (counter == null) { return 0; } else { return counter.get(); } } @Override public void reset() { shipsInPort.clear(); } }