Merge branch 'feature/node_impl' into develop

This commit is contained in:
Nikita Iryupin 2020-12-28 10:14:35 +01:00
commit 06dc9e86f0
5 changed files with 59 additions and 15 deletions

View File

@ -55,6 +55,9 @@ public abstract class ChannelBase implements Observable {
public boolean tick() { public boolean tick() {
requirements.forEach(Requirement::tick); requirements.forEach(Requirement::tick);
try {
requirements.stream().filter(r -> r.getTTL() == 0).forEach(re -> re.getCreator().getProductFromStorage(re.getProductName(), re.getProductType()).setStateToAvailable());
} catch (Exception ignored) {}
requirements = requirements.stream().filter(r -> r.getTTL() > 0).collect(Collectors.toCollection(LinkedList::new)); requirements = requirements.stream().filter(r -> r.getTTL() > 0).collect(Collectors.toCollection(LinkedList::new));
notifyAllObservers(); notifyAllObservers();
return requirements.size() != 0; return requirements.size() != 0;

View File

@ -15,16 +15,14 @@ import org.javamoney.moneta.Money;
import javax.money.MonetaryAmount; import javax.money.MonetaryAmount;
import javax.naming.InsufficientResourcesException; import javax.naming.InsufficientResourcesException;
import java.util.HashMap; import java.util.*;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class NodeBase implements ChannelObserver { public class NodeBase implements ChannelObserver {
private final Map<ChannelBase, ChannelSubscriptionType> subscribedChannels; private final Map<ChannelBase, ChannelSubscriptionType> subscribedChannels;
private final List<Product> products; private final List<Product> products;
private final List<Transaction> refusedTransactions; private final List<Transaction> refusedTransactions;
private final List<RefusedRequirement> refusedRequirements;
private MonetaryAmount money; private MonetaryAmount money;
@ -37,6 +35,7 @@ public class NodeBase implements ChannelObserver {
this.subscribedChannels = new HashMap<>(); this.subscribedChannels = new HashMap<>();
this.products = new LinkedList<>(); this.products = new LinkedList<>();
this.refusedTransactions = new LinkedList<>(); this.refusedTransactions = new LinkedList<>();
this.refusedRequirements = new LinkedList<>();
this.money = Money.of(0, "USD"); this.money = Money.of(0, "USD");
} }
@ -44,6 +43,7 @@ public class NodeBase implements ChannelObserver {
this.subscribedChannels = new HashMap<>(); this.subscribedChannels = new HashMap<>();
this.products = new LinkedList<>(); this.products = new LinkedList<>();
this.refusedTransactions = new LinkedList<>(); this.refusedTransactions = new LinkedList<>();
this.refusedRequirements = new LinkedList<>();
this.money = Money.of(m, "USD"); this.money = Money.of(m, "USD");
} }
@ -55,7 +55,7 @@ public class NodeBase implements ChannelObserver {
.filter(ch -> ch.getProductType().equals(product.getProductType())) .filter(ch -> ch.getProductType().equals(product.getProductType()))
.findAny().ifPresent(channel -> channel.addTransaction(transaction)); .findAny().ifPresent(channel -> channel.addTransaction(transaction));
} catch (InsufficientResourcesException e) { } catch (InsufficientResourcesException e) {
e.printStackTrace(); System.err.println(e.getMessage());
} }
} }
@ -67,7 +67,7 @@ public class NodeBase implements ChannelObserver {
.filter(ch -> ch.getProductType().equals(prevTransaction.getProduct().getProductType())) .filter(ch -> ch.getProductType().equals(prevTransaction.getProduct().getProductType()))
.findAny().ifPresent(channel -> channel.addTransaction(transaction)); .findAny().ifPresent(channel -> channel.addTransaction(transaction));
} catch (InsufficientResourcesException e) { } catch (InsufficientResourcesException e) {
e.printStackTrace(); System.err.println(e.getMessage());
} }
} }
@ -124,6 +124,16 @@ public class NodeBase implements ChannelObserver {
price = getProductFromStorage(pName, pType).getPrice(); price = getProductFromStorage(pName, pType).getPrice();
} }
catch (NullPointerException e) { catch (NullPointerException e) {
refusedRequirements.add(new RefusedRequirement(tType, pType, pName, price));
throw new InsufficientResourcesException("product unavailable");
}
}
if (tType == TransactionType.SALE) {
try {
getProductFromStorage(pName, pType).setStateToInRequirement();
}
catch (NullPointerException | IllegalStateException e) {
refusedRequirements.add(new RefusedRequirement(tType, pType, pName, price));
throw new InsufficientResourcesException("product unavailable"); throw new InsufficientResourcesException("product unavailable");
} }
} }
@ -239,9 +249,10 @@ public class NodeBase implements ChannelObserver {
} }
boolean requirementCheck(Requirement req) { boolean requirementCheck(Requirement req) {
Product product = getProductFromStorage(req.getProductName(), req.getProductType());
return (req.getTransactionType() == TransactionType.SALE && money.isGreaterThanOrEqualTo(req.getPrice())) || return (req.getTransactionType() == TransactionType.SALE && money.isGreaterThanOrEqualTo(req.getPrice())) ||
(req.getTransactionType() == TransactionType.PURCHASE && getProductFromStorage(req.getProductName(), req.getProductType()) != null && (req.getTransactionType() == TransactionType.PURCHASE && product != null &&
getProductFromStorage(req.getProductName(), req.getProductType()).getProductState() == ProductState.AVAILABLE); ((product.getProductState() == ProductState.AVAILABLE) || product.getProductState() == ProductState.IN_REQUIREMENT));
} }
@Override @Override
@ -261,3 +272,17 @@ public class NodeBase implements ChannelObserver {
//System.out.println(this.getClass().getSimpleName() + ": " + money.getNumber()); //System.out.println(this.getClass().getSimpleName() + ": " + money.getNumber());
} }
} }
class RefusedRequirement {
public final TransactionType tType;
public final ProductType pType;
public final String pName;
public final MonetaryAmount price;
public RefusedRequirement(TransactionType tType, ProductType pType, String pName, MonetaryAmount price) {
this.tType = tType;
this.pType = pType;
this.pName = pName;
this.price = price;
}
}

