package org.nightlabs.jfire.trade.ui.transfer.deliver;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.nightlabs.datastructure.Pair;
import org.nightlabs.jfire.store.deliver.AbstractDeliveryController;
import org.nightlabs.jfire.store.deliver.Delivery;
import org.nightlabs.jfire.store.deliver.DeliveryData;
import org.nightlabs.jfire.store.deliver.DeliveryException;
import org.nightlabs.jfire.store.deliver.DeliveryResult;
import org.nightlabs.jfire.store.deliver.id.DeliveryID;
import org.nightlabs.jfire.transfer.TransferController;
/**
* A controller for the different stages of the delivery process as described in the
* <a href="https://www.jfire.org/modules/phpwiki/index.php/WorkflowPaymentAndDelivery">JFire Wiki</a>.
*
* @author Tobias Langner <!-- tobias[dot]langner[at]nightlabs[dot]de -->
* @see TransferController
*/
public class DeliveryControllerImpl extends AbstractDeliveryController {
private Map<DeliveryData, ClientDeliveryProcessor> deliveryProcessorMap;
/**
* Initialises a DeliveryControllerImpl with the list of tuples of the type ({@link DeliveryData}, {@link ClientDeliveryProcessor}). The controller
* will process all given {@link DeliveryData}s using the respective {@link ClientDeliveryProcessor} in the client stages.
* @param deliveryTuples A list of tuples of {@link DeliveryData} and a corresponding {@link ClientDeliveryProcessor}.
*/
// public DeliveryControllerImpl(List<Tuple<DeliveryData, ClientDeliveryProcessor>> deliveryTuples) {
// super();
// deliveryProcessorMap = new HashMap<DeliveryData, ClientDeliveryProcessor>();
// List<DeliveryData> deliveryDatas = new LinkedList<DeliveryData>();
// for (Tuple<DeliveryData, ClientDeliveryProcessor> tuple : deliveryTuples) {
// deliveryDatas.add(tuple.getElement1());
// deliveryProcessorMap.put(tuple.getElement1(), tuple.getElem2());
// }
// setTransferDatas(deliveryDatas);
// }
public DeliveryControllerImpl(List<Pair<DeliveryData, ClientDeliveryProcessor>> deliveryTuples) {
super(getDeliveryDatas(deliveryTuples));
deliveryProcessorMap = new HashMap<DeliveryData, ClientDeliveryProcessor>();
for (Pair<DeliveryData, ClientDeliveryProcessor> tuple : deliveryTuples) {
deliveryProcessorMap.put(tuple.getFirst(), tuple.getSecond());
}
}
private static List<DeliveryData> getDeliveryDatas(List<Pair<DeliveryData, ClientDeliveryProcessor>> deliveryTuples) {
List<DeliveryData> deliveryDatas = new LinkedList<DeliveryData>();
for (Pair<DeliveryData, ClientDeliveryProcessor> tuple : deliveryTuples) {
DeliveryData data = tuple.getFirst();
deliveryDatas.add(data);
}
return deliveryDatas;
}
/*
* (non-Javadoc)
* @see org.nightlabs.jfire.trade.ui.transfer.TransferController#clientBegin()
*/
@Override
public boolean _clientBegin() {
boolean allFailed = true;
ClientDeliveryProcessor clientDeliveryProcessor = null;
Delivery delivery = null;
ArrayList<DeliveryResult> deliverBeginClientResults = new ArrayList<DeliveryResult>(getTransferDatas().size());
for (DeliveryData deliveryData : getTransferDatas()) {
clientDeliveryProcessor = deliveryProcessorMap.get(deliveryData);
delivery = deliveryData.getDelivery();
try {
DeliveryResult deliverBeginClientResult = clientDeliveryProcessor.deliverBegin();
if (deliverBeginClientResult == null)
deliverBeginClientResult = new DeliveryResult(
DeliveryResult.CODE_APPROVED_NO_EXTERNAL,
(String)null,
(Throwable)null);
delivery.setDeliverBeginClientResult(deliverBeginClientResult);
} catch (DeliveryException x) {
delivery.setDeliverBeginClientResult(x.getDeliveryResult());
} catch (Throwable t) {
DeliveryResult deliverBeginClientResult = new DeliveryResult(t);
delivery.setDeliverBeginClientResult(deliverBeginClientResult);
}
deliverBeginClientResults.add(delivery.getDeliverBeginClientResult());
allFailed &= delivery.isFailed();
}
setLastStageResults(deliverBeginClientResults);
return !allFailed;
}
/*
* (non-Javadoc)
* @see org.nightlabs.jfire.trade.ui.transfer.TransferController#clientDoWork()
*/
@Override
public void _clientDoWork() {
List<DeliveryID> deliveryIDs = new ArrayList<DeliveryID>(getTransferDatas().size());
ArrayList<DeliveryResult> deliverDoWorkClientResults = new ArrayList<DeliveryResult>(getTransferDatas().size());
ClientDeliveryProcessor clientDeliveryProcessor = null;
for (DeliveryData deliveryData : getTransferDatas()) {
Delivery delivery = deliveryData.getDelivery();
clientDeliveryProcessor = deliveryProcessorMap.get(deliveryData);
deliveryIDs.add(DeliveryID.create(delivery.getOrganisationID(), delivery.getDeliveryID()));
try {
DeliveryResult deliverDoWorkClientResult = clientDeliveryProcessor.deliverDoWork();
if (deliverDoWorkClientResult == null)
deliverDoWorkClientResult = new DeliveryResult(
DeliveryResult.CODE_DELIVERED_NO_EXTERNAL,
(String)null,
(Throwable)null);
delivery.setDeliverDoWorkClientResult(deliverDoWorkClientResult);
} catch (DeliveryException x) {
delivery.setDeliverDoWorkClientResult(x.getDeliveryResult());
} catch (Throwable t) {
DeliveryResult deliverDoWorkClientResult = new DeliveryResult(t);
delivery.setDeliverDoWorkClientResult(deliverDoWorkClientResult);
}
deliverDoWorkClientResults.add(delivery.getDeliverDoWorkClientResult());
}
setLastStageResults(deliverDoWorkClientResults);
}
/*
* (non-Javadoc)
* @see org.nightlabs.jfire.trade.ui.transfer.TransferController#clientEnd()
*/
@Override
public void _clientEnd() {
ClientDeliveryProcessor clientDeliveryProcessor = null;
Delivery delivery = null;
List<DeliveryResult> deliverEndClientResults = new ArrayList<DeliveryResult>(getTransferDatas().size());
for (DeliveryData deliveryData : getTransferDatas()) {
clientDeliveryProcessor = deliveryProcessorMap.get(deliveryData);
delivery = deliveryData.getDelivery();
try {
DeliveryResult deliverEndClientResult = clientDeliveryProcessor.deliverEnd();
if (deliverEndClientResult == null) {
if (delivery.isForceRollback() || delivery.isFailed()) {
deliverEndClientResult = new DeliveryResult(
DeliveryResult.CODE_ROLLED_BACK_NO_EXTERNAL,
(String)null,
(Throwable)null);
}
else {
deliverEndClientResult = new DeliveryResult(
DeliveryResult.CODE_COMMITTED_NO_EXTERNAL,
(String)null,
(Throwable)null);
}
}
delivery.setDeliverEndClientResult(deliverEndClientResult);
} catch (DeliveryException x) {
delivery.setDeliverEndClientResult(x.getDeliveryResult());
} catch (Throwable t) {
DeliveryResult deliverEndClientResult = new DeliveryResult(t);
delivery.setDeliverEndClientResult(deliverEndClientResult);
}
deliverEndClientResults.add(delivery.getDeliverEndClientResult());
}
setLastStageResults(deliverEndClientResults);
}
// /*
// * (non-Javadoc)
// * @see org.nightlabs.jfire.trade.ui.transfer.TransferController#isRollbackRequired()
// */
// @Override
// public boolean isRollbackRequired() {
// if (isForceRollback())
// return true;
//
// for (DeliveryData deliveryData : getTransferDatas()) {
// Delivery delivery = deliveryData.getDelivery();
// if (delivery.isFailed() || delivery.isForceRollback())
// return true;
// }
//
// return false;
// }
/*
* (non-Javadoc)
* @see org.nightlabs.jfire.trade.ui.transfer.TransferController#verifyData()
*/
@Override
public void verifyData() {
for (DeliveryData deliveryData : getTransferDatas()) {
Delivery delivery = deliveryData.getDelivery();
if ((delivery.getDeliverBeginClientResult() != null && delivery.getDeliverBeginClientResult().isRolledBack()) ||
(delivery.getDeliverBeginServerResult() != null && delivery.getDeliverBeginServerResult().isRolledBack()) ||
(delivery.getDeliverDoWorkClientResult() != null && delivery.getDeliverDoWorkClientResult().isRolledBack()) ||
(delivery.getDeliverDoWorkServerResult() != null && delivery.getDeliverDoWorkServerResult().isRolledBack()) ||
(delivery.getDeliverEndClientResult() != null && delivery.getDeliverEndClientResult().isRolledBack()) ||
(delivery.getDeliverEndServerResult() != null && delivery.getDeliverEndServerResult().isRolledBack()))
delivery.setRollbackStatus(Delivery.ROLLBACK_STATUS_DONE_NORMAL); // TODO this might differ from the value on the server - do we better download the data from the server?
}
}
}