Compare commits

..

No commits in common. "feature/channel_impl" and "master" have entirely different histories.

68 changed files with 0 additions and 2343 deletions

4
.gitignore vendored
View File

@ -1,4 +0,0 @@
.idea
target
*.idb

Binary file not shown.

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4" />

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>
sell <product-type> <product-name>
buy <product-type> <produt-name> <product-price>
pass
-->
<scenarios>
<scenario type="Farmer">
<steps>
generate
pass
sell FRUIT jablko
</steps>
</scenario>
</scenarios>

24
pom.xml
View File

@ -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>

View File

@ -1,129 +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.scenario.Scenario;
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;
public class FoodChain
{
private static FactoryManager factoryManager = new FactoryManager();
public static void main(String[] args)
{
parseChannels();
parseNodes();
parseProducts();
parseScenarios();
// 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());
}
public static FactoryManager getFactoryManager()
{
return factoryManager;
}
// todo maybe some refactoring needed?
// add other entities
public static void parseChannels()
{
try
{
// parse channel configuration
ConfigurationParser.parseDocument("conf/channels.xml");
ParserResult parserResult = ConfigurationParser.getElements("channel");
List<ParserResultElement> elements = parserResult.getElements();
for (ParserResultElement el : elements)
{
ChannelBase res = getFactoryManager().getChannelFactoryInstance().makeChannel(el);
getFactoryManager().getPoolDatabaseInstance().getChannelPoolInstance().add(res);
}
}
catch (ParserConfigurationException | SAXException | IOException e)
{
System.err.println(e.getMessage());
}
}
public static void parseNodes()
{
try
{
// parse channel configuration
ConfigurationParser.parseDocument("conf/nodes.xml");
ParserResult parserResult = ConfigurationParser.getElements("node");
List<ParserResultElement> elements = parserResult.getElements();
for (ParserResultElement el : elements)
{
NodeBase res = getFactoryManager().getNodeFactoryInstance().makeNode(el);
getFactoryManager().getPoolDatabaseInstance().getNodePoolInstance().add(res);
}
}
catch (ParserConfigurationException | SAXException | IOException e)
{
System.err.println(e.getMessage());
}
}
public static void parseProducts()
{
try
{
// parse channel configuration
ConfigurationParser.parseDocument("conf/products.xml");
ParserResult parserResult = ConfigurationParser.getElements("product");
List<ParserResultElement> elements = parserResult.getElements();
for (ParserResultElement el : elements)
{
Product res = getFactoryManager().getProductFactoryInstance().makeProduct(el);
getFactoryManager().getPoolDatabaseInstance().getProductPoolInstance().add(res);
}
}
catch (ParserConfigurationException | SAXException | IOException e)
{
System.err.println(e.getMessage());
}
}
public static void parseScenarios()
{
try
{
// parse channel configuration
ConfigurationParser.parseDocument("conf/scenarios.xml");
ParserResult parserResult = ConfigurationParser.getElements("scenario");
List<ParserResultElement> elements = parserResult.getElements();
for (ParserResultElement el : elements)
{
Scenario res = getFactoryManager().getScenarioFactoryInstance().makeScenario(el);
getFactoryManager().getPoolDatabaseInstance().getScenarioPoolInstance().add(res);
}
}
catch (ParserConfigurationException | SAXException | IOException e)
{
System.err.println(e.getMessage());
}
}
}

View File

@ -1,106 +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.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;
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);
}
public boolean tick() {
requirements.forEach(Requirement::tick);
requirements = requirements.stream().filter(r -> r.getTTL() > 0).collect(Collectors.toCollection(LinkedList::new));
notifyAllObservers();
return requirements.size() != 0;
}
@Override
public void notifyAllObservers(){
subscribers.forEach(subscriber -> new LinkedList<>(requirements).forEach(r -> subscriber.update(r, this)));
}
@Override
public void attach(ChannelObserver observer){
subscribers.add(observer);
}
@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) {}
}
public void disposeOf(Requirement requirement) { this.requirements.remove(requirement); }
public void disposeOf(Transaction transaction) { this.transactions.remove(transaction); }
/**
* Clears all requirements from this channel
*/
public void clearRequirements()
{
this.requirements.clear();
}
public ProductType getProductType() {
return productType;
}
}

View File