View File

@ -17,7 +17,7 @@ public class ProductTransaction extends Transaction {
this.product = product; this.product = product;
type = null; type = null;
lastOperation = product.getCurrentOperation(); lastOperation = product.getCurrentOperation();
if (product == null || product.getProductState() != ProductState.AVAILABLE) throw new InsufficientResourcesException("product not available"); if (product == null || product.getProductState() != ProductState.IN_REQUIREMENT) throw new InsufficientResourcesException("product unavailable");
product.setCurrentOperation(this); product.setCurrentOperation(this);
product.setStateToReadyForDispatch(); product.setStateToReadyForDispatch();
creator.getStorage().remove(product); creator.getStorage().remove(product);

View File

@ -71,22 +71,27 @@ public class Product
// "State machine methods" // "State machine methods"
/** /**
* Set current product state to AVAILABLE * Set current product state to AVAILABLE. Throws IllegalStateException if the product is not IN_ACTION, READY_FOR_RECEPTION or IN_REQUIREMENT.
*/ */
public void setStateToAvailable() public void setStateToAvailable()
{ {
if (this.productState.equals(ProductState.IN_ACTION) ||
this.productState.equals(ProductState.READY_FOR_RECEPTION) ||
this.productState.equals(ProductState.IN_REQUIREMENT))
this.productState = ProductState.AVAILABLE; this.productState = ProductState.AVAILABLE;
else
throw new IllegalStateException("Cannot set state AVAILABLE. Product is not IN_ACTION, READY_FOR_RECEPTION or IN_REQUIREMENT");
} }
/** /**
* Set current product state to READY_FOR_DISPATCH. Throws IllegalStateException if the product is not AVAILABLE. * Set current product state to READY_FOR_DISPATCH. Throws IllegalStateException if the product is not IN_REQUIREMENT.
*/ */
public void setStateToReadyForDispatch() public void setStateToReadyForDispatch()
{ {
if(this.productState.equals(ProductState.AVAILABLE)) if(this.productState.equals(ProductState.IN_REQUIREMENT))
this.productState = ProductState.READY_FOR_DISPATCH; this.productState = ProductState.READY_FOR_DISPATCH;
else else
throw new IllegalStateException("Cannot set state READY_FOR_DISPATCH. Product is not AVAILABLE!"); throw new IllegalStateException("Cannot set state READY_FOR_DISPATCH. Product is not IN_REQUIREMENT!");
} }
/** /**
@ -122,6 +127,17 @@ public class Product
throw new IllegalStateException("Cannot set state IN_ACTION. Product is not AVAILABLE!"); throw new IllegalStateException("Cannot set state IN_ACTION. Product is not AVAILABLE!");
} }
/**
* Set current product state to IN_REQUIREMENT. Throws IllegalStateException if the product is not AVAILABLE.
*/
public void setStateToInRequirement()
{
if(this.productState.equals(ProductState.AVAILABLE))
this.productState = ProductState.IN_REQUIREMENT;
else
throw new IllegalStateException("Cannot set state IN_REQUIREMENT. Product is not AVAILABLE!");
}
/* /*
public void setProductState(ProductState productState) public void setProductState(ProductState productState)
{ {

View File

@ -2,5 +2,5 @@ package cz.cvut.fel.sit.omo.foodchain.product;
public enum ProductState public enum ProductState
{ {
AVAILABLE, READY_FOR_DISPATCH, IN_TRANSIT, READY_FOR_RECEPTION, IN_ACTION AVAILABLE, READY_FOR_DISPATCH, IN_TRANSIT, READY_FOR_RECEPTION, IN_ACTION, IN_REQUIREMENT
} }