diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/channel/ChannelBase.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/channel/ChannelBase.java index 46d8095..54fad99 100644 --- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/channel/ChannelBase.java +++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/channel/ChannelBase.java @@ -55,6 +55,9 @@ public abstract class ChannelBase implements Observable { public boolean 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)); notifyAllObservers(); return requirements.size() != 0; diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/node/base/NodeBase.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/node/base/NodeBase.java index 08f340c..8db8843 100644 --- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/node/base/NodeBase.java +++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/node/base/NodeBase.java @@ -15,16 +15,14 @@ import org.javamoney.moneta.Money; import javax.money.MonetaryAmount; import javax.naming.InsufficientResourcesException; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; +import java.util.*; public class NodeBase implements ChannelObserver { private final Map subscribedChannels; private final List products; private final List refusedTransactions; + private final List refusedRequirements; private MonetaryAmount money; @@ -37,6 +35,7 @@ public class NodeBase implements ChannelObserver { this.subscribedChannels = new HashMap<>(); this.products = new LinkedList<>(); this.refusedTransactions = new LinkedList<>(); + this.refusedRequirements = new LinkedList<>(); this.money = Money.of(0, "USD"); } @@ -44,6 +43,7 @@ public class NodeBase implements ChannelObserver { this.subscribedChannels = new HashMap<>(); this.products = new LinkedList<>(); this.refusedTransactions = new LinkedList<>(); + this.refusedRequirements = new LinkedList<>(); this.money = Money.of(m, "USD"); } @@ -55,7 +55,7 @@ public class NodeBase implements ChannelObserver { .filter(ch -> ch.getProductType().equals(product.getProductType())) .findAny().ifPresent(channel -> channel.addTransaction(transaction)); } 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())) .findAny().ifPresent(channel -> channel.addTransaction(transaction)); } catch (InsufficientResourcesException e) { - e.printStackTrace(); + System.err.println(e.getMessage()); } } @@ -124,6 +124,16 @@ public class NodeBase implements ChannelObserver { price = getProductFromStorage(pName, pType).getPrice(); } 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"); } } @@ -239,9 +249,10 @@ public class NodeBase implements ChannelObserver { } boolean requirementCheck(Requirement req) { + Product product = getProductFromStorage(req.getProductName(), req.getProductType()); return (req.getTransactionType() == TransactionType.SALE && money.isGreaterThanOrEqualTo(req.getPrice())) || - (req.getTransactionType() == TransactionType.PURCHASE && getProductFromStorage(req.getProductName(), req.getProductType()) != null && - getProductFromStorage(req.getProductName(), req.getProductType()).getProductState() == ProductState.AVAILABLE); + (req.getTransactionType() == TransactionType.PURCHASE && product != null && + ((product.getProductState() == ProductState.AVAILABLE) || product.getProductState() == ProductState.IN_REQUIREMENT)); } @Override @@ -261,3 +272,17 @@ public class NodeBase implements ChannelObserver { //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; + } +} diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/operation/ProductTransaction.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/operation/ProductTransaction.java index 640ca63..68c5b69 100644 --- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/operation/ProductTransaction.java +++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/operation/ProductTransaction.java @@ -17,7 +17,7 @@ public class ProductTransaction extends Transaction { this.product = product; type = null; 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.setStateToReadyForDispatch(); creator.getStorage().remove(product); diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/product/Product.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/product/Product.java index 6252afd..b556cb1 100644 --- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/product/Product.java +++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/product/Product.java @@ -71,22 +71,27 @@ public class Product // "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() { - this.productState = ProductState.AVAILABLE; + if (this.productState.equals(ProductState.IN_ACTION) || + this.productState.equals(ProductState.READY_FOR_RECEPTION) || + this.productState.equals(ProductState.IN_REQUIREMENT)) + 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() { - if(this.productState.equals(ProductState.AVAILABLE)) + if(this.productState.equals(ProductState.IN_REQUIREMENT)) this.productState = ProductState.READY_FOR_DISPATCH; 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!"); } + /** + * 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) { diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/product/ProductState.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/product/ProductState.java index 906282e..7e4be38 100644 --- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/product/ProductState.java +++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/product/ProductState.java @@ -2,5 +2,5 @@ package cz.cvut.fel.sit.omo.foodchain.product; 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 }