@ -1,6 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.channel;
public enum ChannelSubscriptionType {
SALE, PURCHASE, SALE_AND_PURCHASE
}

View File

@ -1,11 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.channel;
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
public class FruitChannel extends ChannelBase
{
public FruitChannel()
{
super(ProductType.FRUIT);
}
}

View File

@ -1,11 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.channel;
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
public class MeatChannel extends ChannelBase
{
public MeatChannel()
{
super(ProductType.MEAT);
}
}

View File

@ -1,11 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.channel;
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
public class OtherChannel extends ChannelBase
{
public OtherChannel()
{
super();
}
}

View File

@ -1,11 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.channel;
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
public class VegetableChannel extends ChannelBase
{
public VegetableChannel()
{
super(ProductType.VEGETABLE);
}
}

View File

@ -1,50 +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.parser.ParserResultElement;
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
public class ChannelFactory
{
/**
* Creates channel based on channel type (Fruit, Vegetable, Meat, Other)
* @param input data from channel 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)
{
System.err.println("! Wrong type of enum in ChannelFactory: " + e);
}
catch (Exception e)
{
System.err.println("! Fatal error in ChannelFactory: " + e);
}
return c;
}
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;
}
}

View File

@ -1,75 +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;
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;
}
}

View File

@ -1,78 +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;
public class NodeFactory
{
/**
* Creates Node based on input ParserResultElement
* @param input data from Node 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)
{
System.err.println("! Wrong type of enum in NodeFactory: " + e.getMessage());
}
catch (Exception e)
{
System.err.println("! 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;
}
}

View File

@ -1,39 +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;
public class ProductFactory
{
/**
* Creates Product based on input ParserResultElement
* @param input data from Product 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)
{
System.err.println("! Wrong type of enum in ProductFactory: " + e);
}
catch (Exception e)
{
System.err.println("! Fatal error in ProductFactory: " + e);
}
return p;
}
}

View File

@ -1,84 +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;
public class ScenarioFactory
{
/**
* Creates Scenario based on input ParserResultElement
* @param input data from Scenario 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)
{
System.err.println("! Wrong type of enum in ScenarioFactory: " + e);
}
return s;
}
}

View File

@ -1,21 +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;
public class Customer extends BuyerNodeBase {
public Customer(double startMoney) {
super(startMoney);
allowedSeller = NodeType.Distributor;
allowedPurchaser = NodeType.None;
this.nodeType = NodeType.Customer;
}
public void consumeProduct() {
int i = new Random().nextInt(getStorage().size());
getStorage().remove(i);
}
}

View File

@ -1,14 +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;
public class Distributor extends RetailerNodeBase {
public Distributor(double startMoney) {
super(startMoney);
allowedSeller = NodeType.Seller;
allowedPurchaser = NodeType.Customer;
this.nodeType = NodeType.Distributor;
}
}

View File

@ -1,27 +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;
public class Farmer extends SellerNodeBase {
public Farmer(double startMoney) {
super(startMoney);
allowedSeller = NodeType.None;
allowedPurchaser = NodeType.Processor;
this.nodeType = NodeType.Farmer;
}
public void generateProduct(Product product) {
storeProduct(product);
try {
createRequirement(TransactionType.SALE, product.getProductType(), product.getName(), product.getPrice());
} catch (InsufficientResourcesException e) {
System.err.println(e.getMessage());
}
}
}

View File

@ -1,14 +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;
public class Processor extends RetailerNodeBase {
public Processor(double startMoney) {
super(startMoney);
allowedSeller = NodeType.Farmer;
allowedPurchaser = NodeType.Seller;
this.nodeType = NodeType.Processor;
}
}

View File

@ -1,14 +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;
public class Seller extends RetailerNodeBase {
public Seller(double startMoney) {
super(startMoney);
allowedSeller = NodeType.Processor;
allowedPurchaser = NodeType.Distributor;
this.nodeType = NodeType.Seller;
}
}

View File

@ -1,16 +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;
public class BuyerNodeBase extends NodeBase implements IBuyerNode {
public BuyerNodeBase(double m){
super(m);
}
@Override
public void buyProduct(Product product) {
}
}

View File

@ -1,263 +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.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.requirement.Requirement;
import cz.cvut.fel.sit.omo.foodchain.signature.Signature;
import cz.cvut.fel.sit.omo.foodchain.signature.SignatureManager;
import cz.cvut.fel.sit.omo.foodchain.util.ChannelObserver;
import org.javamoney.moneta.Money;
import javax.money.MonetaryAmount;
import javax.naming.InsufficientResourcesException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class NodeBase implements ChannelObserver {
private final Map<ChannelBase, ChannelSubscriptionType> subscribedChannels;
private final List<Product> products;
private final List<Transaction> refusedTransactions;
private MonetaryAmount money;
protected NodeType nodeType;
protected NodeType allowedSeller;
protected NodeType allowedPurchaser;
public NodeBase() {
this.nodeType = NodeType.None;
this.subscribedChannels = new HashMap<>();
this.products = new LinkedList<>();
this.refusedTransactions = new LinkedList<>();
this.money = Money.of(0, "USD");
}
public NodeBase(double m) {
this.subscribedChannels = new HashMap<>();
this.products = new LinkedList<>();
this.refusedTransactions = new LinkedList<>();
this.money = Money.of(m, "USD");
}
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) {
e.printStackTrace();
}
}
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) {
e.printStackTrace();
}
}
public void receiveTransaction(Transaction transaction) {
try {
receiveTransaction((ProductTransaction) transaction);
}
catch (Exception e) {
try {
receiveTransaction((FinancialTransaction) transaction);
}
catch (Exception ex) {
System.err.println(ex.getMessage());
}
}
}
public void receiveTransaction(ProductTransaction transaction) {
if (validateSignature(transaction)) {
transaction.getProduct().setStateToReadyForReception();
transaction.endTransaction();
sendTransaction(transaction.getProduct().getPrice(), transaction.getNodeCreator(), transaction);
}
else refuseTransaction(transaction);
}
public void receiveTransaction(FinancialTransaction transaction) {
if (validateSignature(transaction)) transaction.endTransaction();
else refuseTransaction(transaction);
}
public void refuseTransaction(Transaction transaction) {
transaction.endTransaction();
refusedTransactions.add(transaction);
}
public void receiveTransactions() {
subscribedChannels.keySet().forEach(ch -> ch.getTransactions(this).forEach(t -> {receiveTransaction(t); ch.disposeOf(t);}));
}
public void createRequirement(TransactionType tType, ProductType pType, String pName, double price) {
Requirement req = new Requirement(this, tType, pType, pName, price);
subscribedChannels.keySet().stream()
.filter(ch -> ch.getProductType().equals(pType))
.findAny().ifPresent(channel -> channel.addRequirement(req));
}
public void createRequirement(TransactionType tType, ProductType pType, String pName, MonetaryAmount price) throws InsufficientResourcesException {
if (price == null) {
try {
price = getProductFromStorage(pName, pType).getPrice();
}
catch (NullPointerException e) {
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));
}
public void acceptRequirement(Requirement req) throws InsufficientResourcesException {
System.out.println(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(getProductFromStorage(req.getProductName(), req.getProductType()).getPrice().multiply(0.9))) {
getProductFromStorage(req.getProductName(), req.getProductType()).setPrice(req.getPrice());
sendTransaction(getProductFromStorage(req.getProductName(), req.getProductType()), req.getCreator());
}
else createRequirement(TransactionType.SALE, req.getProductType(), req.getProductName(), req.getPrice());
}
}
public void subscribeToChannel(ChannelBase channel, ChannelSubscriptionType type) {
subscribedChannels.put(channel, type);
channel.attach(this);
}
public void unsubscribeFromChannel(ChannelBase channel) {
subscribedChannels.remove(channel);
}
/**
* 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.nodeType))
new Action(this, product, action);
else
throw new IllegalCallerException("! IllegalCallerException in NodeBase. " + this.nodeType.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, t, action));
}
public void storeProduct(Product product) {
this.products.add(product);
}
public void storeProducts(List<Product> products) {
this.products.addAll(products);
}
public Product getProductFromStorage(String name, ProductType type) {
return products.stream().filter(ch -> ch.getProductType() == type && ch.getName().equals(name)).findFirst().orElse(null);
}
public List<Product> getStorage() {
return products;
}
public MonetaryAmount getMoney() {
return money;
}
public void addMoney(MonetaryAmount m) {
this.money = this.money.add(m);
}
public void subtractMoney(MonetaryAmount m) {
this.money = this.money.subtract(m);
}
public boolean validateSignature(Transaction transaction) {
return SignatureManager.validateSignature(transaction);
}
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));
}
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;
}
boolean requirementCheck(Requirement req) {
return (req.getTransactionType() == TransactionType.SALE && money.isGreaterThanOrEqualTo(req.getPrice())) ||
(req.getTransactionType() == TransactionType.PURCHASE && getProductFromStorage(req.getProductName(), req.getProductType()) != null &&
getProductFromStorage(req.getProductName(), req.getProductType()).getProductState() == ProductState.AVAILABLE);
}
@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) {
System.err.println(e.getMessage());
}
}
}
public void tick() {
receiveTransactions();
//System.out.println(this.getClass().getSimpleName() + ": " + money.getNumber());
}
}

View File

@ -1,26 +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;
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) {
}
}

View File

@ -1,20 +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;
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) {
}
}

View File

@ -1,5 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.node.enums;
public enum NodeType {
Farmer, Processor, Distributor, Seller, Customer, None, All
}

View File

@ -1,8 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.node.interfaces;
import cz.cvut.fel.sit.omo.foodchain.product.Product;
public interface IBuyerNode {
void buyProduct(Product product);
}

View File

@ -1,10 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.node.interfaces;
import cz.cvut.fel.sit.omo.foodchain.product.Product;
public interface ISellerNode {
void sellProduct(Product product);
void addMargin(Product product);
}

View File

@ -1,58 +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;
public class Action extends OperationBase {
private final OperationBase lastOperation;
private final Product product;
private final ProductOperationType type;
private int duration;
public Action(NodeBase node, Product product, ProductOperationType type) {
super(node);
this.product = product;
this.type = type;
lastOperation = product.getCurrentOperation();
duration = type.getDuration();
product.setCurrentOperation(this);
product.setStateToInAction();
System.out.println(toString());
}
private void endAction() {
this.setTimeEnd();
product.setStateToAvailable();
}
public boolean tick() {
if (duration == 0) {
endAction();
return false;
}
else duration--;
return true;
}
public OperationBase getLastOperation() {
return lastOperation;
}
public Product getProduct() {
return product;
}
public ProductOperationType getType() {
return type;
}
@Override
public String toString() {
return "Action{" +
", product=" + product +
", type=" + type +
", duration=" + duration +
'}';
}
}

View File

@ -1,43 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.operation;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import javax.money.MonetaryAmount;
import javax.naming.InsufficientResourcesException;
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);
this.amount = amount;
this.transactionPaid = transactionPaid;
if (creator.getMoney().isLessThan(amount)) throw new InsufficientResourcesException("not enough money");
creator.subtractMoney(amount);
System.out.println(toString());
}
@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 +
'}';
}
}

View File

@ -1,34 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.operation;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import java.time.LocalDateTime;
public class OperationBase {
private final LocalDateTime timeStart;
private LocalDateTime timeEnd;
private final NodeBase nodeCreator;
OperationBase(NodeBase node) {
nodeCreator = node;
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;
}
}

View File

@ -1,52 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.operation;
import cz.cvut.fel.sit.omo.foodchain.node.enums.NodeType;
public enum ProductOperationType
{
STORE_MEAT(NodeType.All, 20, -8),
STORE_FRUIT(NodeType.All, 8, 2),
STORE_VEGETABLE(NodeType.All, 10, 2),
STORE_OTHER(NodeType.All, 30, 21),
WRAP_INTO_GIFT_PACKAGE(NodeType.Seller, 1, -8),
UNWRAP(NodeType.All, 1, 21),
CUT_TO_PIECES(NodeType.All, 1, 21),
BOIL_MEAT(NodeType.All, 1, 21),
GRILL_MEAT(NodeType.All, 1, 21),
SMOKE_MEAT(NodeType.All, 1, 21),
DRY_MEAT(NodeType.All, 1, 21),
DRY_FRUIT(NodeType.All, 1, 21),
FREEZE_DRY_FRUIT(NodeType.All, 1, 21);
//todo add product type allowed for this action
private final NodeType node;
private final int duration;
private final int temperature;
ProductOperationType(NodeType node, int duration, int temperature)
{
this.node = node;
this.duration = duration;
this.temperature = temperature;
}
public int getDuration()
{
return duration;
}
public int getTemperature()
{
return temperature;
}
public NodeType getNode()
{
return node;
}
}

View File

@ -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.product.Product;
import cz.cvut.fel.sit.omo.foodchain.product.ProductState;
import javax.naming.InsufficientResourcesException;
public class ProductTransaction extends Transaction {
private final OperationBase lastOperation;
private final Product product;
private final ProductOperationType type;
public ProductTransaction(NodeBase creator, NodeBase receiver, TransactionType transactionType, Product product) throws InsufficientResourcesException {
super(creator, receiver, transactionType);
this.product = product;
type = null;
lastOperation = product.getCurrentOperation();
if (product == null || product.getProductState() != ProductState.AVAILABLE) throw new InsufficientResourcesException("product not available");
product.setCurrentOperation(this);
product.setStateToReadyForDispatch();
creator.getStorage().remove(product);
System.out.println(toString());
}
@Override
public void endTransaction() {
super.endTransaction();
getNodeReceiver().storeProduct(product);
product.setStateToAvailable();
}
public OperationBase getLastOperation() {
return lastOperation;
}
public Product getProduct() {
return product;
}
public ProductOperationType getType() {
return type;
}
@Override
public String toString() {
return "ProductTransaction{" +
"product=" + product.getName() +
'}';
}
}

View File

@ -1,45 +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.signature.Signature;
import cz.cvut.fel.sit.omo.foodchain.signature.SignatureManager;
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) {
super(creator);
transactionType = type;
nodeReceiver = receiver;
signature = SignatureManager.signTransaction(this);
}
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() +
'}';
}
}

View File

@ -1,6 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.operation;
public enum TransactionType {
SALE, PURCHASE
}

View File

@ -1,52 +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;
public class ConfigurationParser {
private static Document activeDocument;
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);
}
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;
}
}

View File

@ -1,4 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.parser;
public class ConsoleParser {
}

View File

@ -1,22 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.parser;
import java.util.LinkedList;
import java.util.List;
public class ParserResult {
private final List<ParserResultElement> elements;
public ParserResult() {
elements = new LinkedList<>();
}
public void addElement(ParserResultElement element) {
elements.add(element);
}
public List<ParserResultElement> getElements() {
return elements;
}
}

View File

@ -1,57 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.parser;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
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);
}
}

View File

@ -1,11 +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;
public class ChannelPool extends PoolListBase<ChannelBase> {
public ChannelBase findByType(ProductType type) {
return findAll().stream().filter(ch -> ch.getProductType().equals(type)).findFirst().orElse(null);
}
}

View File

@ -1,6 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.pool;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
public class NodePool extends PoolListBase<NodeBase> {
}

View File

@ -1,44 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.pool;
import cz.cvut.fel.sit.omo.foodchain.util.Singleton;
import java.lang.reflect.InvocationTargetException;
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;
}
}

View File

@ -1,32 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.pool;
import java.util.LinkedList;
import java.util.List;
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);
}
}

View File

@ -1,6 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.pool;
import cz.cvut.fel.sit.omo.foodchain.product.Product;
public class ProductPool extends PoolListBase<Product> {
}

View File

@ -1,6 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.pool;
import cz.cvut.fel.sit.omo.foodchain.scenario.Scenario;
public class ScenarioPool extends PoolListBase<Scenario> {
}

View File

@ -1,188 +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 org.javamoney.moneta.Money;
import javax.money.Monetary;
import javax.money.MonetaryAmount;
public class Product
{
private ProductState productState;
private ProductType productType;
private OperationBase currentOperation;
private MonetaryAmount price;
private String name;
/**
* Creates Product with default state AVAILABLE
* @param name name of product
* @param productType type of product
*/
public Product(String name, ProductType productType)
{
this.name = name;
this.productType = productType;
this.productState = ProductState.AVAILABLE;
this.price = Money.of(0, "USD");
}
public Product(String name, ProductType productType, double m)
{
this.name = name;
this.productType = productType;
this.productState = ProductState.AVAILABLE;
this.price = Money.of(m, "USD");
}
/**
* Creates Product
* @param name name of product
* @param productType type of product
* @param productState state of product
*/
public Product(String name, ProductType productType, ProductState productState)
{
this.name = name;
this.productType = productType;
this.productState = productState;
this.price = Money.of(0, "USD");
}
public Product(String name, ProductType productType, ProductState productState, double m)
{
this.name = name;
this.productType = productType;
this.productState = productState;
this.price = Money.of(m, "USD");
}
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!");
}
/*
public void setProductState(ProductState productState)
{
this.productState = productState;
}*/
//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; }
}

