package org.sculptor.shipping.core.domain;
import java.util.ArrayList;
import java.util.List;
import org.joda.time.DateTime;
import org.sculptor.framework.event.DynamicMethodDispatcher;
/**
*
* Entity representing Ship. This class is responsible for the domain object
* related business logic for Ship. Properties and associations are implemented
* in the generated base class
* {@link org.sculptor.shipping.core.domain.ShipBase}.
*/
public class Ship extends ShipBase {
private static final long serialVersionUID = 1L;
protected Ship() {
}
/**
* Use {@link #createNew(String, String)} for constructing new InventoryItem
* instances. This constructor is needed for persistence mapper.
*/
public Ship(ShipId shipId) {
super(shipId);
}
public static Ship createNew(ShipId shipId, String name) {
Ship result = new Ship(shipId);
result.applyChange(new ShipCreated(new DateTime(), shipId, name));
return result;
}
public void arrival(Port port) {
applyChange(new ShipHasArrived(new DateTime(), getShipId(), port));
}
public void apply(ShipHasArrived event) {
setPort(event.getPort());
}
public boolean isAtSea() {
return getPort() == null;
}
public void departure(Port port) {
applyChange(new ShipHasDepartured(new DateTime(), getShipId(), port));
}
public void apply(ShipHasDepartured event) {
setPort(null);
}
public void load(Cargo cargo) {
applyChange(new CargoLoaded(new DateTime(), getShipId(), cargo));
}
public void apply(CargoLoaded event) {
addCargo(event.getCargo());
}
public void unload(Cargo cargo) {
applyChange(new CargoUnloaded(new DateTime(), getShipId(), cargo));
}
public void apply(CargoUnloaded event) {
removeCargo(event.getCargo());
}
public void apply(ShipCreated event) {
setName(event.getName());
}
public void apply(Object other) {
// ignore
}
private final List<ShipEvent> changes = new ArrayList<ShipEvent>();
public List<ShipEvent> getUncommittedChanges() {
return changes;
}
public void markChangesAsCommitted() {
changes.clear();
}
private void applyChange(ShipEvent event, boolean isNew) {
DynamicMethodDispatcher.dispatch(this, event, "apply");
if (isNew) {
changes.add(event);
} else {
setVersion(event.getAggregateVersion());
}
}
private void applyChange(ShipEvent event) {
applyChange(event, true);
}
public void loadFromHistory(List<ShipEvent> history) {
for (ShipEvent each : history) {
applyChange(each, false);
}
}
}