Compare commits
No commits in common. "feature/text_report_impl" and "master" have entirely different histories.
feature/te
...
master
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,4 +0,0 @@
|
|||||||
.idea
|
|
||||||
target
|
|
||||||
|
|
||||||
*.idb
|
|
||||||
Binary file not shown.
@ -1,2 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="JAVA_MODULE" version="4" />
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<!DOCTYPE channels [
|
|
||||||
<!ELEMENT channels (channel)*>
|
|
||||||
<!ELEMENT channel (#PCDATA)>
|
|
||||||
<!ATTLIST channel
|
|
||||||
type CDATA #REQUIRED>
|
|
||||||
]>
|
|
||||||
<channels>
|
|
||||||
<channel type="MEAT"></channel>
|
|
||||||
<channel type="VEGETABLE"></channel>
|
|
||||||
<channel type="FRUIT"></channel>
|
|
||||||
</channels>
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<!DOCTYPE nodes [
|
|
||||||
<!ELEMENT nodes (node)*>
|
|
||||||
<!ELEMENT node (money|channels)*>
|
|
||||||
<!ATTLIST node
|
|
||||||
type CDATA #REQUIRED>
|
|
||||||
<!ELEMENT money (#PCDATA)>
|
|
||||||
<!ELEMENT channels (#PCDATA)>
|
|
||||||
]>
|
|
||||||
<nodes>
|
|
||||||
<node type = "Farmer">
|
|
||||||
<money>100</money>
|
|
||||||
<channels>MEAT PURCHASE;VEGETABLE PURCHASE;FRUIT PURCHASE</channels>
|
|
||||||
</node>
|
|
||||||
<node type = "Processor">
|
|
||||||
<money>10</money>
|
|
||||||
<channels>MEAT SALE_AND_PURCHASE;VEGETABLE SALE_AND_PURCHASE;FRUIT SALE_AND_PURCHASE</channels>
|
|
||||||
</node>
|
|
||||||
<node type = "Seller">
|
|
||||||
<money>1500</money>
|
|
||||||
<channels>MEAT SALE_AND_PURCHASE;VEGETABLE SALE_AND_PURCHASE;FRUIT SALE_AND_PURCHASE</channels>
|
|
||||||
</node>
|
|
||||||
<node type = "Distributor">
|
|
||||||
<money>1000</money>
|
|
||||||
<channels>MEAT SALE_AND_PURCHASE;VEGETABLE SALE_AND_PURCHASE;FRUIT SALE_AND_PURCHASE</channels>
|
|
||||||
</node>
|
|
||||||
<node type = "Customer">
|
|
||||||
<money>250</money>
|
|
||||||
<channels>MEAT SALE;VEGETABLE SALE;FRUIT SALE</channels>
|
|
||||||
</node>
|
|
||||||
</nodes>
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<!DOCTYPE products [
|
|
||||||
<!ELEMENT products (product)*>
|
|
||||||
<!ELEMENT product (name|type|price)*>
|
|
||||||
<!ELEMENT name (#PCDATA)>
|
|
||||||
<!ELEMENT type (#PCDATA)>
|
|
||||||
<!ELEMENT price (#PCDATA)>
|
|
||||||
]>
|
|
||||||
<products>
|
|
||||||
<product>
|
|
||||||
<name>jablko</name>
|
|
||||||
<type>FRUIT</type>
|
|
||||||
<price>5</price>
|
|
||||||
</product>
|
|
||||||
<product>
|
|
||||||
<name>hruška</name>
|
|
||||||
<type>FRUIT</type>
|
|
||||||
<price>7</price>
|
|
||||||
</product>
|
|
||||||
<product>
|
|
||||||
<name>banán</name>
|
|
||||||
<type>FRUIT</type>
|
|
||||||
<price>10</price>
|
|
||||||
</product>
|
|
||||||
<product>
|
|
||||||
<name>okurka</name>
|
|
||||||
<type>VEGETABLE</type>
|
|
||||||
<price>3</price>
|
|
||||||
</product>
|
|
||||||
<product>
|
|
||||||
<name>paprika</name>
|
|
||||||
<type>VEGETABLE</type>
|
|
||||||
<price>5</price>
|
|
||||||
</product>
|
|
||||||
<product>
|
|
||||||
<name>rajče</name>
|
|
||||||
<type>VEGETABLE</type>
|
|
||||||
<price>3</price>
|
|
||||||
</product>
|
|
||||||
<product>
|
|
||||||
<name>vepřové</name>
|
|
||||||
<type>MEAT</type>
|
|
||||||
<price>20</price>
|
|
||||||
</product>
|
|
||||||
<product>
|
|
||||||
<name>hovězí</name>
|
|
||||||
<type>MEAT</type>
|
|
||||||
<price>50</price>
|
|
||||||
</product>
|
|
||||||
<product>
|
|
||||||
<name>kuřecí</name>
|
|
||||||
<type>MEAT</type>
|
|
||||||
<price>30</price>
|
|
||||||
</product>
|
|
||||||
</products>
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<!DOCTYPE scenarios [
|
|
||||||
<!ELEMENT scenarios (scenario)*>
|
|
||||||
<!ELEMENT scenario (steps)*>
|
|
||||||
<!ATTLIST scenario
|
|
||||||
type CDATA #REQUIRED>
|
|
||||||
<!ELEMENT steps (#PCDATA)>
|
|
||||||
]>
|
|
||||||
<!--
|
|
||||||
generate
|
|
||||||
consume
|
|
||||||
doaction <product-operation-type>
|
|
||||||
doaction <product-operation-type> <product-name>
|
|
||||||
sell <product-type> <product-name>
|
|
||||||
buy <product-type> <produt-name> <product-price>
|
|
||||||
pass
|
|
||||||
-->
|
|
||||||
<scenarios>
|
|
||||||
<scenario type="Farmer">
|
|
||||||
<steps>
|
|
||||||
generate
|
|
||||||
sell FRUIT jablko
|
|
||||||
</steps>
|
|
||||||
</scenario>
|
|
||||||
</scenarios>
|
|
||||||
24
pom.xml
24
pom.xml
@ -1,24 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<groupId>cz.cvut.fel.sit.omo.foodchain</groupId>
|
|
||||||
<artifactId>FoodChain</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.javamoney</groupId>
|
|
||||||
<artifactId>moneta</artifactId>
|
|
||||||
<version>1.4.2</version>
|
|
||||||
<type>pom</type>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<maven.compiler.target>12</maven.compiler.target>
|
|
||||||
<maven.compiler.source>12</maven.compiler.source>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
</project>
|
|
||||||
@ -1,133 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.channel.ChannelBase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.factory.FactoryManager;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
|
|
||||||
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.ParserResultElement;
|
|
||||||
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.util.ReportLogger;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.util.Ticker;
|
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.LogManager;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
public class FoodChain
|
|
||||||
{
|
|
||||||
|
|
||||||
private static FactoryManager factoryManager = new FactoryManager();
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
LogManager.getLogManager().reset();
|
|
||||||
Logger rootLogger = LogManager.getLogManager().getLogger("");
|
|
||||||
|
|
||||||
rootLogger.addHandler(new ReportLogger());
|
|
||||||
|
|
||||||
if(args.length < 4)
|
|
||||||
{
|
|
||||||
parseChannels("conf/channels.xml");
|
|
||||||
parseNodes("conf/nodes.xml");
|
|
||||||
parseProducts("conf/products.xml");
|
|
||||||
parseScenarios("conf/scenarios.xml");
|
|
||||||
|
|
||||||
rootLogger.log(Level.CONFIG,"Parsed default scenarios");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
parseChannels(args[1]);
|
|
||||||
parseNodes(args[2]);
|
|
||||||
parseProducts(args[3]);
|
|
||||||
parseScenarios(args[4]);
|
|
||||||
|
|
||||||
rootLogger.log(Level.CONFIG,"Parsed non-default scenarios");
|
|
||||||
}
|
|
||||||
|
|
||||||
// getFactoryManager().getPoolDatabaseInstance().getChannelPoolInstance().findAll().stream().forEach(ch -> System.out.println(ch.getProductType()));
|
|
||||||
// getFactoryManager().getPoolDatabaseInstance().getNodePoolInstance().findAll().stream().forEach(ch -> System.out.println(ch));
|
|
||||||
// getFactoryManager().getPoolDatabaseInstance().getProductPoolInstance().findAll().stream().forEach(ch -> System.out.println(ch.getProductType() + " " + ch.getName()));
|
|
||||||
// getFactoryManager().getPoolDatabaseInstance().getScenarioPoolInstance().findAll().stream().forEach(ch -> ch.getSteps().stream().forEach(s -> System.out.println(s)));
|
|
||||||
|
|
||||||
Ticker.start();
|
|
||||||
while (Ticker.getTimer().isRunning())
|
|
||||||
{
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReportingManager reportingManager = new ReportingManager();
|
|
||||||
|
|
||||||
System.out.println(reportingManager.generateReport());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FactoryManager getFactoryManager()
|
|
||||||
{
|
|
||||||
return factoryManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ParserResult parseDocument(String path, String rootElementTag)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ConfigurationParser.parseDocument(path);
|
|
||||||
}
|
|
||||||
catch (ParserConfigurationException | SAXException | IOException e)
|
|
||||||
{
|
|
||||||
System.err.println(e.getMessage());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return ConfigurationParser.getElements(rootElementTag);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void parseChannels(String path)
|
|
||||||
{
|
|
||||||
ParserResult parserResult = parseDocument(path, "channel");
|
|
||||||
List<ParserResultElement> elements = parserResult.getElements();
|
|
||||||
for (ParserResultElement el : elements)
|
|
||||||
{
|
|
||||||
ChannelBase res = getFactoryManager().getChannelFactoryInstance().makeChannel(el);
|
|
||||||
getFactoryManager().getPoolDatabaseInstance().getChannelPoolInstance().add(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void parseNodes(String path)
|
|
||||||
{
|
|
||||||
ParserResult parserResult = parseDocument(path, "node");
|
|
||||||
List<ParserResultElement> elements = parserResult.getElements();
|
|
||||||
for (ParserResultElement el : elements)
|
|
||||||
{
|
|
||||||
NodeBase res = getFactoryManager().getNodeFactoryInstance().makeNode(el);
|
|
||||||
getFactoryManager().getPoolDatabaseInstance().getNodePoolInstance().add(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void parseProducts(String path)
|
|
||||||
{
|
|
||||||
ParserResult parserResult = parseDocument(path, "product");
|
|
||||||
List<ParserResultElement> elements = parserResult.getElements();
|
|
||||||
for (ParserResultElement el : elements)
|
|
||||||
{
|
|
||||||
Product res = getFactoryManager().getProductFactoryInstance().makeProduct(el);
|
|
||||||
getFactoryManager().getPoolDatabaseInstance().getProductPoolInstance().add(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void parseScenarios(String path)
|
|
||||||
{
|
|
||||||
ParserResult parserResult = parseDocument(path, "scenario");
|
|
||||||
List<ParserResultElement> elements = parserResult.getElements();
|
|
||||||
for (ParserResultElement el : elements)
|
|
||||||
{
|
|
||||||
Scenario res = getFactoryManager().getScenarioFactoryInstance().makeScenario(el);
|
|
||||||
getFactoryManager().getPoolDatabaseInstance().getScenarioPoolInstance().add(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,134 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.channel;
|
|
||||||
|
|
||||||
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.Transaction;
|
|
||||||
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.util.ChannelObserver;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.util.Observable;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for all channels
|
|
||||||
*/
|
|
||||||
public abstract class ChannelBase implements Observable {
|
|
||||||
protected ProductType productType;
|
|
||||||
protected Queue<Requirement> requirements;
|
|
||||||
protected Queue<Transaction> transactions;
|
|
||||||
|
|
||||||
private Set<ChannelObserver> subscribers;
|
|
||||||
|
|
||||||
public ChannelBase(ProductType type)
|
|
||||||
{
|
|
||||||
this.requirements = new LinkedList<>();
|
|
||||||
this.transactions = new LinkedList<>();
|
|
||||||
this.subscribers = new HashSet<>();
|
|
||||||
this.productType = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChannelBase()
|
|
||||||
{
|
|
||||||
this.requirements = new LinkedList<>();
|
|
||||||
this.transactions = new LinkedList<>();
|
|
||||||
this.subscribers = new HashSet<>();
|
|
||||||
this.productType = ProductType.OTHER;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Queue<Transaction> getTransactions(NodeBase node)
|
|
||||||
{
|
|
||||||
return this.transactions.stream().filter(t -> t.getNodeReceiver().equals(node)).collect(Collectors.toCollection(LinkedList::new));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Queue<Requirement> getCurrentRequirements()
|
|
||||||
{
|
|
||||||
return this.requirements;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds new requirement to the requirement Queue.
|
|
||||||
* @param requirement requirement
|
|
||||||
*/
|
|
||||||
public void addRequirement(Requirement requirement)
|
|
||||||
{
|
|
||||||
this.requirements.add(requirement);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Passes tick onto every requirement in channel, if requirement has TTL= 0 deletes it, notifies all nodes with current requirements.
|
|
||||||
* @return if there are any requirements
|
|
||||||
*/
|
|
||||||
public boolean tick() {
|
|
||||||
requirements.forEach(Requirement::tick);
|
|
||||||
try {
|
|
||||||
requirements.stream().filter(r -> r.getTTL() == 0).forEach(re -> re.getCreator().getStorage().getProduct(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies all nodes apart from creator about a requirement.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void notifyAllObservers(){
|
|
||||||
subscribers.forEach(subscriber -> new LinkedList<>(requirements).forEach(r -> subscriber.update(r, this)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds observer to list of subscribed nodes.
|
|
||||||
* @param observer channelobserver
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void attach(ChannelObserver observer){
|
|
||||||
subscribers.add(observer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes observer from list of subscribed nodes.
|
|
||||||
* @param observer channelobserver
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void detach(ChannelObserver observer){ subscribers.remove(observer); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds new transaction to the transaction Queue.
|
|
||||||
* @param transaction transaction
|
|
||||||
*/
|
|
||||||
public void addTransaction(Transaction transaction)
|
|
||||||
{
|
|
||||||
this.transactions.add(transaction);
|
|
||||||
try {
|
|
||||||
((ProductTransaction) transaction).getProduct().setStateToInTransit();
|
|
||||||
}
|
|
||||||
catch (Exception ignored) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes requirement from list of active requirements.
|
|
||||||
* @param requirement requirement
|
|
||||||
*/
|
|
||||||
public void disposeOf(Requirement requirement) { this.requirements.remove(requirement); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes transaction from list of unprocessed transactions.
|
|
||||||
* @param transaction transaction
|
|
||||||
*/
|
|
||||||
public void disposeOf(Transaction transaction) { this.transactions.remove(transaction); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears all active requirements from this channel.
|
|
||||||
*/
|
|
||||||
public void clearRequirements()
|
|
||||||
{
|
|
||||||
this.requirements.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProductType getProductType() {
|
|
||||||
return productType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.channel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enum class for different subscription types
|
|
||||||
*/
|
|
||||||
public enum ChannelSubscriptionType {
|
|
||||||
|
|
||||||
SALE, PURCHASE, SALE_AND_PURCHASE
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.channel;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Channel for transporting fruit
|
|
||||||
*/
|
|
||||||
public class FruitChannel extends ChannelBase
|
|
||||||
{
|
|
||||||
public FruitChannel()
|
|
||||||
{
|
|
||||||
super(ProductType.FRUIT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.channel;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Channel for transporting meat
|
|
||||||
*/
|
|
||||||
public class MeatChannel extends ChannelBase
|
|
||||||
{
|
|
||||||
public MeatChannel()
|
|
||||||
{
|
|
||||||
super(ProductType.MEAT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.channel;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Channel for transporting other products
|
|
||||||
*/
|
|
||||||
public class OtherChannel extends ChannelBase
|
|
||||||
{
|
|
||||||
public OtherChannel()
|
|
||||||
{
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.channel;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Channel for transporting vegetable
|
|
||||||
*/
|
|
||||||
public class VegetableChannel extends ChannelBase
|
|
||||||
{
|
|
||||||
public VegetableChannel()
|
|
||||||
{
|
|
||||||
super(ProductType.VEGETABLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.factory;
|
|
||||||
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.channel.*;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.parser.ParserResultElement;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
|
|
||||||
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory for creating channels
|
|
||||||
*/
|
|
||||||
public class ChannelFactory
|
|
||||||
{
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(ChannelFactory.class.getName());
|
|
||||||
/**
|
|
||||||
* Creates channel based on channel type (Fruit, Vegetable, Meat, Other).
|
|
||||||
* @param input data from channel that is created
|
|
||||||
* @return created Channel (FruitChannel, VegetableChannel, MeatChannel, OtherChannel)
|
|
||||||
*/
|
|
||||||
public ChannelBase makeChannel(ParserResultElement input)
|
|
||||||
{
|
|
||||||
ChannelBase c = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ProductType channelType = ProductType.valueOf(input.getAttribute("type"));
|
|
||||||
c = makeChannelFromChannelType(channelType);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e)
|
|
||||||
{
|
|
||||||
LOGGER.log(Level.SEVERE, "! Wrong type of enum in ChannelFactory: " + e);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOGGER.log(Level.SEVERE, "! Fatal error in ChannelFactory: " + e);
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates channel based on channel type (Fruit, Vegetable, Meat, Other).
|
|
||||||
* @param typeOfChannel channel type to be created
|
|
||||||
* @return created Channel (FruitChannel, VegetableChannel, MeatChannel, OtherChannel)
|
|
||||||
*/
|
|
||||||
private ChannelBase makeChannelFromChannelType(ProductType typeOfChannel)
|
|
||||||
{
|
|
||||||
switch (typeOfChannel)
|
|
||||||
{
|
|
||||||
case FRUIT:
|
|
||||||
return new FruitChannel();
|
|
||||||
case VEGETABLE:
|
|
||||||
return new VegetableChannel();
|
|
||||||
case MEAT:
|
|
||||||
return new MeatChannel();
|
|
||||||
case OTHER:
|
|
||||||
return new OtherChannel();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.factory;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.pool.PoolDatabase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.util.Singleton;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manager class for all factories and pool database
|
|
||||||
*/
|
|
||||||
public class FactoryManager
|
|
||||||
{
|
|
||||||
public NodeFactory getNodeFactoryInstance()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return Singleton.getInstance(NodeFactory.class);
|
|
||||||
}
|
|
||||||
catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChannelFactory getChannelFactoryInstance()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return Singleton.getInstance(ChannelFactory.class);
|
|
||||||
}
|
|
||||||
catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScenarioFactory getScenarioFactoryInstance()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return Singleton.getInstance(ScenarioFactory.class);
|
|
||||||
}
|
|
||||||
catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProductFactory getProductFactoryInstance()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return Singleton.getInstance(ProductFactory.class);
|
|
||||||
}
|
|
||||||
catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PoolDatabase getPoolDatabaseInstance()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return Singleton.getInstance(PoolDatabase.class);
|
|
||||||
}
|
|
||||||
catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.factory;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.FoodChain;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.channel.ChannelSubscriptionType;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.*;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.enums.NodeType;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.parser.ParserResultElement;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.pool.ChannelPool;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory for creating nodes
|
|
||||||
*/
|
|
||||||
public class NodeFactory
|
|
||||||
{
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(NodeFactory.class.getName());
|
|
||||||
/**
|
|
||||||
* Creates Node based on input ParserResultElement.
|
|
||||||
* @param input data from Node that is created
|
|
||||||
* @return created Node
|
|
||||||
*/
|
|
||||||
public NodeBase makeNode(ParserResultElement input)
|
|
||||||
{
|
|
||||||
NodeBase n = null;
|
|
||||||
NodeType nodeType = null;
|
|
||||||
String subsChannels = "";
|
|
||||||
double startMoney = 0;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
nodeType = NodeType.valueOf(input.getAttribute("type"));
|
|
||||||
|
|
||||||
subsChannels = input.getChild("channels");
|
|
||||||
startMoney = Double.parseDouble(input.getChild("money"));
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e)
|
|
||||||
{
|
|
||||||
LOGGER.log(Level.SEVERE, "! Wrong type of enum in NodeFactory: " + e.getMessage());
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOGGER.log(Level.SEVERE, "! Fatal error in NodeFactory: " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (Objects.requireNonNull(nodeType))
|
|
||||||
{
|
|
||||||
case Farmer:
|
|
||||||
n = new Farmer(startMoney);
|
|
||||||
break;
|
|
||||||
case Processor:
|
|
||||||
n = new Processor(startMoney);
|
|
||||||
break;
|
|
||||||
case Distributor:
|
|
||||||
n = new Distributor(startMoney);
|
|
||||||
break;
|
|
||||||
case Seller:
|
|
||||||
n = new Seller(startMoney);
|
|
||||||
break;
|
|
||||||
case Customer:
|
|
||||||
n = new Customer(startMoney);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n != null)
|
|
||||||
{
|
|
||||||
String[] subs = subsChannels.split(";");
|
|
||||||
for (String s : subs)
|
|
||||||
{
|
|
||||||
String[] el = s.split(" ");
|
|
||||||
|
|
||||||
ChannelPool temp = FoodChain.getFactoryManager().getPoolDatabaseInstance().getChannelPoolInstance();
|
|
||||||
n.subscribeToChannel(temp.findByType(ProductType.valueOf(el[0])), ChannelSubscriptionType.valueOf(el[1]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.factory;
|
|
||||||
|
|
||||||
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.ProductState;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
|
|
||||||
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory for creating products
|
|
||||||
*/
|
|
||||||
public class ProductFactory
|
|
||||||
{
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(ProductFactory.class.getName());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates Product based on input ParserResultElement.
|
|
||||||
* @param input data from Product that is created
|
|
||||||
* @return created Product
|
|
||||||
*/
|
|
||||||
public Product makeProduct(ParserResultElement input)
|
|
||||||
{
|
|
||||||
Product p = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
String name = input.getChild("name");
|
|
||||||
ProductType productType = ProductType.valueOf(input.getChild("type"));
|
|
||||||
//ProductState productState = ProductState.valueOf(input.getChild("state"));
|
|
||||||
double price = Double.parseDouble(input.getChild("price"));
|
|
||||||
|
|
||||||
//p = new Product(name, price, productType, productState);
|
|
||||||
p = new Product(name, productType, price);
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e)
|
|
||||||
{
|
|
||||||
LOGGER.log(Level.SEVERE, "! Wrong type of enum in ProductFactory: " + e.getMessage());
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOGGER.log(Level.SEVERE, "! Fatal error in ProductFactory: " + e.getMessage());
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,89 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.factory;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.FoodChain;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.Customer;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.Farmer;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.operation.ProductOperationType;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.operation.TransactionType;
|
|
||||||
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.ProductType;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.scenario.*;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory for creating scenarios
|
|
||||||
*/
|
|
||||||
public class ScenarioFactory
|
|
||||||
{
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(ScenarioFactory.class.getName());
|
|
||||||
/**
|
|
||||||
* Creates Scenario based on input ParserResultElement.
|
|
||||||
* @param input data from Scenario that is created
|
|
||||||
* @return created Scenario
|
|
||||||
*/
|
|
||||||
public Scenario makeScenario(ParserResultElement input)
|
|
||||||
{
|
|
||||||
Scenario s = null;
|
|
||||||
NodeBase node = null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
String nodeType = input.getAttribute("type");
|
|
||||||
node = FoodChain.getFactoryManager().getPoolDatabaseInstance().getNodePoolInstance().findAll().stream()
|
|
||||||
.filter(ch -> ch.getClass().getSimpleName().equals(nodeType)).findFirst().orElse(null);
|
|
||||||
|
|
||||||
String[] steps = Arrays.stream(input.getChild("steps").split("\n")).filter(st -> !st.strip().equals("")).toArray(String[]::new);
|
|
||||||
List<ScenarioStep> scenarioSteps = new LinkedList<>();
|
|
||||||
ScenarioStep scenarioStep = null;
|
|
||||||
for (String step : steps)
|
|
||||||
{
|
|
||||||
String[] parts = step.strip().split(" ");
|
|
||||||
switch (parts[0])
|
|
||||||
{
|
|
||||||
case "generate":
|
|
||||||
scenarioStep = new GenerateProductStep((Farmer) node);
|
|
||||||
break;
|
|
||||||
case "consume":
|
|
||||||
scenarioStep = new ConsumeProductStep((Customer) node);
|
|
||||||
break;
|
|
||||||
case "doaction":
|
|
||||||
if (parts.length == 2)
|
|
||||||
{
|
|
||||||
scenarioStep = new DoActionStep(node, ProductOperationType.valueOf(parts[1]));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Product p = FoodChain.getFactoryManager().getPoolDatabaseInstance().getProductPoolInstance().findAll().stream()
|
|
||||||
.filter(pr -> pr.getName().equals(parts[2])).findFirst().orElse(null);
|
|
||||||
scenarioStep = new DoActionStep(node, ProductOperationType.valueOf(parts[1]), p);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "sell":
|
|
||||||
scenarioStep = new SendRequirementStep(node, TransactionType.SALE, ProductType.valueOf(parts[1]), parts[2]);
|
|
||||||
break;
|
|
||||||
case "buy":
|
|
||||||
scenarioStep = new SendRequirementStep(node, TransactionType.PURCHASE, ProductType.valueOf(parts[1]), parts[2], Double.parseDouble(parts[3]));
|
|
||||||
break;
|
|
||||||
case "pass":
|
|
||||||
scenarioStep = new PassStep();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
scenarioSteps.add(scenarioStep);
|
|
||||||
}
|
|
||||||
s = new Scenario(scenarioSteps);
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e)
|
|
||||||
{
|
|
||||||
LOGGER.log(Level.SEVERE, "! Wrong type of enum in ScenarioFactory: " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.node;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.base.BuyerNodeBase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.enums.NodeType;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Customer node
|
|
||||||
*/
|
|
||||||
public class Customer extends BuyerNodeBase {
|
|
||||||
|
|
||||||
public Customer(double startMoney) {
|
|
||||||
super(startMoney);
|
|
||||||
allowedSeller = NodeType.Distributor;
|
|
||||||
allowedPurchaser = NodeType.None;
|
|
||||||
nodeType = NodeType.Customer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void consumeProduct() {
|
|
||||||
int i = new Random().nextInt(getStorage().getNumberOfStoredProducts());
|
|
||||||
getStorage().getProducts().remove(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.node;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.base.RetailerNodeBase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.enums.NodeType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Distributor node
|
|
||||||
*/
|
|
||||||
public class Distributor extends RetailerNodeBase {
|
|
||||||
|
|
||||||
public Distributor(double startMoney) {
|
|
||||||
super(startMoney);
|
|
||||||
allowedSeller = NodeType.Seller;
|
|
||||||
allowedPurchaser = NodeType.Customer;
|
|
||||||
this.nodeType = NodeType.Distributor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.node;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.base.SellerNodeBase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.enums.NodeType;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.operation.TransactionType;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.Product;
|
|
||||||
|
|
||||||
import javax.naming.InsufficientResourcesException;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Farmer node
|
|
||||||
*/
|
|
||||||
public class Farmer extends SellerNodeBase {
|
|
||||||
|
|
||||||
public Farmer(double startMoney) {
|
|
||||||
super(startMoney);
|
|
||||||
allowedSeller = NodeType.None;
|
|
||||||
allowedPurchaser = NodeType.Processor;
|
|
||||||
nodeType = NodeType.Farmer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void generateProduct(Product product) {
|
|
||||||
this.storage.storeProduct(product);
|
|
||||||
try {
|
|
||||||
createRequirement(TransactionType.SALE, product.getProductType(), product.getName(), product.getPrice());
|
|
||||||
} catch (InsufficientResourcesException e) {
|
|
||||||
LOGGER.log(Level.WARNING, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.node;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.base.RetailerNodeBase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.enums.NodeType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Processor node
|
|
||||||
*/
|
|
||||||
public class Processor extends RetailerNodeBase {
|
|
||||||
|
|
||||||
public Processor(double startMoney) {
|
|
||||||
super(startMoney);
|
|
||||||
allowedSeller = NodeType.Farmer;
|
|
||||||
allowedPurchaser = NodeType.Seller;
|
|
||||||
this.nodeType = NodeType.Processor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.node;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.base.RetailerNodeBase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.enums.NodeType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Seller node
|
|
||||||
*/
|
|
||||||
public class Seller extends RetailerNodeBase {
|
|
||||||
|
|
||||||
public Seller(double startMoney) {
|
|
||||||
super(startMoney);
|
|
||||||
allowedSeller = NodeType.Processor;
|
|
||||||
allowedPurchaser = NodeType.Distributor;
|
|
||||||
this.nodeType = NodeType.Seller;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,125 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.node;
|
|
||||||
|
|
||||||
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.ProductOperationType;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.Product;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Storage sub-node for storing products of other nodes
|
|
||||||
*/
|
|
||||||
public class Storage
|
|
||||||
{
|
|
||||||
private final NodeBase storageOwner;
|
|
||||||
private final List<Product> products = new LinkedList<>();
|
|
||||||
|
|
||||||
public Storage(NodeBase owner)
|
|
||||||
{
|
|
||||||
this.storageOwner = owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds provided product into the storage.
|
|
||||||
* @param product
|
|
||||||
*/
|
|
||||||
public void storeProduct(Product product)
|
|
||||||
{
|
|
||||||
this.products.add(product);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds all of the provided products into the storage.
|
|
||||||
* @param products
|
|
||||||
*/
|
|
||||||
public void storeProducts(List<Product> products)
|
|
||||||
{
|
|
||||||
this.products.addAll(products);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds a product (first if there is multiple of them) based on its name and type.
|
|
||||||
* @param name name of product to find
|
|
||||||
* @param type type of product to find
|
|
||||||
* @return product if found, null if product is not in storage
|
|
||||||
*/
|
|
||||||
public Product getProduct(String name, ProductType type)
|
|
||||||
{
|
|
||||||
return products.stream().filter(ch -> ch.getProductType() == type && ch.getName().equals(name)).findFirst().orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Product> getProducts()
|
|
||||||
{
|
|
||||||
return products;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns number of products in storage.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public int getNumberOfStoredProducts()
|
|
||||||
{
|
|
||||||
return this.products.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether storage contains provided product.
|
|
||||||
* @param product product to check
|
|
||||||
* @return true if contains, false if not
|
|
||||||
*/
|
|
||||||
public boolean containsProduct(Product product)
|
|
||||||
{
|
|
||||||
return products.contains(product);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether storage contains provided product.
|
|
||||||
* @param name name of product to check
|
|
||||||
* @param type type of product to check
|
|
||||||
* @return true if contains, false if not
|
|
||||||
*/
|
|
||||||
public boolean containsProduct(String name, ProductType type)
|
|
||||||
{
|
|
||||||
return this.getProduct(name,type) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes provided product from storage if storage contains this product. (Removes only first found).
|
|
||||||
* @param product product to remove
|
|
||||||
*/
|
|
||||||
public void removeProduct(Product product)
|
|
||||||
{
|
|
||||||
if (containsProduct(product))
|
|
||||||
this.products.remove(product);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proceed specific type of action on provided product if its possible.
|
|
||||||
* @param action type of product operation to do
|
|
||||||
* @param product product to proceed
|
|
||||||
*/
|
|
||||||
public void doAction(ProductOperationType action, Product product) throws IllegalCallerException
|
|
||||||
{
|
|
||||||
if (action.getNode().equals(this.storageOwner.getNodeType()))
|
|
||||||
if (action.getProduct().equals(product.getProductType()) || action.getProduct().equals(ProductType.ALL))
|
|
||||||
new Action(this.storageOwner, product, action);
|
|
||||||
else
|
|
||||||
throw new IllegalCallerException("! IllegalCallerException in NodeBase. " + product.getProductType().toString() + " cannot be processed by action " + action.name() + " only for " + action.getProduct());
|
|
||||||
else
|
|
||||||
throw new IllegalCallerException("! IllegalCallerException in NodeBase. " + this.storageOwner.getNodeType().toString() + " cannot do action available only for " + action.getNode());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls specific ProductOperation on each product in stock.
|
|
||||||
* @param action ProductOperationType
|
|
||||||
*/
|
|
||||||
public void doAction(ProductOperationType action)
|
|
||||||
{
|
|
||||||
this.products.forEach(t -> new Action(this.storageOwner, t, action));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.node.base;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.interfaces.IBuyerNode;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.Product;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for all buyer nodes
|
|
||||||
*/
|
|
||||||
public class BuyerNodeBase extends NodeBase implements IBuyerNode {
|
|
||||||
public BuyerNodeBase(double m){
|
|
||||||
super(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void buyProduct(Product product) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,392 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.node.base;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.channel.ChannelBase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.channel.ChannelSubscriptionType;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.Storage;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.enums.NodeType;
|
|
||||||
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.ProductState;
|
|
||||||
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.signature.SignatureManager;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.util.ChannelObserver;
|
|
||||||
import org.javamoney.moneta.Money;
|
|
||||||
|
|
||||||
import javax.money.MonetaryAmount;
|
|
||||||
import javax.naming.InsufficientResourcesException;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for all nodes
|
|
||||||
*/
|
|
||||||
public class NodeBase implements ChannelObserver {
|
|
||||||
protected static final Logger LOGGER = Logger.getLogger(NodeBase.class.getName());
|
|
||||||
|
|
||||||
private final Map<ChannelBase, ChannelSubscriptionType> subscribedChannels = new HashMap<>();
|
|
||||||
private final List<Transaction> refusedTransactions = new LinkedList<>();
|
|
||||||
private final List<RefusedRequirement> refusedRequirements = new LinkedList<>();
|
|
||||||
|
|
||||||
private MonetaryAmount money;
|
|
||||||
|
|
||||||
protected final Storage storage;
|
|
||||||
protected NodeType nodeType;
|
|
||||||
protected NodeType allowedSeller;
|
|
||||||
protected NodeType allowedPurchaser;
|
|
||||||
|
|
||||||
public NodeBase() {
|
|
||||||
this.nodeType = NodeType.None;
|
|
||||||
this.storage = new Storage(this);
|
|
||||||
this.money = Money.of(0, "USD");
|
|
||||||
}
|
|
||||||
|
|
||||||
public NodeBase(double m) {
|
|
||||||
this.nodeType = NodeType.None;
|
|
||||||
this.storage = new Storage(this);
|
|
||||||
this.money = Money.of(m, "USD");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends product transaction to node through a channel based on its type.
|
|
||||||
*
|
|
||||||
* @param product product to be sent
|
|
||||||
* @param node receiver node
|
|
||||||
*/
|
|
||||||
public void sendTransaction(Product product, NodeBase node) {
|
|
||||||
try {
|
|
||||||
Transaction transaction = new ProductTransaction(this, node, TransactionType.SALE, product);
|
|
||||||
subscribedChannels.keySet().stream()
|
|
||||||
.filter(ch -> ch.getProductType().equals(product.getProductType()))
|
|
||||||
.findAny().ifPresent(channel -> channel.addTransaction(transaction));
|
|
||||||
} catch (InsufficientResourcesException e) {
|
|
||||||
LOGGER.log(Level.WARNING, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends financial transaction to node through a channel based on previous transaction type.
|
|
||||||
*
|
|
||||||
* @param amount amount to be sent
|
|
||||||
* @param node receiver node
|
|
||||||
* @param prevTransaction previous product transaction
|
|
||||||
*/
|
|
||||||
public void sendTransaction(MonetaryAmount amount, NodeBase node, ProductTransaction prevTransaction) {
|
|
||||||
try {
|
|
||||||
Transaction transaction = new FinancialTransaction(this, node, TransactionType.PURCHASE, amount, prevTransaction);
|
|
||||||
subscribedChannels.keySet().stream()
|
|
||||||
.filter(ch -> ch.getProductType().equals(prevTransaction.getProduct().getProductType()))
|
|
||||||
.findAny().ifPresent(channel -> channel.addTransaction(transaction));
|
|
||||||
} catch (InsufficientResourcesException e) {
|
|
||||||
LOGGER.log(Level.WARNING, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receives (processes) transaction.
|
|
||||||
*
|
|
||||||
* @param transaction transaction to be received
|
|
||||||
*/
|
|
||||||
public void receiveTransaction(Transaction transaction) {
|
|
||||||
try {
|
|
||||||
receiveTransaction((ProductTransaction) transaction);
|
|
||||||
} catch (Exception e) {
|
|
||||||
try {
|
|
||||||
receiveTransaction((FinancialTransaction) transaction);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
LOGGER.log(Level.WARNING, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receives (validates) product transaction and sends financial transaction as response.
|
|
||||||
*
|
|
||||||
* @param transaction transaction to be received
|
|
||||||
*/
|
|
||||||
public void receiveTransaction(ProductTransaction transaction) {
|
|
||||||
if (validateSignature(transaction)) {
|
|
||||||
transaction.getProduct().setStateToReadyForReception();
|
|
||||||
transaction.endTransaction();
|
|
||||||
sendTransaction(transaction.getProduct().getPrice(), transaction.getNodeCreator(), transaction);
|
|
||||||
|
|
||||||
} else refuseTransaction(transaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receives (validates) financial transaction.
|
|
||||||
*
|
|
||||||
* @param transaction transaction to be received
|
|
||||||
*/
|
|
||||||
public void receiveTransaction(FinancialTransaction transaction) {
|
|
||||||
if (validateSignature(transaction)) transaction.endTransaction();
|
|
||||||
else refuseTransaction(transaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds transaction to refused transactions.
|
|
||||||
*
|
|
||||||
* @param transaction
|
|
||||||
*/
|
|
||||||
public void refuseTransaction(Transaction transaction) {
|
|
||||||
transaction.endTransaction();
|
|
||||||
refusedTransactions.add(transaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receives all transactions for this node.
|
|
||||||
*/
|
|
||||||
public void receiveTransactions() {
|
|
||||||
subscribedChannels.keySet().forEach(ch -> ch.getTransactions(this).forEach(t -> {
|
|
||||||
receiveTransaction(t);
|
|
||||||
ch.disposeOf(t);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates requirement based on data provided.
|
|
||||||
*
|
|
||||||
* @param tType transaction type
|
|
||||||
* @param pType product type
|
|
||||||
* @param pName product name
|
|
||||||
* @param price product price
|
|
||||||
* @throws InsufficientResourcesException if product is unavailable
|
|
||||||
*/
|
|
||||||
public void createRequirement(TransactionType tType, ProductType pType, String pName, MonetaryAmount price) throws InsufficientResourcesException {
|
|
||||||
if (price == null) {
|
|
||||||
try {
|
|
||||||
price = storage.getProduct(pName, pType).getPrice();
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
refusedRequirements.add(new RefusedRequirement(tType, pType, pName, price));
|
|
||||||
throw new InsufficientResourcesException("product unavailable");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tType == TransactionType.SALE) {
|
|
||||||
try {
|
|
||||||
storage.getProduct(pName, pType).setStateToInRequirement();
|
|
||||||
} catch (NullPointerException | IllegalStateException e) {
|
|
||||||
refusedRequirements.add(new RefusedRequirement(tType, pType, pName, price));
|
|
||||||
throw new InsufficientResourcesException("product unavailable");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Requirement req = new Requirement(this, tType, pType, pName, price);
|
|
||||||
subscribedChannels.keySet().stream()
|
|
||||||
.filter(ch -> ch.getProductType().equals(pType))
|
|
||||||
.findAny().ifPresent(channel -> channel.addRequirement(req));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accepts requirement and creates response.
|
|
||||||
*
|
|
||||||
* @param req requirement to be accepted
|
|
||||||
* @throws InsufficientResourcesException if product is unavailable
|
|
||||||
*/
|
|
||||||
public void acceptRequirement(Requirement req) throws InsufficientResourcesException {
|
|
||||||
LOGGER.log(Level.INFO, this.nodeType.toString() + " accepted " + req.toString());
|
|
||||||
if (req.getTransactionType() == TransactionType.SALE) {
|
|
||||||
createRequirement(TransactionType.PURCHASE, req.getProductType(), req.getProductName(), req.getPrice());
|
|
||||||
} else {
|
|
||||||
if (req.getPrice().isGreaterThanOrEqualTo(storage.getProduct(req.getProductName(), req.getProductType()).getPrice().multiply(0.9))) {
|
|
||||||
storage.getProduct(req.getProductName(), req.getProductType()).setPrice(req.getPrice());
|
|
||||||
sendTransaction(storage.getProduct(req.getProductName(), req.getProductType()), req.getCreator());
|
|
||||||
} else createRequirement(TransactionType.SALE, req.getProductType(), req.getProductName(), req.getPrice());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds channel to subscribed channels with correct type.
|
|
||||||
*
|
|
||||||
* @param channel channel to be subscribed
|
|
||||||
* @param type type of subscription
|
|
||||||
*/
|
|
||||||
public void subscribeToChannel(ChannelBase channel, ChannelSubscriptionType type) {
|
|
||||||
subscribedChannels.put(channel, type);
|
|
||||||
channel.attach(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes channel from subscribed channels.
|
|
||||||
*
|
|
||||||
* @param channel
|
|
||||||
*/
|
|
||||||
public void unsubscribeFromChannel(ChannelBase channel) {
|
|
||||||
subscribedChannels.remove(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proceed specific type of action on provided product if its possible. (Propagated to its storage).
|
|
||||||
*
|
|
||||||
* @param action type of product operation to do
|
|
||||||
* @param product product to proceed
|
|
||||||
*/
|
|
||||||
public void doAction(ProductOperationType action, Product product) throws IllegalCallerException {
|
|
||||||
this.storage.doAction(action, product);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls specific ProductOperation on each product in stock (Propagated to its storage).
|
|
||||||
*
|
|
||||||
* @param action ProductOperationType
|
|
||||||
*/
|
|
||||||
public void doAction(ProductOperationType action) {
|
|
||||||
this.storage.doAction(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Storage getStorage() {
|
|
||||||
return storage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NodeType getNodeType() {
|
|
||||||
return nodeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MonetaryAmount getMoney() {
|
|
||||||
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
|
|
||||||
*
|
|
||||||
* @param m amount to be added
|
|
||||||
*/
|
|
||||||
|
|
||||||
public void addMoney(MonetaryAmount m) {
|
|
||||||
this.money = this.money.add(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subtracts amount from current assets.
|
|
||||||
*
|
|
||||||
* @param m amount to be subtracted
|
|
||||||
*/
|
|
||||||
public void subtractMoney(MonetaryAmount m) {
|
|
||||||
this.money = this.money.subtract(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates signature on transaction.
|
|
||||||
*
|
|
||||||
* @param transaction transaction to be validated
|
|
||||||
* @return signature is valid
|
|
||||||
*/
|
|
||||||
public boolean validateSignature(Transaction transaction) {
|
|
||||||
return SignatureManager.validateSignature(transaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if requirement creator is an allowed purchaser or allowed seller.
|
|
||||||
*
|
|
||||||
* @param req requirement
|
|
||||||
* @return creator is valid
|
|
||||||
*/
|
|
||||||
boolean senderPurchaserCheck(Requirement req) {
|
|
||||||
NodeType creatorType = req.getCreator().nodeType;
|
|
||||||
|
|
||||||
return !req.getCreator().equals(this) &&
|
|
||||||
(((allowedSeller == creatorType || allowedSeller == NodeType.All) && (req.getTransactionType() == TransactionType.SALE)) ||
|
|
||||||
((allowedPurchaser == creatorType || allowedPurchaser == NodeType.All) && req.getTransactionType() == TransactionType.PURCHASE));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if requirement type corresponds with channel subscription type.
|
|
||||||
*
|
|
||||||
* @param requirement requirement
|
|
||||||
* @param channel channel
|
|
||||||
* @return requirement type corresponds with channel subscription type
|
|
||||||
*/
|
|
||||||
boolean transactionSubscriptionCheck(Requirement requirement, ChannelBase channel) {
|
|
||||||
switch (subscribedChannels.get(channel)) {
|
|
||||||
case SALE:
|
|
||||||
return requirement.getTransactionType() == TransactionType.SALE;
|
|
||||||
case PURCHASE:
|
|
||||||
return requirement.getTransactionType() == TransactionType.PURCHASE;
|
|
||||||
case SALE_AND_PURCHASE:
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Chacks if product is available or if node has enough money
|
|
||||||
*
|
|
||||||
* @param req requirement
|
|
||||||
* @return product is available or node has enough money
|
|
||||||
*/
|
|
||||||
boolean requirementCheck(Requirement req) {
|
|
||||||
Product product = storage.getProduct(req.getProductName(), req.getProductType());
|
|
||||||
return (req.getTransactionType() == TransactionType.SALE && money.isGreaterThanOrEqualTo(req.getPrice())) ||
|
|
||||||
(req.getTransactionType() == TransactionType.PURCHASE && product != null &&
|
|
||||||
((product.getProductState() == ProductState.AVAILABLE) || product.getProductState() == ProductState.IN_REQUIREMENT));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Chacks incomming requirement.
|
|
||||||
*
|
|
||||||
* @param requirement requirement
|
|
||||||
* @param channel channel
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void update(Requirement requirement, ChannelBase channel) {
|
|
||||||
if (senderPurchaserCheck(requirement) && transactionSubscriptionCheck(requirement, channel) && requirementCheck(requirement)) {
|
|
||||||
try {
|
|
||||||
acceptRequirement(requirement);
|
|
||||||
channel.disposeOf(requirement);
|
|
||||||
} catch (InsufficientResourcesException e) {
|
|
||||||
LOGGER.log(Level.WARNING, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receives transactions.
|
|
||||||
*/
|
|
||||||
public void tick() {
|
|
||||||
receiveTransactions();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String accept(ReportTextVisitor visitor) {
|
|
||||||
return visitor.visit(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.node.base;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.interfaces.IBuyerNode;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.interfaces.ISellerNode;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.Product;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for all retailer nodes
|
|
||||||
*/
|
|
||||||
public class RetailerNodeBase extends NodeBase implements IBuyerNode, ISellerNode {
|
|
||||||
public RetailerNodeBase(double startMoney) {
|
|
||||||
super(startMoney);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sellProduct(Product product) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addMargin(Product product) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void buyProduct(Product product) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.node.base;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.interfaces.ISellerNode;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.Product;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for all seller nodes
|
|
||||||
*/
|
|
||||||
public class SellerNodeBase extends NodeBase implements ISellerNode {
|
|
||||||
public SellerNodeBase(double startMoney) {
|
|
||||||
super(startMoney);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sellProduct(Product product) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addMargin(Product product) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.node.enums;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enum class for all nodes
|
|
||||||
*/
|
|
||||||
public enum NodeType {
|
|
||||||
Farmer, Processor, Distributor, Seller, Customer, None, All
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.node.interfaces;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.Product;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for buyer nodes
|
|
||||||
*/
|
|
||||||
public interface IBuyerNode {
|
|
||||||
|
|
||||||
void buyProduct(Product product);
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.node.interfaces;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.Product;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for seller nodes
|
|
||||||
*/
|
|
||||||
public interface ISellerNode {
|
|
||||||
|
|
||||||
void sellProduct(Product product);
|
|
||||||
|
|
||||||
void addMargin(Product product);
|
|
||||||
}
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
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.product.Product;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.reporting.ReportTextVisitor;
|
|
||||||
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Operation for processing products in storage
|
|
||||||
*/
|
|
||||||
public class Action extends OperationBase {
|
|
||||||
private final Product product;
|
|
||||||
private final ProductOperationType type;
|
|
||||||
private int duration;
|
|
||||||
|
|
||||||
public Action(NodeBase node, Product product, ProductOperationType type) {
|
|
||||||
super(node, product.getCurrentOperation());
|
|
||||||
this.product = product;
|
|
||||||
this.type = type;
|
|
||||||
duration = type.getDuration();
|
|
||||||
product.setCurrentOperation(this);
|
|
||||||
product.setStateToInAction();
|
|
||||||
|
|
||||||
LOGGER.log(Level.INFO, toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ends this action and changes products type to available.
|
|
||||||
*/
|
|
||||||
private void endAction() {
|
|
||||||
this.setTimeEnd();
|
|
||||||
product.setStateToAvailable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Changes actions duration or ends action.
|
|
||||||
* @return action is in progress
|
|
||||||
*/
|
|
||||||
public boolean tick() {
|
|
||||||
if (duration == 0) {
|
|
||||||
endAction();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else duration--;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Product getProduct() {
|
|
||||||
return product;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProductOperationType getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Action{" +
|
|
||||||
", product=" + product +
|
|
||||||
", type=" + type +
|
|
||||||
", duration=" + duration +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
public String accept(ReportTextVisitor visitor) {
|
|
||||||
return visitor.visit(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
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.reporting.ReportTextVisitor;
|
|
||||||
|
|
||||||
import javax.money.MonetaryAmount;
|
|
||||||
import javax.naming.InsufficientResourcesException;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Operation for transporting money
|
|
||||||
*/
|
|
||||||
public class FinancialTransaction extends Transaction {
|
|
||||||
|
|
||||||
private final MonetaryAmount amount;
|
|
||||||
private final ProductTransaction transactionPaid;
|
|
||||||
|
|
||||||
public FinancialTransaction(NodeBase creator, NodeBase receiver, TransactionType type, MonetaryAmount amount, ProductTransaction transactionPaid) throws InsufficientResourcesException {
|
|
||||||
super(creator, receiver, type, transactionPaid);
|
|
||||||
this.amount = amount;
|
|
||||||
this.transactionPaid = transactionPaid;
|
|
||||||
if (creator.getMoney().isLessThan(amount)) throw new InsufficientResourcesException("not enough money");
|
|
||||||
creator.subtractMoney(amount);
|
|
||||||
|
|
||||||
LOGGER.log(Level.INFO, toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ends transaction and adds amount to receiver node.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void endTransaction() {
|
|
||||||
super.endTransaction();
|
|
||||||
getNodeReceiver().addMoney(amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MonetaryAmount getAmount() {
|
|
||||||
return amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProductTransaction getTransactionPaid() {
|
|
||||||
return transactionPaid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "FinancialTransaction{" +
|
|
||||||
"amount=" + amount.getNumber() +
|
|
||||||
", transactionPaid=" + transactionPaid +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String accept(ReportTextVisitor visitor) {
|
|
||||||
return visitor.visit(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
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.reporting.PartiesReportVisitor;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.reporting.ReportTextVisitor;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for all operations
|
|
||||||
*/
|
|
||||||
public abstract class OperationBase {
|
|
||||||
|
|
||||||
protected static final Logger LOGGER = Logger.getLogger(OperationBase.class.getName());
|
|
||||||
|
|
||||||
private final LocalDateTime timeStart;
|
|
||||||
private LocalDateTime timeEnd;
|
|
||||||
|
|
||||||
private final NodeBase nodeCreator;
|
|
||||||
private final OperationBase lastOperation;
|
|
||||||
|
|
||||||
OperationBase(NodeBase node, OperationBase lastOperation) {
|
|
||||||
nodeCreator = node;
|
|
||||||
this.lastOperation = lastOperation;
|
|
||||||
timeStart = LocalDateTime.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getTimeStart() {
|
|
||||||
return timeStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getTimeEnd() {
|
|
||||||
return timeEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTimeEnd() {
|
|
||||||
this.timeEnd = LocalDateTime.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
public NodeBase getNodeCreator() {
|
|
||||||
return nodeCreator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OperationBase getLastOperation() {
|
|
||||||
return lastOperation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String accept(ReportTextVisitor reportVisitor){
|
|
||||||
return reportVisitor.visit(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.operation;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.enums.NodeType;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enum class for product operations types with parameters
|
|
||||||
*/
|
|
||||||
public enum ProductOperationType
|
|
||||||
{
|
|
||||||
STORE_MEAT(NodeType.All, ProductType.MEAT, 20, -8),
|
|
||||||
STORE_FRUIT(NodeType.All, ProductType.FRUIT, 8, 2),
|
|
||||||
STORE_VEGETABLE(NodeType.All, ProductType.VEGETABLE, 10, 2),
|
|
||||||
STORE_OTHER(NodeType.All, ProductType.OTHER, 30, 21),
|
|
||||||
|
|
||||||
WRAP_INTO_GIFT_PACKAGE(NodeType.Seller, ProductType.ALL, 1, -8),
|
|
||||||
UNWRAP(NodeType.All, ProductType.ALL, 1, 21),
|
|
||||||
CUT_TO_PIECES(NodeType.All, ProductType.ALL, 1, 21),
|
|
||||||
|
|
||||||
BOIL_MEAT(NodeType.All, ProductType.MEAT, 1, 21),
|
|
||||||
GRILL_MEAT(NodeType.All, ProductType.MEAT, 1, 21),
|
|
||||||
SMOKE_MEAT(NodeType.All, ProductType.MEAT, 1, 21),
|
|
||||||
DRY_MEAT(NodeType.All, ProductType.MEAT, 1, 21),
|
|
||||||
|
|
||||||
DRY_FRUIT(NodeType.All, ProductType.FRUIT, 1, 21),
|
|
||||||
FREEZE_DRY_FRUIT(NodeType.All, ProductType.FRUIT, 1, 21);
|
|
||||||
|
|
||||||
private final NodeType node;
|
|
||||||
private final ProductType product;
|
|
||||||
private final int duration;
|
|
||||||
private final int temperature;
|
|
||||||
|
|
||||||
ProductOperationType(NodeType node, ProductType product, int duration, int temperature)
|
|
||||||
{
|
|
||||||
this.node = node;
|
|
||||||
this.product = product;
|
|
||||||
this.duration = duration;
|
|
||||||
this.temperature = temperature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDuration()
|
|
||||||
{
|
|
||||||
return duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTemperature()
|
|
||||||
{
|
|
||||||
return temperature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NodeType getNode()
|
|
||||||
{
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProductType getProduct() { return product; }
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
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.product.Product;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.ProductState;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.reporting.ReportTextVisitor;
|
|
||||||
|
|
||||||
import javax.naming.InsufficientResourcesException;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Operation for transporting products
|
|
||||||
*/
|
|
||||||
public class ProductTransaction extends Transaction {
|
|
||||||
|
|
||||||
private final Product product;
|
|
||||||
private final ProductOperationType type;
|
|
||||||
|
|
||||||
public ProductTransaction(NodeBase creator, NodeBase receiver, TransactionType transactionType, Product product) throws InsufficientResourcesException {
|
|
||||||
super(creator, receiver, transactionType, product.getCurrentOperation());
|
|
||||||
this.product = product;
|
|
||||||
type = null;
|
|
||||||
if (product == null || product.getProductState() != ProductState.IN_REQUIREMENT) throw new InsufficientResourcesException("product unavailable");
|
|
||||||
product.setCurrentOperation(this);
|
|
||||||
product.setStateToReadyForDispatch();
|
|
||||||
creator.getStorage().removeProduct(product);
|
|
||||||
|
|
||||||
LOGGER.log(Level.INFO, toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ends transaction and stores product in receivers storage.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void endTransaction() {
|
|
||||||
super.endTransaction();
|
|
||||||
getNodeReceiver().getStorage().storeProduct(product);
|
|
||||||
product.setStateToAvailable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Product getProduct() {
|
|
||||||
return product;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProductOperationType getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "ProductTransaction{" +
|
|
||||||
"product=" + product.getName() +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String accept(ReportTextVisitor visitor) {
|
|
||||||
return visitor.visit(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
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.reporting.ReportTextVisitor;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.signature.Signature;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.signature.SignatureManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Operation for transporting things between nodes
|
|
||||||
*/
|
|
||||||
public abstract class Transaction extends OperationBase {
|
|
||||||
|
|
||||||
private final TransactionType transactionType;
|
|
||||||
private final Signature signature;
|
|
||||||
private final NodeBase nodeReceiver;
|
|
||||||
|
|
||||||
Transaction(NodeBase creator, NodeBase receiver, TransactionType type, OperationBase lastOperation) {
|
|
||||||
super(creator, lastOperation);
|
|
||||||
transactionType = type;
|
|
||||||
nodeReceiver = receiver;
|
|
||||||
signature = SignatureManager.signTransaction(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets time end to current time.
|
|
||||||
*/
|
|
||||||
public void endTransaction() {
|
|
||||||
this.setTimeEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TransactionType getTransactionType() {
|
|
||||||
return transactionType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Signature getSignature() {
|
|
||||||
return signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NodeBase getNodeReceiver() {
|
|
||||||
return nodeReceiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Transaction{" +
|
|
||||||
"transactionType=" + transactionType +
|
|
||||||
", signature=" + (signature != null) +
|
|
||||||
", nodeCreator=" + getNodeCreator().getClass().getSimpleName() +
|
|
||||||
", nodeReceiver=" + nodeReceiver.getClass().getSimpleName() +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract String accept(ReportTextVisitor visitor);
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.operation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enum class for transaction types
|
|
||||||
*/
|
|
||||||
public enum TransactionType {
|
|
||||||
|
|
||||||
SALE, PURCHASE
|
|
||||||
}
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.parser;
|
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.w3c.dom.Node;
|
|
||||||
import org.w3c.dom.NodeList;
|
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parser for XML configuration
|
|
||||||
*/
|
|
||||||
public class ConfigurationParser {
|
|
||||||
|
|
||||||
private static Document activeDocument;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses xml file to document.
|
|
||||||
* @param name file name
|
|
||||||
* @throws ParserConfigurationException ParserConfigurationException
|
|
||||||
* @throws IOException IOException
|
|
||||||
* @throws SAXException SAXException
|
|
||||||
*/
|
|
||||||
public static void parseDocument(String name) throws ParserConfigurationException, IOException, SAXException {
|
|
||||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
|
||||||
factory.setValidating(true);
|
|
||||||
factory.setIgnoringElementContentWhitespace(true);
|
|
||||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
|
||||||
File file = new File(name);
|
|
||||||
activeDocument = builder.parse(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns parsed result with all elements having provided tag.
|
|
||||||
* @param tag element tag
|
|
||||||
* @return parsed result element
|
|
||||||
*/
|
|
||||||
public static ParserResult getElements(String tag) {
|
|
||||||
NodeList elements = activeDocument.getElementsByTagName(tag);
|
|
||||||
ParserResult resultList = new ParserResult();
|
|
||||||
for (int i = 0; i < elements.getLength(); i++) {
|
|
||||||
Node tmpNode = elements.item(i);
|
|
||||||
ParserResultElement element = new ParserResultElement();
|
|
||||||
for (int j = 0; j < tmpNode.getAttributes().getLength(); j++) {
|
|
||||||
element
|
|
||||||
.addAttribute(
|
|
||||||
tmpNode
|
|
||||||
.getAttributes()
|
|
||||||
.item(j)
|
|
||||||
.getNodeName(),
|
|
||||||
tmpNode
|
|
||||||
.getAttributes()
|
|
||||||
.item(j)
|
|
||||||
.getTextContent());
|
|
||||||
}
|
|
||||||
for (int j = 0; j < tmpNode.getChildNodes().getLength(); j++) {
|
|
||||||
element.addChild(tmpNode.getChildNodes().item(j).getNodeName(), tmpNode.getChildNodes().item(j).getTextContent());
|
|
||||||
}
|
|
||||||
resultList.addElement(element);
|
|
||||||
}
|
|
||||||
return resultList;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.parser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parser for console input
|
|
||||||
*/
|
|
||||||
public class ConsoleParser {
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.parser;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper class for parser result elements
|
|
||||||
*/
|
|
||||||
public class ParserResult {
|
|
||||||
|
|
||||||
private final List<ParserResultElement> elements;
|
|
||||||
|
|
||||||
public ParserResult() {
|
|
||||||
elements = new LinkedList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds element to list.
|
|
||||||
* @param element element
|
|
||||||
*/
|
|
||||||
public void addElement(ParserResultElement element) {
|
|
||||||
elements.add(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ParserResultElement> getElements() {
|
|
||||||
return elements;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.parser;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for storing all information given in a xml tag
|
|
||||||
*/
|
|
||||||
public class ParserResultElement {
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
private Map<String, String> attributes;
|
|
||||||
private Map<String, String> children;
|
|
||||||
|
|
||||||
public ParserResultElement() {
|
|
||||||
children = new HashMap<>();
|
|
||||||
attributes = new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getAttributes() {
|
|
||||||
return attributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAttributes(Map<String, String> attributes) {
|
|
||||||
this.attributes = attributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addAttribute(String key, String value) {
|
|
||||||
attributes.put(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAttribute(String key) {
|
|
||||||
return attributes.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getChildren() {
|
|
||||||
return children;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChildren(Map<String, String> children) {
|
|
||||||
this.children = children;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addChild(String key, String value) {
|
|
||||||
children.put(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getChild(String key) {
|
|
||||||
return children.get(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.pool;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.channel.ChannelBase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pool for storing all channels
|
|
||||||
*/
|
|
||||||
public class ChannelPool extends PoolListBase<ChannelBase> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds channel by its type.
|
|
||||||
* @param type type of channel
|
|
||||||
* @return channel
|
|
||||||
*/
|
|
||||||
public ChannelBase findByType(ProductType type) {
|
|
||||||
return findAll().stream().filter(ch -> ch.getProductType().equals(type)).findFirst().orElse(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.pool;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*Pool for storing all nodes
|
|
||||||
*/
|
|
||||||
public class NodePool extends PoolListBase<NodeBase> {
|
|
||||||
}
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.pool;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.util.Singleton;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Database class for storing all pools
|
|
||||||
*/
|
|
||||||
public class PoolDatabase {
|
|
||||||
|
|
||||||
public ChannelPool getChannelPoolInstance() {
|
|
||||||
try {
|
|
||||||
return Singleton.getInstance(ChannelPool.class);
|
|
||||||
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NodePool getNodePoolInstance() {
|
|
||||||
try {
|
|
||||||
return Singleton.getInstance(NodePool.class);
|
|
||||||
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProductPool getProductPoolInstance() {
|
|
||||||
try {
|
|
||||||
return Singleton.getInstance(ProductPool.class);
|
|
||||||
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScenarioPool getScenarioPoolInstance() {
|
|
||||||
try {
|
|
||||||
return Singleton.getInstance(ScenarioPool.class);
|
|
||||||
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.pool;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for all pools
|
|
||||||
* @param <T> pool type
|
|
||||||
*/
|
|
||||||
public abstract class PoolListBase<T> {
|
|
||||||
List<T> pool;
|
|
||||||
|
|
||||||
public PoolListBase() {
|
|
||||||
pool = new LinkedList<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<T> findAll() {
|
|
||||||
return pool;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(T element) {
|
|
||||||
pool.add(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(T element) {
|
|
||||||
pool.remove(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() {
|
|
||||||
pool.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean contains(T element) {
|
|
||||||
return pool.contains(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.pool;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.Product;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pool for storing all products
|
|
||||||
*/
|
|
||||||
public class ProductPool extends PoolListBase<Product> {
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.pool;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.scenario.Scenario;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pool for storing all scenarios
|
|
||||||
*/
|
|
||||||
public class ScenarioPool extends PoolListBase<Scenario> {
|
|
||||||
}
|
|
||||||
@ -1,157 +0,0 @@
|
|||||||
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.OperationBase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.reporting.ReportTextVisitor;
|
|
||||||
import org.javamoney.moneta.Money;
|
|
||||||
|
|
||||||
import javax.money.MonetaryAmount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Product class
|
|
||||||
*/
|
|
||||||
public class Product
|
|
||||||
{
|
|
||||||
private ProductState productState;
|
|
||||||
private ProductType productType;
|
|
||||||
private OperationBase currentOperation;
|
|
||||||
private MonetaryAmount price;
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
public Product(String name, ProductType productType, double m)
|
|
||||||
{
|
|
||||||
this.name = name;
|
|
||||||
this.productType = productType;
|
|
||||||
this.productState = ProductState.AVAILABLE;
|
|
||||||
this.price = Money.of(m, "USD");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Passes tick onto current operation
|
|
||||||
* @return operation is active
|
|
||||||
*/
|
|
||||||
public boolean tick() {
|
|
||||||
try {
|
|
||||||
return ((Action) currentOperation).tick();
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// "State machine methods"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set current product state to AVAILABLE. Throws IllegalStateException if the product is not IN_ACTION, READY_FOR_RECEPTION or IN_REQUIREMENT.
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
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 IN_REQUIREMENT.
|
|
||||||
*/
|
|
||||||
public void setStateToReadyForDispatch()
|
|
||||||
{
|
|
||||||
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 IN_REQUIREMENT!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set current product state to IN_TRANSIT. Throws IllegalStateException if the product is not READY_FOR_DISPATCH.
|
|
||||||
*/
|
|
||||||
public void setStateToInTransit()
|
|
||||||
{
|
|
||||||
if(this.productState.equals(ProductState.READY_FOR_DISPATCH))
|
|
||||||
this.productState = ProductState.IN_TRANSIT;
|
|
||||||
else
|
|
||||||
throw new IllegalStateException("Cannot set state IN_TRANSIT. Product is not READY_FOR_DISPATCH!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set current product state to READY_FOR_RECEPTION. Throws IllegalStateException if the product is not READY_FOR_RECEPTION.
|
|
||||||
*/
|
|
||||||
public void setStateToReadyForReception()
|
|
||||||
{
|
|
||||||
if(this.productState.equals(ProductState.IN_TRANSIT))
|
|
||||||
this.productState = ProductState.READY_FOR_RECEPTION;
|
|
||||||
else
|
|
||||||
throw new IllegalStateException("Cannot set state READY_FOR_RECEPTION. Product has not been in transit!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set current product state to IN_ACTION. Throws IllegalStateException if the product is not AVAILABLE.
|
|
||||||
*/
|
|
||||||
public void setStateToInAction()
|
|
||||||
{
|
|
||||||
if(this.productState.equals(ProductState.AVAILABLE))
|
|
||||||
this.productState = ProductState.IN_ACTION;
|
|
||||||
else
|
|
||||||
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!");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Getters & Setters
|
|
||||||
|
|
||||||
public ProductState getProductState()
|
|
||||||
{
|
|
||||||
return productState;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProductType getProductType()
|
|
||||||
{
|
|
||||||
return productType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProductType(ProductType productType)
|
|
||||||
{
|
|
||||||
this.productType = productType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name)
|
|
||||||
{
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OperationBase getCurrentOperation()
|
|
||||||
{
|
|
||||||
return currentOperation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCurrentOperation(OperationBase currentOperation)
|
|
||||||
{
|
|
||||||
this.currentOperation = currentOperation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MonetaryAmount getPrice() { return price; }
|
|
||||||
|
|
||||||
public void setPrice(MonetaryAmount price) { this.price = price; }
|
|
||||||
|
|
||||||
public String accept(ReportTextVisitor visitor){
|
|
||||||
return visitor.visit(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.product;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enum class for product states
|
|
||||||
*/
|
|
||||||
public enum ProductState
|
|
||||||
{
|
|
||||||
AVAILABLE, READY_FOR_DISPATCH, IN_TRANSIT, READY_FOR_RECEPTION, IN_ACTION, IN_REQUIREMENT
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.product;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enum class for product types
|
|
||||||
*/
|
|
||||||
public enum ProductType
|
|
||||||
{
|
|
||||||
MEAT, FRUIT, VEGETABLE, OTHER, ALL // ALL is used only for actions
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,77 +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.*;
|
|
||||||
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 "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
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 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +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.*;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.requirement;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.operation.TransactionType;
|
|
||||||
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.util.Ticker;
|
|
||||||
import org.javamoney.moneta.Money;
|
|
||||||
|
|
||||||
import javax.money.MonetaryAmount;
|
|
||||||
import javax.naming.InsufficientResourcesException;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Requirement class
|
|
||||||
*/
|
|
||||||
public class Requirement {
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(Ticker.class.getName());
|
|
||||||
|
|
||||||
private final NodeBase creator;
|
|
||||||
private final TransactionType transactionType;
|
|
||||||
private final ProductType productType;
|
|
||||||
private final String productName;
|
|
||||||
private final MonetaryAmount price;
|
|
||||||
private int TTL;
|
|
||||||
private static int counter;
|
|
||||||
private int id;
|
|
||||||
|
|
||||||
public Requirement(NodeBase creator, TransactionType transactionType, ProductType productType, String productName, MonetaryAmount price) {
|
|
||||||
this.creator = creator;
|
|
||||||
this.transactionType = transactionType;
|
|
||||||
this.productType = productType;
|
|
||||||
this.productName = productName;
|
|
||||||
this.price = price;
|
|
||||||
this.TTL = 3;
|
|
||||||
this.id = counter++;
|
|
||||||
|
|
||||||
LOGGER.log(Level.INFO, toString());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reduces TTL.
|
|
||||||
*/
|
|
||||||
public void tick() {
|
|
||||||
TTL--;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NodeBase getCreator() {
|
|
||||||
return creator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TransactionType getTransactionType() {
|
|
||||||
return transactionType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProductType getProductType() {
|
|
||||||
return productType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProductName() {
|
|
||||||
return productName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MonetaryAmount getPrice() { return price; }
|
|
||||||
|
|
||||||
public int getTTL() {
|
|
||||||
return TTL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Requirement{" +
|
|
||||||
"id=" + id +
|
|
||||||
", creator=" + creator.getClass().getSimpleName() +
|
|
||||||
", transactionType=" + transactionType +
|
|
||||||
", productName='" + productName + '\'' +
|
|
||||||
", TTL=" + TTL +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.scenario;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.Customer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Step for consuming random product from storage
|
|
||||||
*/
|
|
||||||
public class ConsumeProductStep extends ScenarioStep {
|
|
||||||
|
|
||||||
private final Customer node;
|
|
||||||
|
|
||||||
public ConsumeProductStep(Customer node) {
|
|
||||||
this.node = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Consumes random product.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
void execute() {
|
|
||||||
node.consumeProduct();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.scenario;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.operation.ProductOperationType;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.Product;
|
|
||||||
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Step for starting action on product(s)
|
|
||||||
*/
|
|
||||||
public class DoActionStep extends ScenarioStep {
|
|
||||||
private final NodeBase nodeBase;
|
|
||||||
private final ProductOperationType productOperationType;
|
|
||||||
private final Product product;
|
|
||||||
|
|
||||||
public DoActionStep(NodeBase node, ProductOperationType productOperationType, Product product){
|
|
||||||
this.nodeBase = node;
|
|
||||||
this.productOperationType = productOperationType;
|
|
||||||
this.product = product;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DoActionStep(NodeBase node, ProductOperationType productOperationType){
|
|
||||||
this(node, productOperationType, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts action.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
void execute() {
|
|
||||||
try {
|
|
||||||
if (product != null) {
|
|
||||||
nodeBase.doAction(productOperationType, product);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nodeBase.doAction(productOperationType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IllegalCallerException e) {
|
|
||||||
LOGGER.log(Level.SEVERE, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.scenario;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.FoodChain;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.Farmer;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.Product;
|
|
||||||
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Step for generating product from pool
|
|
||||||
*/
|
|
||||||
public class GenerateProductStep extends ScenarioStep {
|
|
||||||
|
|
||||||
private final Farmer node;
|
|
||||||
private final Product product;
|
|
||||||
private static int counter = 0;
|
|
||||||
|
|
||||||
public GenerateProductStep(Farmer node) {
|
|
||||||
this.node = node;
|
|
||||||
if (counter < FoodChain.getFactoryManager().getPoolDatabaseInstance().getProductPoolInstance().findAll().size()) {
|
|
||||||
product = FoodChain.getFactoryManager().getPoolDatabaseInstance().getProductPoolInstance().findAll().get(counter);
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
product = null;
|
|
||||||
LOGGER.log(Level.SEVERE, "Insufficient products in pool");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates product from pool.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
void execute() {
|
|
||||||
node.generateProduct(product);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.scenario;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Step for skipping
|
|
||||||
*/
|
|
||||||
public class PassStep extends ScenarioStep {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Does nothing.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
void execute() {}
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.scenario;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scenatio class fpr holding and executing steps
|
|
||||||
*/
|
|
||||||
public class Scenario {
|
|
||||||
List<ScenarioStep> steps;
|
|
||||||
Iterator<ScenarioStep> stepIterator;
|
|
||||||
|
|
||||||
public Scenario(List<ScenarioStep> steps) {
|
|
||||||
this.steps = steps;
|
|
||||||
stepIterator = steps.listIterator(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes next step.
|
|
||||||
* @return scenario has steps
|
|
||||||
*/
|
|
||||||
boolean execute() {
|
|
||||||
if (!stepIterator.hasNext()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
stepIterator.next().execute();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes next step.
|
|
||||||
* @return scenario has steps
|
|
||||||
*/
|
|
||||||
public boolean tick() {
|
|
||||||
return execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ScenarioStep> getSteps() {
|
|
||||||
return steps;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.scenario;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.operation.OperationBase;
|
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scenario step class
|
|
||||||
*/
|
|
||||||
public abstract class ScenarioStep {
|
|
||||||
protected static final Logger LOGGER = Logger.getLogger(ScenarioStep.class.getName());
|
|
||||||
|
|
||||||
abstract void execute();
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.scenario;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.operation.TransactionType;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
|
|
||||||
import org.javamoney.moneta.Money;
|
|
||||||
|
|
||||||
import javax.money.MonetaryAmount;
|
|
||||||
import javax.naming.InsufficientResourcesException;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Step for sending requirements
|
|
||||||
*/
|
|
||||||
public class SendRequirementStep extends ScenarioStep {
|
|
||||||
private final NodeBase node;
|
|
||||||
private final TransactionType tType;
|
|
||||||
private final ProductType pType;
|
|
||||||
private final String pName;
|
|
||||||
private MonetaryAmount pPrice;
|
|
||||||
|
|
||||||
// sell
|
|
||||||
public SendRequirementStep(NodeBase node, TransactionType tType, ProductType pType, String pName) {
|
|
||||||
this.node = node;
|
|
||||||
this.tType = tType;
|
|
||||||
this.pType = pType;
|
|
||||||
this.pName = pName;
|
|
||||||
this.pPrice = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// buy
|
|
||||||
public SendRequirementStep(NodeBase node, TransactionType tType, ProductType pType, String pName, Double price) {
|
|
||||||
this.node = node;
|
|
||||||
this.tType = tType;
|
|
||||||
this.pType = pType;
|
|
||||||
this.pName = pName;
|
|
||||||
this.pPrice = Money.of(price, "USD");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates requirement.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
void execute() {
|
|
||||||
try {
|
|
||||||
node.createRequirement(tType, pType, pName, pPrice);
|
|
||||||
} catch (InsufficientResourcesException e) {
|
|
||||||
LOGGER.log(Level.SEVERE, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.signature;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.operation.Transaction;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Signature class validating its transaction
|
|
||||||
*/
|
|
||||||
public class Signature {
|
|
||||||
|
|
||||||
private final String managerCode;
|
|
||||||
private final Transaction transaction;
|
|
||||||
private final LocalDateTime signedDate;
|
|
||||||
private final UUID uuid;
|
|
||||||
|
|
||||||
public Signature(String code, Transaction transaction) {
|
|
||||||
managerCode = code;
|
|
||||||
this.transaction = transaction;
|
|
||||||
signedDate = LocalDateTime.now();
|
|
||||||
uuid = UUID.randomUUID();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transaction getTransaction(String code) {
|
|
||||||
if (code.equals(managerCode))
|
|
||||||
return transaction;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getSignedDate(String code) {
|
|
||||||
if (code.equals(managerCode))
|
|
||||||
return signedDate;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UUID getUuid(String code) {
|
|
||||||
if (code.equals(managerCode))
|
|
||||||
return uuid;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.signature;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.operation.Transaction;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manager class for creating and validating signatures
|
|
||||||
*/
|
|
||||||
public class SignatureManager {
|
|
||||||
|
|
||||||
private static final String MANAGER_CODE = "iW91AJWNOCmX1pbpLlW0";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates signature for transaction.
|
|
||||||
* @param transaction transaction
|
|
||||||
* @return signature
|
|
||||||
*/
|
|
||||||
public static Signature signTransaction(Transaction transaction) {
|
|
||||||
return new Signature(MANAGER_CODE, transaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if signature corresponds with its transaction.
|
|
||||||
* @param transaction transaction
|
|
||||||
* @return signature corresponds with its transaction
|
|
||||||
*/
|
|
||||||
public static boolean validateSignature(Transaction transaction) {
|
|
||||||
return transaction.equals(transaction.getSignature().getTransaction(MANAGER_CODE))
|
|
||||||
&& transaction.getSignature().getUuid(MANAGER_CODE).equals(transaction.getSignature().getTransaction(MANAGER_CODE).getSignature().getUuid(MANAGER_CODE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.util;
|
|
||||||
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.channel.ChannelBase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.requirement.Requirement;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for nodes that receives requirements
|
|
||||||
*/
|
|
||||||
public interface ChannelObserver {
|
|
||||||
void update(Requirement requirement, ChannelBase channel);
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for channels to work with observers
|
|
||||||
*/
|
|
||||||
public interface Observable {
|
|
||||||
void attach(ChannelObserver channelObserver);
|
|
||||||
void detach(ChannelObserver channelObserver);
|
|
||||||
void notifyAllObservers();
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.util;
|
|
||||||
|
|
||||||
import java.util.logging.Handler;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.LogRecord;
|
|
||||||
|
|
||||||
public class ReportLogger extends Handler
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void publish(LogRecord record) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append(record.getSourceClassName())
|
|
||||||
.append("#")
|
|
||||||
.append(record.getSourceMethodName())
|
|
||||||
.append(" - ")
|
|
||||||
.append(record.getMessage());
|
|
||||||
|
|
||||||
if(record.getLevel().equals(Level.WARNING) || record.getLevel().equals(Level.SEVERE))
|
|
||||||
{
|
|
||||||
System.err.println(sb.toString());
|
|
||||||
//todo add some outprint to report log
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
System.out.println(sb.toString());
|
|
||||||
//todo add some outprint to report log
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void flush() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws SecurityException {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.util;
|
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Singleton implementation 1 of 3
|
|
||||||
*/
|
|
||||||
public class Singleton {
|
|
||||||
|
|
||||||
private static final Singleton instance = new Singleton();
|
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
private final Map<Class, Object> mapHolder = new HashMap<>();
|
|
||||||
|
|
||||||
private Singleton() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T getInstance(Class<T> tClass) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
|
|
||||||
if (!instance.mapHolder.containsKey(tClass)) {
|
|
||||||
Constructor<T> cons = tClass.getConstructor();
|
|
||||||
Object object = cons.newInstance();
|
|
||||||
instance.mapHolder.put(tClass, object);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (T) instance.mapHolder.get(tClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
package cz.cvut.fel.sit.omo.foodchain.util;
|
|
||||||
|
|
||||||
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.pool.PoolDatabase;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.product.Product;
|
|
||||||
import cz.cvut.fel.sit.omo.foodchain.scenario.Scenario;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates artificial time for application
|
|
||||||
*/
|
|
||||||
public class Ticker {
|
|
||||||
protected static final Logger LOGGER = Logger.getLogger(Ticker.class.getName());
|
|
||||||
|
|
||||||
private static Timer timer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts timer.
|
|
||||||
*/
|
|
||||||
public static void start() {
|
|
||||||
timer = new Timer(1000, actionEvent -> {
|
|
||||||
LOGGER.log(Level.INFO, "-----tick-----");
|
|
||||||
|
|
||||||
PoolDatabase db = FoodChain.getFactoryManager().getPoolDatabaseInstance();
|
|
||||||
boolean productBool = db.getProductPoolInstance().findAll().stream().filter(Product::tick).count() == 0; // change duration of action
|
|
||||||
boolean channelBool = db.getChannelPoolInstance().findAll().stream().filter(ChannelBase::tick).count() == 0; // change TTL of requirements
|
|
||||||
boolean scenarioBool = db.getScenarioPoolInstance().findAll().stream().filter(Scenario::tick).count() == 0; // do next step in scenario
|
|
||||||
db.getNodePoolInstance().findAll().forEach(n -> n.tick()); // receive transactions
|
|
||||||
if (channelBool && productBool && scenarioBool) stop();
|
|
||||||
});
|
|
||||||
timer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stops timer (ends application).
|
|
||||||
*/
|
|
||||||
public static void stop() {
|
|
||||||
timer.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Timer getTimer() { return timer; }
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user