Merge branch 'feature/text_report_impl' into develop

This commit is contained in:
Nikita Iryupin 2021-01-04 15:52:02 +01:00
commit 6fac514d61
17 changed files with 377 additions and 67 deletions

View File

@ -19,7 +19,6 @@ pass
<scenario type="Farmer"> <scenario type="Farmer">
<steps> <steps>
generate generate
pass
sell FRUIT jablko sell FRUIT jablko
</steps> </steps>
</scenario> </scenario>

View File

@ -7,6 +7,7 @@ import cz.cvut.fel.sit.omo.foodchain.parser.ConfigurationParser;
import cz.cvut.fel.sit.omo.foodchain.parser.ParserResult; import cz.cvut.fel.sit.omo.foodchain.parser.ParserResult;
import cz.cvut.fel.sit.omo.foodchain.parser.ParserResultElement; import cz.cvut.fel.sit.omo.foodchain.parser.ParserResultElement;
import cz.cvut.fel.sit.omo.foodchain.product.Product; import cz.cvut.fel.sit.omo.foodchain.product.Product;
import cz.cvut.fel.sit.omo.foodchain.reporting.ReportingManager;
import cz.cvut.fel.sit.omo.foodchain.scenario.Scenario; import cz.cvut.fel.sit.omo.foodchain.scenario.Scenario;
import cz.cvut.fel.sit.omo.foodchain.util.ReportLogger; import cz.cvut.fel.sit.omo.foodchain.util.ReportLogger;
import cz.cvut.fel.sit.omo.foodchain.util.Ticker; import cz.cvut.fel.sit.omo.foodchain.util.Ticker;
@ -67,6 +68,10 @@ public class FoodChain
{ {
; ;
} }
ReportingManager reportingManager = new ReportingManager();
System.out.println(reportingManager.generateReport());
} }
public static FactoryManager getFactoryManager() public static FactoryManager getFactoryManager()

View File

@ -4,6 +4,7 @@ import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import cz.cvut.fel.sit.omo.foodchain.operation.ProductTransaction; import cz.cvut.fel.sit.omo.foodchain.operation.ProductTransaction;
import cz.cvut.fel.sit.omo.foodchain.operation.Transaction; import cz.cvut.fel.sit.omo.foodchain.operation.Transaction;
import cz.cvut.fel.sit.omo.foodchain.product.ProductType; import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
import cz.cvut.fel.sit.omo.foodchain.reporting.ReportTextVisitor;
import cz.cvut.fel.sit.omo.foodchain.requirement.Requirement; import cz.cvut.fel.sit.omo.foodchain.requirement.Requirement;
import cz.cvut.fel.sit.omo.foodchain.util.ChannelObserver; import cz.cvut.fel.sit.omo.foodchain.util.ChannelObserver;
import cz.cvut.fel.sit.omo.foodchain.util.Observable; import cz.cvut.fel.sit.omo.foodchain.util.Observable;

View File