View File

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

View File

@ -1,6 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.product;
public enum ProductType
{
MEAT, FRUIT, VEGETABLE, OTHER;
}

View File

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

View File

@ -1,4 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.reporting;
public class ReportingManager {
}

View File

@ -1,81 +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 org.javamoney.moneta.Money;
import javax.money.MonetaryAmount;
import javax.naming.InsufficientResourcesException;
public class Requirement {
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, double price) {
this.creator = creator;
this.transactionType = transactionType;
this.productType = productType;
this.productName = productName;
this.price = Money.of(price, "USD");
this.TTL = 3;
this.id = counter++;
System.out.println(toString());
}
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++;
System.out.println(toString());
}
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 +
'}';
}
}

View File

@ -1,17 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.scenario;
import cz.cvut.fel.sit.omo.foodchain.node.Customer;
public class ConsumeProductStep extends ScenarioStep {
private final Customer node;
public ConsumeProductStep(Customer node) {
this.node = node;
}
@Override
void execute() {
node.consumeProduct();
}
}

View File

@ -1,38 +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;
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);
}
@Override
void execute() {
//todo maybe do a better error handling
try {
if (product != null) {
nodeBase.doAction(productOperationType, product);
}
else {
nodeBase.doAction(productOperationType);
}
}
catch (IllegalCallerException e) {
System.err.println(e.getMessage());
}
}
}