@ -8,6 +8,7 @@ import cz.cvut.fel.sit.omo.foodchain.operation.*;
import cz.cvut.fel.sit.omo.foodchain.product.Product; import cz.cvut.fel.sit.omo.foodchain.product.Product;
import cz.cvut.fel.sit.omo.foodchain.product.ProductState; import cz.cvut.fel.sit.omo.foodchain.product.ProductState;
import cz.cvut.fel.sit.omo.foodchain.product.ProductType; import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
import cz.cvut.fel.sit.omo.foodchain.reporting.ReportTextVisitor;
import cz.cvut.fel.sit.omo.foodchain.requirement.Requirement; import cz.cvut.fel.sit.omo.foodchain.requirement.Requirement;
import cz.cvut.fel.sit.omo.foodchain.signature.SignatureManager; import cz.cvut.fel.sit.omo.foodchain.signature.SignatureManager;
import cz.cvut.fel.sit.omo.foodchain.util.ChannelObserver; import cz.cvut.fel.sit.omo.foodchain.util.ChannelObserver;
@ -52,6 +53,7 @@ public class NodeBase implements ChannelObserver {
/** /**
* Sends product transaction to node through a channel based on its type. * Sends product transaction to node through a channel based on its type.
*
* @param product product to be sent * @param product product to be sent
* @param node receiver node * @param node receiver node
*/ */
@ -69,6 +71,7 @@ public class NodeBase implements ChannelObserver {
/** /**
* Sends financial transaction to node through a channel based on previous transaction type. * Sends financial transaction to node through a channel based on previous transaction type.
*
* @param amount amount to be sent * @param amount amount to be sent
* @param node receiver node * @param node receiver node
* @param prevTransaction previous product transaction * @param prevTransaction previous product transaction
@ -86,17 +89,16 @@ public class NodeBase implements ChannelObserver {
/** /**
* Receives (processes) transaction. * Receives (processes) transaction.
*
* @param transaction transaction to be received * @param transaction transaction to be received
*/ */
public void receiveTransaction(Transaction transaction) { public void receiveTransaction(Transaction transaction) {
try { try {
receiveTransaction((ProductTransaction) transaction); receiveTransaction((ProductTransaction) transaction);
} } catch (Exception e) {
catch (Exception e) {
try { try {
receiveTransaction((FinancialTransaction) transaction); receiveTransaction((FinancialTransaction) transaction);
} } catch (Exception ex) {
catch (Exception ex) {
LOGGER.log(Level.WARNING, e.getMessage()); LOGGER.log(Level.WARNING, e.getMessage());
} }
} }
@ -104,6 +106,7 @@ public class NodeBase implements ChannelObserver {
/** /**
* Receives (validates) product transaction and sends financial transaction as response. * Receives (validates) product transaction and sends financial transaction as response.
*
* @param transaction transaction to be received * @param transaction transaction to be received
*/ */
public void receiveTransaction(ProductTransaction transaction) { public void receiveTransaction(ProductTransaction transaction) {
@ -112,12 +115,12 @@ public class NodeBase implements ChannelObserver {
transaction.endTransaction(); transaction.endTransaction();
sendTransaction(transaction.getProduct().getPrice(), transaction.getNodeCreator(), transaction); sendTransaction(transaction.getProduct().getPrice(), transaction.getNodeCreator(), transaction);
} } else refuseTransaction(transaction);
else refuseTransaction(transaction);
} }
/** /**
* Receives (validates) financial transaction. * Receives (validates) financial transaction.
*
* @param transaction transaction to be received * @param transaction transaction to be received
*/ */
public void receiveTransaction(FinancialTransaction transaction) { public void receiveTransaction(FinancialTransaction transaction) {
@ -128,6 +131,7 @@ public class NodeBase implements ChannelObserver {
/** /**
* Adds transaction to refused transactions. * Adds transaction to refused transactions.
*
* @param transaction * @param transaction
*/ */
public void refuseTransaction(Transaction transaction) { public void refuseTransaction(Transaction transaction) {
@ -139,11 +143,15 @@ public class NodeBase implements ChannelObserver {
* Receives all transactions for this node. * Receives all transactions for this node.
*/ */
public void receiveTransactions() { public void receiveTransactions() {
subscribedChannels.keySet().forEach(ch -> ch.getTransactions(this).forEach(t -> {receiveTransaction(t); ch.disposeOf(t);})); subscribedChannels.keySet().forEach(ch -> ch.getTransactions(this).forEach(t -> {
receiveTransaction(t);
ch.disposeOf(t);
}));
} }
/** /**
* Creates requirement based on data provided. * Creates requirement based on data provided.
*
* @param tType transaction type * @param tType transaction type
* @param pType product type * @param pType product type
* @param pName product name * @param pName product name
@ -154,8 +162,7 @@ public class NodeBase implements ChannelObserver {
if (price == null) { if (price == null) {
try { try {
price = storage.getProduct(pName, pType).getPrice(); price = storage.getProduct(pName, pType).getPrice();
} } catch (NullPointerException e) {
catch (NullPointerException e) {
refusedRequirements.add(new RefusedRequirement(tType, pType, pName, price)); refusedRequirements.add(new RefusedRequirement(tType, pType, pName, price));
throw new InsufficientResourcesException("product unavailable"); throw new InsufficientResourcesException("product unavailable");
} }
@ -163,8 +170,7 @@ public class NodeBase implements ChannelObserver {
if (tType == TransactionType.SALE) { if (tType == TransactionType.SALE) {
try { try {
storage.getProduct(pName, pType).setStateToInRequirement(); storage.getProduct(pName, pType).setStateToInRequirement();
} } catch (NullPointerException | IllegalStateException e) {
catch (NullPointerException | IllegalStateException e) {
refusedRequirements.add(new RefusedRequirement(tType, pType, pName, price)); refusedRequirements.add(new RefusedRequirement(tType, pType, pName, price));
throw new InsufficientResourcesException("product unavailable"); throw new InsufficientResourcesException("product unavailable");
} }
@ -177,6 +183,7 @@ public class NodeBase implements ChannelObserver {
/** /**
* Accepts requirement and creates response. * Accepts requirement and creates response.
*
* @param req requirement to be accepted * @param req requirement to be accepted
* @throws InsufficientResourcesException if product is unavailable * @throws InsufficientResourcesException if product is unavailable
*/ */
@ -184,19 +191,18 @@ public class NodeBase implements ChannelObserver {
LOGGER.log(Level.INFO, this.nodeType.toString() + " accepted " + req.toString()); LOGGER.log(Level.INFO, this.nodeType.toString() + " accepted " + req.toString());
if (req.getTransactionType() == TransactionType.SALE) { if (req.getTransactionType() == TransactionType.SALE) {
createRequirement(TransactionType.PURCHASE, req.getProductType(), req.getProductName(), req.getPrice()); createRequirement(TransactionType.PURCHASE, req.getProductType(), req.getProductName(), req.getPrice());
} } else {
else {
if (req.getPrice().isGreaterThanOrEqualTo(storage.getProduct(req.getProductName(), req.getProductType()).getPrice().multiply(0.9))) { if (req.getPrice().isGreaterThanOrEqualTo(storage.getProduct(req.getProductName(), req.getProductType()).getPrice().multiply(0.9))) {
storage.getProduct(req.getProductName(), req.getProductType()).setPrice(req.getPrice()); storage.getProduct(req.getProductName(), req.getProductType()).setPrice(req.getPrice());
sendTransaction(storage.getProduct(req.getProductName(), req.getProductType()), req.getCreator()); sendTransaction(storage.getProduct(req.getProductName(), req.getProductType()), req.getCreator());
} } else createRequirement(TransactionType.SALE, req.getProductType(), req.getProductName(), req.getPrice());
else createRequirement(TransactionType.SALE, req.getProductType(), req.getProductName(), req.getPrice());
} }
} }
/** /**
* Adds channel to subscribed channels with correct type. * Adds channel to subscribed channels with correct type.
*
* @param channel channel to be subscribed * @param channel channel to be subscribed
* @param type type of subscription * @param type type of subscription
*/ */
@ -208,6 +214,7 @@ public class NodeBase implements ChannelObserver {
/** /**
* Removes channel from subscribed channels. * Removes channel from subscribed channels.
*
* @param channel * @param channel
*/ */
public void unsubscribeFromChannel(ChannelBase channel) { public void unsubscribeFromChannel(ChannelBase channel) {
@ -217,20 +224,20 @@ public class NodeBase implements ChannelObserver {
/** /**
* Proceed specific type of action on provided product if its possible. (Propagated to its storage). * Proceed specific type of action on provided product if its possible. (Propagated to its storage).
*
* @param action type of product operation to do * @param action type of product operation to do
* @param product product to proceed * @param product product to proceed
*/ */
public void doAction(ProductOperationType action, Product product) throws IllegalCallerException public void doAction(ProductOperationType action, Product product) throws IllegalCallerException {
{ this.storage.doAction(action, product);
this.storage.doAction(action,product);
} }
/** /**
* Calls specific ProductOperation on each product in stock (Propagated to its storage). * Calls specific ProductOperation on each product in stock (Propagated to its storage).
*
* @param action ProductOperationType * @param action ProductOperationType
*/ */
public void doAction(ProductOperationType action) public void doAction(ProductOperationType action) {
{
this.storage.doAction(action); this.storage.doAction(action);
} }
@ -246,16 +253,37 @@ public class NodeBase implements ChannelObserver {
return money; return money;
} }
public Map<ChannelBase, ChannelSubscriptionType> getSubscribedChannels() {
return subscribedChannels;
}
public List<Transaction> getRefusedTransactions() {
return refusedTransactions;
}
public NodeType getAllowedSeller() {
return allowedSeller;
}
public NodeType getAllowedPurchaser() {
return allowedPurchaser;
}
/** /**
* Adds amount to current assets * Adds amount to current assets
*
* @param m amount to be added * @param m amount to be added
*/ */
public void addMoney(MonetaryAmount m) { public void addMoney(MonetaryAmount m) {
this.money = this.money.add(m); this.money = this.money.add(m);
} }
/** /**
* Subtracts amount from current assets. * Subtracts amount from current assets.
*
* @param m amount to be subtracted * @param m amount to be subtracted
*/ */
public void subtractMoney(MonetaryAmount m) { public void subtractMoney(MonetaryAmount m) {
@ -264,6 +292,7 @@ public class NodeBase implements ChannelObserver {
/** /**
* Validates signature on transaction. * Validates signature on transaction.
*
* @param transaction transaction to be validated * @param transaction transaction to be validated
* @return signature is valid * @return signature is valid
*/ */
@ -273,6 +302,7 @@ public class NodeBase implements ChannelObserver {
/** /**
* Checks if requirement creator is an allowed purchaser or allowed seller. * Checks if requirement creator is an allowed purchaser or allowed seller.
*
* @param req requirement * @param req requirement
* @return creator is valid * @return creator is valid
*/ */
@ -286,6 +316,7 @@ public class NodeBase implements ChannelObserver {
/** /**
* Checks if requirement type corresponds with channel subscription type. * Checks if requirement type corresponds with channel subscription type.
*
* @param requirement requirement * @param requirement requirement
* @param channel channel * @param channel channel
* @return requirement type corresponds with channel subscription type * @return requirement type corresponds with channel subscription type
@ -305,6 +336,7 @@ public class NodeBase implements ChannelObserver {
/** /**
* Chacks if product is available or if node has enough money * Chacks if product is available or if node has enough money
*
* @param req requirement * @param req requirement
* @return product is available or node has enough money * @return product is available or node has enough money
*/ */
@ -317,6 +349,7 @@ public class NodeBase implements ChannelObserver {
/** /**
* Chacks incomming requirement. * Chacks incomming requirement.
*
* @param requirement requirement * @param requirement requirement
* @param channel channel * @param channel channel
*/ */
@ -352,4 +385,8 @@ public class NodeBase implements ChannelObserver {
this.price = price; this.price = price;
} }
} }
public String accept(ReportTextVisitor visitor) {
return visitor.visit(this);
}
} }

View File

@ -2,6 +2,7 @@ package cz.cvut.fel.sit.omo.foodchain.operation;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase; import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import cz.cvut.fel.sit.omo.foodchain.product.Product; import cz.cvut.fel.sit.omo.foodchain.product.Product;
import cz.cvut.fel.sit.omo.foodchain.reporting.ReportTextVisitor;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -10,16 +11,14 @@ import java.util.logging.Logger;
* Operation for processing products in storage * Operation for processing products in storage
*/ */
public class Action extends OperationBase { public class Action extends OperationBase {
private final OperationBase lastOperation;
private final Product product; private final Product product;
private final ProductOperationType type; private final ProductOperationType type;
private int duration; private int duration;
public Action(NodeBase node, Product product, ProductOperationType type) { public Action(NodeBase node, Product product, ProductOperationType type) {
super(node); super(node, product.getCurrentOperation());
this.product = product; this.product = product;
this.type = type; this.type = type;
lastOperation = product.getCurrentOperation();
duration = type.getDuration(); duration = type.getDuration();
product.setCurrentOperation(this); product.setCurrentOperation(this);
product.setStateToInAction(); product.setStateToInAction();
@ -48,10 +47,6 @@ public class Action extends OperationBase {
return true; return true;
} }
public OperationBase getLastOperation() {
return lastOperation;
}
public Product getProduct() { public Product getProduct() {
return product; return product;
} }
@ -68,4 +63,8 @@ public class Action extends OperationBase {
", duration=" + duration + ", duration=" + duration +
'}'; '}';
} }
public String accept(ReportTextVisitor visitor) {
return visitor.visit(this);
}
} }

View File

@ -1,6 +1,7 @@
package cz.cvut.fel.sit.omo.foodchain.operation; package cz.cvut.fel.sit.omo.foodchain.operation;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase; import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import cz.cvut.fel.sit.omo.foodchain.reporting.ReportTextVisitor;
import javax.money.MonetaryAmount; import javax.money.MonetaryAmount;
import javax.naming.InsufficientResourcesException; import javax.naming.InsufficientResourcesException;
@ -15,7 +16,7 @@ public class FinancialTransaction extends Transaction {
private final ProductTransaction transactionPaid; private final ProductTransaction transactionPaid;
public FinancialTransaction(NodeBase creator, NodeBase receiver, TransactionType type, MonetaryAmount amount, ProductTransaction transactionPaid) throws InsufficientResourcesException { public FinancialTransaction(NodeBase creator, NodeBase receiver, TransactionType type, MonetaryAmount amount, ProductTransaction transactionPaid) throws InsufficientResourcesException {
super(creator, receiver, type); super(creator, receiver, type, transactionPaid);
this.amount = amount; this.amount = amount;
this.transactionPaid = transactionPaid; this.transactionPaid = transactionPaid;
if (creator.getMoney().isLessThan(amount)) throw new InsufficientResourcesException("not enough money"); if (creator.getMoney().isLessThan(amount)) throw new InsufficientResourcesException("not enough money");
@ -48,4 +49,9 @@ public class FinancialTransaction extends Transaction {
", transactionPaid=" + transactionPaid + ", transactionPaid=" + transactionPaid +
'}'; '}';
} }
@Override
public String accept(ReportTextVisitor visitor) {
return visitor.visit(this);
}
} }

View File

@ -1,7 +1,8 @@
package cz.cvut.fel.sit.omo.foodchain.operation; package cz.cvut.fel.sit.omo.foodchain.operation;
import cz.cvut.fel.sit.omo.foodchain.factory.ScenarioFactory;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase; import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import cz.cvut.fel.sit.omo.foodchain.reporting.PartiesReportVisitor;
import cz.cvut.fel.sit.omo.foodchain.reporting.ReportTextVisitor;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -17,9 +18,11 @@ public abstract class OperationBase {
private LocalDateTime timeEnd; private LocalDateTime timeEnd;
private final NodeBase nodeCreator; private final NodeBase nodeCreator;
private final OperationBase lastOperation;
OperationBase(NodeBase node) { OperationBase(NodeBase node, OperationBase lastOperation) {
nodeCreator = node; nodeCreator = node;
this.lastOperation = lastOperation;
timeStart = LocalDateTime.now(); timeStart = LocalDateTime.now();
} }
@ -38,4 +41,12 @@ public abstract class OperationBase {
public NodeBase getNodeCreator() { public NodeBase getNodeCreator() {
return nodeCreator; return nodeCreator;
} }
public OperationBase getLastOperation() {
return lastOperation;
}
public String accept(ReportTextVisitor reportVisitor){
return reportVisitor.visit(this);
}
} }

View File

@ -3,6 +3,7 @@ package cz.cvut.fel.sit.omo.foodchain.operation;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase; import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import cz.cvut.fel.sit.omo.foodchain.product.Product; import cz.cvut.fel.sit.omo.foodchain.product.Product;
import cz.cvut.fel.sit.omo.foodchain.product.ProductState; import cz.cvut.fel.sit.omo.foodchain.product.ProductState;
import cz.cvut.fel.sit.omo.foodchain.reporting.ReportTextVisitor;
import javax.naming.InsufficientResourcesException; import javax.naming.InsufficientResourcesException;
import java.util.logging.Level; import java.util.logging.Level;
@ -12,15 +13,13 @@ import java.util.logging.Level;
*/ */
public class ProductTransaction extends Transaction { public class ProductTransaction extends Transaction {
private final OperationBase lastOperation;
private final Product product; private final Product product;
private final ProductOperationType type; private final ProductOperationType type;
public ProductTransaction(NodeBase creator, NodeBase receiver, TransactionType transactionType, Product product) throws InsufficientResourcesException { public ProductTransaction(NodeBase creator, NodeBase receiver, TransactionType transactionType, Product product) throws InsufficientResourcesException {
super(creator, receiver, transactionType); super(creator, receiver, transactionType, product.getCurrentOperation());
this.product = product; this.product = product;
type = null; type = null;
lastOperation = product.getCurrentOperation();
if (product == null || product.getProductState() != ProductState.IN_REQUIREMENT) throw new InsufficientResourcesException("product unavailable"); if (product == null || product.getProductState() != ProductState.IN_REQUIREMENT) throw new InsufficientResourcesException("product unavailable");
product.setCurrentOperation(this); product.setCurrentOperation(this);
product.setStateToReadyForDispatch(); product.setStateToReadyForDispatch();
@ -39,10 +38,6 @@ public class ProductTransaction extends Transaction {
product.setStateToAvailable(); product.setStateToAvailable();
} }
public OperationBase getLastOperation() {
return lastOperation;
}
public Product getProduct() { public Product getProduct() {
return product; return product;
} }
@ -57,4 +52,9 @@ public class ProductTransaction extends Transaction {
"product=" + product.getName() + "product=" + product.getName() +
'}'; '}';
} }
@Override
public String accept(ReportTextVisitor visitor) {
return visitor.visit(this);
}
} }

View File

@ -1,6 +1,7 @@
package cz.cvut.fel.sit.omo.foodchain.operation; package cz.cvut.fel.sit.omo.foodchain.operation;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase; import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import cz.cvut.fel.sit.omo.foodchain.reporting.ReportTextVisitor;
import cz.cvut.fel.sit.omo.foodchain.signature.Signature; import cz.cvut.fel.sit.omo.foodchain.signature.Signature;
import cz.cvut.fel.sit.omo.foodchain.signature.SignatureManager; import cz.cvut.fel.sit.omo.foodchain.signature.SignatureManager;
@ -13,8 +14,8 @@ public abstract class Transaction extends OperationBase {
private final Signature signature; private final Signature signature;
private final NodeBase nodeReceiver; private final NodeBase nodeReceiver;
Transaction(NodeBase creator, NodeBase receiver, TransactionType type) { Transaction(NodeBase creator, NodeBase receiver, TransactionType type, OperationBase lastOperation) {
super(creator); super(creator, lastOperation);
transactionType = type; transactionType = type;
nodeReceiver = receiver; nodeReceiver = receiver;
signature = SignatureManager.signTransaction(this); signature = SignatureManager.signTransaction(this);
@ -48,4 +49,6 @@ public abstract class Transaction extends OperationBase {
", nodeReceiver=" + nodeReceiver.getClass().getSimpleName() + ", nodeReceiver=" + nodeReceiver.getClass().getSimpleName() +
'}'; '}';
} }
public abstract String accept(ReportTextVisitor visitor);
} }

View File

@ -2,9 +2,9 @@ package cz.cvut.fel.sit.omo.foodchain.product;
import cz.cvut.fel.sit.omo.foodchain.operation.Action; import cz.cvut.fel.sit.omo.foodchain.operation.Action;
import cz.cvut.fel.sit.omo.foodchain.operation.OperationBase; import cz.cvut.fel.sit.omo.foodchain.operation.OperationBase;
import cz.cvut.fel.sit.omo.foodchain.reporting.ReportTextVisitor;
import org.javamoney.moneta.Money; import org.javamoney.moneta.Money;
import javax.money.Monetary;
import javax.money.MonetaryAmount; import javax.money.MonetaryAmount;
/** /**
@ -150,4 +150,8 @@ public class Product
public MonetaryAmount getPrice() { return price; } public MonetaryAmount getPrice() { return price; }
public void setPrice(MonetaryAmount price) { this.price = price; } public void setPrice(MonetaryAmount price) { this.price = price; }
public String accept(ReportTextVisitor visitor){
return visitor.visit(this);
}
} }

View File

@ -0,0 +1,35 @@
package cz.cvut.fel.sit.omo.foodchain.reporting;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import cz.cvut.fel.sit.omo.foodchain.operation.Action;
import cz.cvut.fel.sit.omo.foodchain.operation.FinancialTransaction;
import cz.cvut.fel.sit.omo.foodchain.operation.ProductTransaction;
import cz.cvut.fel.sit.omo.foodchain.product.Product;
public class FoodChainReportVisitor implements ReportTextVisitor {
@Override
public String visit(NodeBase node) {
return null;
}
@Override
public String visit(Product product) {
return null;
}
@Override
public String visit(ProductTransaction transaction) {
return null;
}
@Override
public String visit(FinancialTransaction transaction) {
return null;
}
@Override
public String visit(Action action) {
return null;
}
}

View File

@ -0,0 +1,77 @@
package cz.cvut.fel.sit.omo.foodchain.reporting;
import cz.cvut.fel.sit.omo.foodchain.channel.ChannelBase;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import cz.cvut.fel.sit.omo.foodchain.operation.*;
import cz.cvut.fel.sit.omo.foodchain.product.Product;
import java.util.LinkedList;
import java.util.List;
public class PartiesReportVisitor implements ReportTextVisitor {
private NodeBase current;
@Override
public String visit(NodeBase node) {
current = node;
StringBuilder builder = new StringBuilder();
builder.append("------NODE------").append(ln)
.append("Node type: ").append(node.getNodeType()).append(ln)
.append("Allowed seller: ").append(node.getAllowedSeller()).append(ln)
.append("Allowed purchaser: ").append(node.getAllowedPurchaser()).append(ln)
.append("Product sold and purchased, action provided: ").append(ln);
db.getProductPoolInstance().findAll().forEach(p -> builder.append(p.accept(this)));
builder.append(ln);
return builder.toString();
}
@Override
public String visit(Product product) {
if (current == null) return "";
StringBuilder builder = new StringBuilder();
List<OperationBase> operations = new LinkedList<>();
OperationBase operation = product.getCurrentOperation();
while (operation != null){
operations.add(operation);
operation = operation.getLastOperation();
}
operations.forEach(o -> builder.append(o.accept(this)));
if (builder.toString().equals("")) return "";
builder.append(ln);
return builder.toString();
}
@Override
public String visit(ProductTransaction transaction) {
if (transaction.getNodeCreator() == current)
return "Sell " + transaction.getProduct().getName() + ln;
else if (transaction.getNodeReceiver() == current)
return "Get " + transaction.getProduct().getName() + ln;
return "";
}
@Override
public String visit(FinancialTransaction transaction) {
if (transaction.getNodeCreator() == current)
return "Send " + transaction.getAmount() + ln;
else if (transaction.getNodeReceiver() == current)
return "Get " + transaction.getAmount() + ln;
return "";
}
@Override
public String visit(Action action) {
if (action.getNodeCreator() == current)
return "Action " + action.getType() + " with " + action.getProduct().getName() + ln;
return "";
}
}

View File

@ -0,0 +1,47 @@
package cz.cvut.fel.sit.omo.foodchain.reporting;
import cz.cvut.fel.sit.omo.foodchain.FoodChain;
import cz.cvut.fel.sit.omo.foodchain.pool.PoolDatabase;
public class ReportBuilder {
private final StringBuilder report;
private final PoolDatabase db;
public ReportBuilder(){
report = new StringBuilder();
db = FoodChain.getFactoryManager().getPoolDatabaseInstance();
}
public ReportBuilder addPartiesReport(){
ReportTextVisitor reportVisitor = new PartiesReportVisitor();
db.getNodePoolInstance().findAll().forEach(n -> report.append(reportVisitor.visit(n)));
return this;
}
public ReportBuilder addFoodChainReport(){
ReportTextVisitor reportVisitor = new FoodChainReportVisitor();
db.getProductPoolInstance().findAll().forEach(p -> report.append(reportVisitor.visit(p)));
return this;
}
public ReportBuilder addSecurityReport(){
ReportTextVisitor reportVisitor = new FoodChainReportVisitor();
db.getNodePoolInstance().findAll().forEach(n -> report.append(reportVisitor.visit(n)));
return this;
}
public ReportBuilder addTransactionReport(){
//TODO
return this;
}
public String build(){
return report.toString();
}
}

View File

@ -1,19 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.reporting;
import cz.cvut.fel.sit.omo.foodchain.channel.ChannelBase;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import cz.cvut.fel.sit.omo.foodchain.operation.OperationBase;
public class ReportTextFileVisitor {
public void visit(NodeBase node){
}
public void visit(OperationBase operationBase){
}
public void visit(ChannelBase channel){
}
}

View File

@ -0,0 +1,41 @@
package cz.cvut.fel.sit.omo.foodchain.reporting;
import cz.cvut.fel.sit.omo.foodchain.FoodChain;
import cz.cvut.fel.sit.omo.foodchain.channel.ChannelBase;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import cz.cvut.fel.sit.omo.foodchain.operation.*;
import cz.cvut.fel.sit.omo.foodchain.pool.PoolDatabase;
import cz.cvut.fel.sit.omo.foodchain.product.Product;
public interface ReportTextVisitor {
String ln = System.lineSeparator();
PoolDatabase db = FoodChain.getFactoryManager().getPoolDatabaseInstance();
String visit(NodeBase node);
String visit(Product product);
String visit(ProductTransaction transaction);
String visit(FinancialTransaction transaction);
String visit(Action action);
default String visit(OperationBase operationBase){
try
{
return visit((Action) operationBase);
} catch (ClassCastException e){
return visit((Transaction) operationBase);
}
}
default String visit(Transaction transaction){
try
{
return visit((ProductTransaction) transaction);
} catch (ClassCastException e){
return visit((FinancialTransaction) transaction);
}
}
}

View File

@ -1,4 +1,34 @@
package cz.cvut.fel.sit.omo.foodchain.reporting; package cz.cvut.fel.sit.omo.foodchain.reporting;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
public class ReportingManager { public class ReportingManager {
public void createFileTextReport(String pathname) {
File reportFile = new File(pathname);
try {
FileWriter fileWriter = new FileWriter(reportFile);
if (!reportFile.createNewFile()) {
throw new FileAlreadyExistsException(pathname);
}
fileWriter.write(generateReport());
} catch (IOException e) {
e.printStackTrace();
}
}
public String generateReport(){
ReportBuilder reportBuilder = new ReportBuilder();
return reportBuilder
.addPartiesReport()
.addFoodChainReport()
.addSecurityReport()
.addTransactionReport()
.build();
}
} }

View File

@ -0,0 +1,34 @@
package cz.cvut.fel.sit.omo.foodchain.reporting;
import cz.cvut.fel.sit.omo.foodchain.channel.ChannelBase;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import cz.cvut.fel.sit.omo.foodchain.operation.*;
import cz.cvut.fel.sit.omo.foodchain.product.Product;
public class SecurityReportReportVisitor implements ReportTextVisitor {
@Override
public String visit(NodeBase node) {
return null;
}
@Override
public String visit(Product product) {
return null;
}
@Override
public String visit(ProductTransaction transaction) {
return null;
}
@Override
public String visit(FinancialTransaction transaction) {
return null;
}
@Override
public String visit(Action action) {
return null;
}
}