View File

@ -1,29 +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;
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;
System.err.println("Insufficient products in pool");
}
}
@Override
void execute() {
node.generateProduct(product);
}
}

View File

@ -1,7 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.scenario;
public class PassStep extends ScenarioStep {
@Override
void execute() {}
}

View File

@ -1,36 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.scenario;
import java.util.Iterator;
import java.util.List;
public class Scenario {
List<ScenarioStep> steps;
Iterator<ScenarioStep> stepIterator;
public Scenario() {
//steps = //TODO init
stepIterator = steps.listIterator(0);
}
public Scenario(List<ScenarioStep> steps) {
this.steps = steps;
stepIterator = steps.listIterator(0);
}
boolean execute() {
if (!stepIterator.hasNext()) {
// stepIterator = steps.listIterator(0);
return false;
}
stepIterator.next().execute();
return true;
}
public boolean tick() {
return execute();
}
public List<ScenarioStep> getSteps() {
return steps;
}
}

View File

@ -1,5 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.scenario;
public abstract class ScenarioStep {
abstract void execute();
}

View File

@ -1,44 +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;
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");
}
@Override
void execute() {
try {
node.createRequirement(tType, pType, pName, pPrice);
} catch (InsufficientResourcesException e) {
System.err.println(e.getMessage());
}
}
}

View File

@ -1,39 +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;
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;
}
}

View File

@ -1,17 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.signature;
import cz.cvut.fel.sit.omo.foodchain.operation.Transaction;
public class SignatureManager {
private static final String MANAGER_CODE = "iW91AJWNOCmX1pbpLlW0";
public static Signature signTransaction(Transaction transaction) {
return new Signature(MANAGER_CODE, 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));
}
}

View File

@ -1,8 +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;
public interface ChannelObserver {
void update(Requirement requirement, ChannelBase channel);
}

View File

@ -1,7 +0,0 @@
package cz.cvut.fel.sit.omo.foodchain.util;
public interface Observable {
void attach(ChannelObserver channelObserver);
void detach(ChannelObserver channelObserver);
void notifyAllObservers();
}

View File

@ -1,27 +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;
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);
}
}

View File

@ -1,33 +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.pool.PoolDatabase;
import cz.cvut.fel.sit.omo.foodchain.product.Product;
import cz.cvut.fel.sit.omo.foodchain.scenario.Scenario;
import javax.swing.*;
public class Ticker {
private static Timer timer;
public static void start() {
timer = new Timer(1000, actionEvent -> {
System.out.println("-----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();
}
public static void stop() {
timer.stop();
}
public static Timer getTimer() { return timer; }
}