Refactoring

This commit is contained in:
Tomáš Musil 2021-01-11 11:47:39 +01:00
parent b6a51a68d6
commit 1e745e6ad0
61 changed files with 375 additions and 438 deletions

2
.gitignore vendored
View File

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

View File

@ -183,28 +183,28 @@ Applied margin: 1.0
Product sold and purchased, action provided:
-----Product: jablko-----
Get jablko
Presence of product on Node (in ticks): 2
Presence of product on Node (in ticks): 6
-----Product: hruška-----
Get hruška
Presence of product on Node (in ticks): 4
Presence of product on Node (in ticks): 3
-----Product: banán-----
Get banán
Presence of product on Node (in ticks): 2
Presence of product on Node (in ticks): 1
-----Product: okurka-----
Get okurka
Presence of product on Node (in ticks): 2
Presence of product on Node (in ticks): 3
-----Product: paprika-----
Get paprika
Presence of product on Node (in ticks): 4
Presence of product on Node (in ticks): 1
-----Product: vepřové-----
Get vepřové
Presence of product on Node (in ticks): 4
Presence of product on Node (in ticks): 3
-----Product: hovězí-----
Get hovězí
Presence of product on Node (in ticks): 1
Presence of product on Node (in ticks): 3
-----Product: kuřecí-----
Get kuřecí
Presence of product on Node (in ticks): 2
Presence of product on Node (in ticks): 1
@ -464,7 +464,7 @@ ProductTransaction{product=banán, creator=Distributor, receiver=Customer}
FinancialTransaction{amount=23.4, transactionPaid=ProductTransaction{product=banán, creator=Distributor, receiver=Customer}}
Action{product=hovězí, type=GRILL_MEAT, duration=2, temperature=200}
Requirement{id=38, creator=Seller, transactionType=SALE, productName='jablko', TTL=5}
Customer consumed okurka VEGETABLE
Customer consumed banán FRUIT
-----tick-----
Processor accepted Requirement{id=35, creator=Seller, transactionType=PURCHASE, productName='paprika', TTL=4}
ProductTransaction{product=paprika, creator=Processor, receiver=Seller}
@ -477,7 +477,7 @@ FinancialTransaction{amount=13.65, transactionPaid=ProductTransaction{product=hr
Requirement{id=40, creator=Processor, transactionType=SALE, productName='rajče', TTL=5}
Action{product=paprika, type=WRAP_INTO_GIFT_PACKAGE, duration=1, temperature=21}
Requirement{id=41, creator=Distributor, transactionType=SALE, productName='hruška', TTL=5}
Customer consumed banán FRUIT
Customer consumed okurka VEGETABLE
-----tick-----
Seller accepted Requirement{id=40, creator=Processor, transactionType=SALE, productName='rajče', TTL=4}
Requirement{id=42, creator=Seller, transactionType=PURCHASE, productName='rajče', TTL=5}
@ -518,7 +518,7 @@ FinancialTransaction{amount=9.75, transactionPaid=ProductTransaction{product=pap
Requirement{id=52, creator=Processor, transactionType=SALE, productName='hovězí', TTL=5}
Requirement{id=53, creator=Seller, transactionType=SALE, productName='vepřové', TTL=5}
Requirement{id=54, creator=Distributor, transactionType=SALE, productName='paprika', TTL=5}
Customer consumed jablko FRUIT
Customer consumed hruška FRUIT
-----tick-----
Processor accepted Requirement{id=51, creator=Seller, transactionType=PURCHASE, productName='kuřecí', TTL=4}
ProductTransaction{product=kuřecí, creator=Processor, receiver=Seller}
@ -533,7 +533,7 @@ ProductTransaction{product=paprika, creator=Distributor, receiver=Customer}
FinancialTransaction{amount=39, transactionPaid=ProductTransaction{product=kuřecí, creator=Processor, receiver=Seller}}
FinancialTransaction{amount=11.7, transactionPaid=ProductTransaction{product=paprika, creator=Distributor, receiver=Customer}}
Action{product=kuřecí, type=WRAP_INTO_GIFT_PACKAGE, duration=1, temperature=21}
Customer consumed hruška FRUIT
Customer consumed paprika VEGETABLE
-----tick-----
Processor accepted Requirement{id=55, creator=Seller, transactionType=PURCHASE, productName='hovězí', TTL=4}
ProductTransaction{product=hovězí, creator=Processor, receiver=Seller}
@ -559,7 +559,7 @@ Distributor accepted Requirement{id=62, creator=Seller, transactionType=SALE, pr
Requirement{id=63, creator=Distributor, transactionType=PURCHASE, productName='kuřecí', TTL=5}
FinancialTransaction{amount=97.5, transactionPaid=ProductTransaction{product=hovězí, creator=Seller, receiver=Distributor}}
Requirement{id=64, creator=Distributor, transactionType=SALE, productName='hovězí', TTL=5}
Customer consumed paprika VEGETABLE
Customer consumed jablko FRUIT
-----tick-----
Customer accepted Requirement{id=64, creator=Distributor, transactionType=SALE, productName='hovězí', TTL=4}
Requirement{id=65, creator=Customer, transactionType=PURCHASE, productName='hovězí', TTL=5}
@ -570,14 +570,14 @@ ProductTransaction{product=hovězí, creator=Distributor, receiver=Customer}
FinancialTransaction{amount=58.5, transactionPaid=ProductTransaction{product=kuřecí, creator=Seller, receiver=Distributor}}
FinancialTransaction{amount=117, transactionPaid=ProductTransaction{product=hovězí, creator=Distributor, receiver=Customer}}
Requirement{id=66, creator=Distributor, transactionType=SALE, productName='kuřecí', TTL=5}
Customer consumed hovězí MEAT
Customer consumed vepřové MEAT
-----tick-----
Customer accepted Requirement{id=66, creator=Distributor, transactionType=SALE, productName='kuřecí', TTL=4}
Requirement{id=67, creator=Customer, transactionType=PURCHASE, productName='kuřecí', TTL=5}
Distributor accepted Requirement{id=67, creator=Customer, transactionType=PURCHASE, productName='kuřecí', TTL=5}
ProductTransaction{product=kuřecí, creator=Distributor, receiver=Customer}
FinancialTransaction{amount=70.2, transactionPaid=ProductTransaction{product=kuřecí, creator=Distributor, receiver=Customer}}
Customer consumed vepřové MEAT
-----tick-----
Customer consumed kuřecí MEAT
-----tick-----
Customer consumed hovězí MEAT
-----tick-----

View File

@ -20,76 +20,64 @@ import java.util.logging.LogManager;
import java.util.logging.Logger;
/**
* Main application class
* Main application class.
*/
public class FoodChain
{
public class FoodChain {
private static FactoryManager factoryManager = new FactoryManager();
private static final FactoryManager factoryManager = new FactoryManager();
/**
* Main application method that parses configuration and starts Ticker.
*
* @param args args
*/
public static void main(String[] args)
{
public static void main(String[] args) {
LogManager.getLogManager().reset();
Logger rootLogger = LogManager.getLogManager().getLogger("");
rootLogger.addHandler(new ReportLogger());
if(args.length < 1)
{
if (args.length < 1) {
parseChannels("conf/channels.xml");
parseNodes("conf/nodes.xml");
parseProducts("conf/products.xml");
parseScenarios("conf/scenarios.xml");
// rootLogger.log(Level.INFO,"Parsed default scenarios");
}
else if (args.length < 2)
{
} else if (args.length < 2) {
parseChannels("conf/channels.xml");
parseNodes("conf/nodes.xml");
parseProducts("conf/products.xml");
parseScenarios(args[0]);
// rootLogger.log(Level.INFO,"Parsed non-default scenarios");
}
else
{
} else {
parseChannels(args[1]);
parseNodes(args[2]);
parseProducts(args[3]);
parseScenarios(args[4]);
// rootLogger.log(Level.INFO,"Parsed non-default scenarios");
}
Ticker.start();
while (Ticker.getTimer().isRunning()) {}
while (Ticker.getTimer().isRunning()) {
}
ReportingManager reportingManager = new ReportingManager();
reportingManager.createFileTextReport("reports.txt");
reportingManager.createFileTextReport("reports/reports.txt");
}
public static FactoryManager getFactoryManager() { return factoryManager; }
public static FactoryManager getFactoryManager() {
return factoryManager;
}
/**
* Provides connection between FoodChain and ConfigurationParser.
* @param path file path
*
* @param path file path
* @param rootElementTag tag to be parsed
* @return parser result
*/
private static ParserResult parseDocument(String path, String rootElementTag)
{
try
{
private static ParserResult parseDocument(String path, String rootElementTag) {
try {
ConfigurationParser.parseDocument(path);
}
catch (ParserConfigurationException | SAXException | IOException e)
{
} catch (ParserConfigurationException | SAXException | IOException e) {
System.err.println(e.getMessage());
}
@ -99,14 +87,13 @@ public class FoodChain
/**
* Parses channels.
*
* @param path file path
*/
private static void parseChannels(String path)
{
private static void parseChannels(String path) {
ParserResult parserResult = parseDocument(path, "channel");
List<ParserResultElement> elements = parserResult.getElements();
for (ParserResultElement el : elements)
{
for (ParserResultElement el : elements) {
ChannelBase res = getFactoryManager().getChannelFactoryInstance().makeChannel(el);
getFactoryManager().getPoolDatabaseInstance().getChannelPoolInstance().add(res);
}
@ -114,14 +101,13 @@ public class FoodChain
/**
* Parses nodes.
*
* @param path file path
*/
private static void parseNodes(String path)
{
private static void parseNodes(String path) {
ParserResult parserResult = parseDocument(path, "node");
List<ParserResultElement> elements = parserResult.getElements();
for (ParserResultElement el : elements)
{
for (ParserResultElement el : elements) {
NodeBase res = getFactoryManager().getNodeFactoryInstance().makeNode(el);
getFactoryManager().getPoolDatabaseInstance().getNodePoolInstance().add(res);
}
@ -129,14 +115,13 @@ public class FoodChain
/**
* Parses products.
*
* @param path file path
*/
private static void parseProducts(String path)
{
private static void parseProducts(String path) {
ParserResult parserResult = parseDocument(path, "product");
List<ParserResultElement> elements = parserResult.getElements();
for (ParserResultElement el : elements)
{
for (ParserResultElement el : elements) {
Product res = getFactoryManager().getProductFactoryInstance().makeProduct(el);
getFactoryManager().getPoolDatabaseInstance().getProductPoolInstance().add(res);
}
@ -144,14 +129,13 @@ public class FoodChain
/**
* Parses scenarios.
*
* @param path file path
*/
private static void parseScenarios(String path)
{
private static void parseScenarios(String path) {
ParserResult parserResult = parseDocument(path, "scenario");
List<ParserResultElement> elements = parserResult.getElements();
for (ParserResultElement el : elements)
{
for (ParserResultElement el : elements) {
Scenario res = getFactoryManager().getScenarioFactoryInstance().makeScenario(el);
getFactoryManager().getPoolDatabaseInstance().getScenarioPoolInstance().add(res);
}

View File

@ -15,59 +15,57 @@ import java.util.Set;
import java.util.stream.Collectors;
/**
* Base class for all channels
* 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;
private final Set<ChannelObserver> subscribers;
public ChannelBase(ProductType type)
{
public ChannelBase(ProductType type) {
this.requirements = new LinkedList<>();
this.transactions = new LinkedList<>();
this.subscribers = new HashSet<>();
this.productType = type;
}
public ChannelBase()
{
public ChannelBase() {
this.requirements = new LinkedList<>();
this.transactions = new LinkedList<>();
this.subscribers = new HashSet<>();
this.productType = ProductType.OTHER;
}
public Queue<Transaction> getTransactions(NodeBase node)
{
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()
{
public Queue<Requirement> getCurrentRequirements() {
return this.requirements;
}
/**
* Adds new requirement to the requirement Queue.
*
* @param requirement requirement
*/
public void addRequirement(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) {}
} catch (Exception ignored) {
}
requirements = requirements.stream().filter(r -> r.getTTL() > 0).collect(Collectors.toCollection(LinkedList::new));
notifyAllObservers();
return requirements.size() != 0;
@ -77,56 +75,65 @@ public abstract class ChannelBase implements Observable {
* Notifies all nodes apart from creator about a requirement.
*/
@Override
public void notifyAllObservers(){
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){
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); }
public void detach(ChannelObserver observer) {
subscribers.remove(observer);
}
/**
* Adds new transaction to the transaction Queue.
*
* @param transaction transaction
*/
public void addTransaction(Transaction transaction)
{
public void addTransaction(Transaction transaction) {
this.transactions.add(transaction);
try {
((ProductTransaction) transaction).getProduct().setStateToInTransit();
} catch (Exception ignored) {
}
catch (Exception ignored) {}
}
/**
* Removes requirement from list of active requirements.
*
* @param requirement requirement
*/
public void disposeOf(Requirement requirement) { this.requirements.remove(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); }
public void disposeOf(Transaction transaction) {
this.transactions.remove(transaction);
}
/**
* Clears all active requirements from this channel.
*/
public void clearRequirements()
{
public void clearRequirements() {
this.requirements.clear();
}

View File

@ -1,7 +1,7 @@
package cz.cvut.fel.sit.omo.foodchain.channel;
/**
* Enum class for different subscription types
* Enum class for different subscription types.
*/
public enum ChannelSubscriptionType {

View File

@ -3,12 +3,10 @@ package cz.cvut.fel.sit.omo.foodchain.channel;
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
/**
* Channel for transporting fruit
* Channel for transporting fruit.
*/
public class FruitChannel extends ChannelBase
{
public FruitChannel()
{
public class FruitChannel extends ChannelBase {
public FruitChannel() {
super(ProductType.FRUIT);
}
}

View File

@ -3,12 +3,10 @@ package cz.cvut.fel.sit.omo.foodchain.channel;
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
/**
* Channel for transporting meat
* Channel for transporting meat.
*/
public class MeatChannel extends ChannelBase
{
public MeatChannel()
{
public class MeatChannel extends ChannelBase {
public MeatChannel() {
super(ProductType.MEAT);
}
}

View File

@ -1,12 +1,10 @@
package cz.cvut.fel.sit.omo.foodchain.channel;
/**
* Channel for transporting other products
* Channel for transporting other products.
*/
public class OtherChannel extends ChannelBase
{
public OtherChannel()
{
public class OtherChannel extends ChannelBase {
public OtherChannel() {
super();
}
}

View File

@ -3,12 +3,10 @@ package cz.cvut.fel.sit.omo.foodchain.channel;
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
/**
* Channel for transporting vegetable
* Channel for transporting vegetable.
*/
public class VegetableChannel extends ChannelBase
{
public VegetableChannel()
{
public class VegetableChannel extends ChannelBase {
public VegetableChannel() {
super(ProductType.VEGETABLE);
}
}

View File

@ -9,31 +9,26 @@ import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Factory for creating channels
* Factory for creating channels.
*/
public class ChannelFactory
{
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)
{
public ChannelBase makeChannel(ParserResultElement input) {
ChannelBase c = null;
try
{
try {
ProductType channelType = ProductType.valueOf(input.getAttribute("type"));
c = makeChannelFromChannelType(channelType);
}
catch (IllegalArgumentException e)
{
} catch (IllegalArgumentException e) {
LOGGER.log(Level.SEVERE, "! Wrong type of enum in ChannelFactory: " + e);
}
catch (Exception e)
{
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "! Fatal error in ChannelFactory: " + e);
}
return c;
@ -41,13 +36,12 @@ public class ChannelFactory
/**
* 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)
{
private ChannelBase makeChannelFromChannelType(ProductType typeOfChannel) {
switch (typeOfChannel) {
case FRUIT:
return new FruitChannel();
case VEGETABLE:

View File

@ -6,70 +6,49 @@ import cz.cvut.fel.sit.omo.foodchain.util.Singleton;
import java.lang.reflect.InvocationTargetException;
/**
* Manager class for all factories and pool database
* Manager class for all factories and pool database.
*/
public class FactoryManager
{
public NodeFactory getNodeFactoryInstance()
{
try
{
public class FactoryManager {
public NodeFactory getNodeFactoryInstance() {
try {
return Singleton.getInstance(NodeFactory.class);
}
catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e)
{
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
public ChannelFactory getChannelFactoryInstance()
{
try
{
public ChannelFactory getChannelFactoryInstance() {
try {
return Singleton.getInstance(ChannelFactory.class);
}
catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e)
{
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
public ScenarioFactory getScenarioFactoryInstance()
{
try
{
public ScenarioFactory getScenarioFactoryInstance() {
try {
return Singleton.getInstance(ScenarioFactory.class);
}
catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e)
{
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
public ProductFactory getProductFactoryInstance()
{
try
{
public ProductFactory getProductFactoryInstance() {
try {
return Singleton.getInstance(ProductFactory.class);
}
catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e)
{
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
public PoolDatabase getPoolDatabaseInstance()
{
try
{
public PoolDatabase getPoolDatabaseInstance() {
try {
return Singleton.getInstance(PoolDatabase.class);
}
catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e)
{
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
return null;

View File

@ -12,18 +12,18 @@ import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Factory for creating nodes
* Factory for creating nodes.
*/
public class NodeFactory
{
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)
{
public NodeBase makeNode(ParserResultElement input) {
NodeBase n = null;
NodeType nodeType = null;
String subsChannels = "";
@ -31,26 +31,20 @@ public class NodeFactory
double margin = 0;
double acceptableDiscount = 0;
try
{
try {
nodeType = NodeType.valueOf(input.getAttribute("type"));
subsChannels = input.getChild("channels");
startMoney = Double.parseDouble(input.getChild("money"));
margin = Double.parseDouble(input.getChild("margin"));
acceptableDiscount = Double.parseDouble(input.getChild("discount"));
}
catch (IllegalArgumentException e)
{
} catch (IllegalArgumentException e) {
LOGGER.log(Level.SEVERE, "! Wrong type of enum in NodeFactory: " + e.getMessage());
}
catch (Exception e)
{
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "! Fatal error in NodeFactory: " + e.getMessage());
}
switch (Objects.requireNonNull(nodeType))
{
switch (Objects.requireNonNull(nodeType)) {
case Farmer:
n = new Farmer(startMoney, margin, acceptableDiscount);
break;
@ -69,11 +63,9 @@ public class NodeFactory
default:
}
if (n != null)
{
if (n != null) {
String[] subs = subsChannels.split(";");
for (String s : subs)
{
for (String s : subs) {
String[] el = s.split(" ");
ChannelPool temp = FoodChain.getFactoryManager().getPoolDatabaseInstance().getChannelPoolInstance();

View File

@ -9,22 +9,20 @@ import java.util.logging.Logger;
/**
* Factory for creating products
* Factory for creating products.
*/
public class ProductFactory
{
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)
{
public Product makeProduct(ParserResultElement input) {
Product p = null;
try
{
try {
String name = input.getChild("name");
ProductType productType = ProductType.valueOf(input.getChild("type"));
//ProductState productState = ProductState.valueOf(input.getChild("state"));
@ -32,13 +30,9 @@ public class ProductFactory
//p = new Product(name, price, productType, productState);
p = new Product(name, productType, price);
}
catch (IllegalArgumentException e)
{
} catch (IllegalArgumentException e) {
LOGGER.log(Level.SEVERE, "! Wrong type of enum in ProductFactory: " + e.getMessage());
}
catch (Exception e)
{
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "! Fatal error in ProductFactory: " + e.getMessage());
}
return p;

View File

@ -17,23 +17,22 @@ import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Factory for creating scenarios
* Factory for creating scenarios.
*/
public class ScenarioFactory
{
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)
{
public Scenario makeScenario(ParserResultElement input) {
Scenario s = null;
NodeBase node = null;
try
{
try {
String nodeType = input.getAttribute("type");
node = FoodChain.getFactoryManager().getPoolDatabaseInstance().getNodePoolInstance().findAll().stream()
.filter(ch -> ch.getClass().getSimpleName().equals(nodeType)).findFirst().orElse(null);
@ -41,11 +40,9 @@ public class ScenarioFactory
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)
{
for (String step : steps) {
String[] parts = step.strip().split(" ");
switch (parts[0])
{
switch (parts[0]) {
case "generate":
scenarioStep = new GenerateProductStep((Farmer) node);
break;
@ -53,12 +50,9 @@ public class ScenarioFactory
scenarioStep = new ConsumeProductStep((Customer) node);
break;
case "doaction":
if (parts.length == 2)
{
if (parts.length == 2) {
scenarioStep = new DoActionStep(node, ProductOperationType.valueOf(parts[1]));
}
else
{
} else {
scenarioStep = new DoActionStep(node, ProductOperationType.valueOf(parts[1]), parts[2]);
}
break;
@ -75,9 +69,7 @@ public class ScenarioFactory
scenarioSteps.add(scenarioStep);
}
s = new Scenario(scenarioSteps);
}
catch (IllegalArgumentException e)
{
} catch (IllegalArgumentException e) {
LOGGER.log(Level.SEVERE, "! Wrong type of enum in ScenarioFactory: " + e.getMessage());
}

View File

@ -6,7 +6,7 @@ import java.util.Random;
import java.util.logging.Level;
/**
* Customer node
* Customer node.
*/
public class Customer extends NodeBase {
@ -18,8 +18,7 @@ public class Customer extends NodeBase {
}
public void consumeProduct() {
if(getStorage().getNumberOfStoredProducts() == 0)
{
if (getStorage().getNumberOfStoredProducts() == 0) {
LOGGER.log(Level.WARNING, this.nodeType + " tried to consume non existing product.");
return;
}

View File

@ -1,7 +1,7 @@
package cz.cvut.fel.sit.omo.foodchain.node;
/**
* Distributor node
* Distributor node.
*/
public class Distributor extends NodeBase {

View File

@ -7,7 +7,7 @@ import javax.naming.InsufficientResourcesException;
import java.util.logging.Level;
/**
* Farmer node
* Farmer node.
*/
public class Farmer extends NodeBase {

View File

@ -24,23 +24,20 @@ import java.util.logging.Logger;
/**
* Base class for all nodes
* Base class for all nodes.
*/
public class NodeBase implements ChannelObserver {
protected static final Logger LOGGER = Logger.getLogger(NodeBase.class.getName());
protected final Storage storage;
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;
private final double margin;
private final double acceptableDiscount;
protected final Storage storage;
protected NodeType nodeType;
protected NodeType allowedSeller;
protected NodeType allowedPurchaser;
private MonetaryAmount money;
public NodeBase() {
this.nodeType = NodeType.None;
@ -141,7 +138,7 @@ public class NodeBase implements ChannelObserver {
/**
* Adds transaction to refused transactions.
*
* @param transaction
* @param transaction transaction
*/
private void refuseTransaction(Transaction transaction) {
transaction.endTransaction();
@ -220,22 +217,11 @@ public class NodeBase implements ChannelObserver {
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 name product to proceed
* @param action type of product operation to do
* @param name product to proceed
*/
public void doAction(ProductOperationType action, String name) throws IllegalCallerException, InsufficientResourcesException {
this.storage.doAction(action, name);
@ -271,7 +257,9 @@ public class NodeBase implements ChannelObserver {
return refusedTransactions;
}
public List<RefusedRequirement> getRefusedRequirements() { return refusedRequirements; }
public List<RefusedRequirement> getRefusedRequirements() {
return refusedRequirements;
}
public NodeType getAllowedSeller() {
return allowedSeller;
@ -281,12 +269,16 @@ public class NodeBase implements ChannelObserver {
return allowedPurchaser;
}
public double getMargin() { return margin; }
public double getMargin() {
return margin;
}
public double getAcceptableDiscount() { return acceptableDiscount; }
public double getAcceptableDiscount() {
return acceptableDiscount;
}
/**
* Adds amount to current assets
* Adds amount to current assets.
*
* @param m amount to be added
*/
@ -349,7 +341,7 @@ public class NodeBase implements ChannelObserver {
}
/**
* Chacks if product is available or if node has enough money
* Checks if product is available or if node has enough money.
*
* @param req requirement
* @return product is available or node has enough money

View File

@ -1,7 +1,7 @@
package cz.cvut.fel.sit.omo.foodchain.node;
/**
* Enum class for all nodes
* Enum class for all nodes.
*/
public enum NodeType {
Farmer, Processor, Distributor, Seller, Customer, None, All

View File

@ -1,7 +1,7 @@
package cz.cvut.fel.sit.omo.foodchain.node;
/**
* Processor node
* Processor node.
*/
public class Processor extends NodeBase {

View File

@ -1,7 +1,7 @@
package cz.cvut.fel.sit.omo.foodchain.node;
/**
* Seller node
* Seller node.
*/
public class Seller extends NodeBase {

View File

@ -9,107 +9,97 @@ import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
import javax.naming.InsufficientResourcesException;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
/**
* Storage sub-node for storing products of other nodes
* Storage sub-node for storing products of other nodes.
*/
public class Storage
{
public class Storage {
private final NodeBase storageOwner;
private final List<Product> products = new LinkedList<>();
private final List<ProductCache> cache = new LinkedList<>();
public Storage(NodeBase owner)
{
public Storage(NodeBase owner) {
this.storageOwner = owner;
}
/**
* Adds provided product into the storage.
* @param product
*
* @param product product to be stored
*/
public void storeProduct(Product product)
{
public void storeProduct(Product product) {
this.products.add(product);
this.cache.add(new ProductCache(product.getName(), product.getProductType()));
}
/**
* Adds all of the provided products into the storage.
* @param products
*/
public void storeProducts(List<Product> products)
{
this.products.addAll(products);
this.cache.addAll(products.stream().map(p -> new ProductCache(p.getName(), p.getProductType())).collect(Collectors.toList()));
}
/**
* 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)
{
public Product getProduct(String name, ProductType type) {
return products.stream().filter(ch -> (ch.getProductType().equals(type) || type.equals(ProductType.ALL)) && ch.getName().equals(name)).findFirst().orElse(null);
}
public List<Product> getProducts()
{
public List<Product> getProducts() {
return products;
}
public List<ProductCache> getCache() { return cache; }
public List<ProductCache> getCache() {
return cache;
}
/**
* Returns number of products in storage.
* @return
*
* @return number of products in storage
*/
public int getNumberOfStoredProducts()
{
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)
{
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;
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)
{
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 action type of product operation to do
* @param productName product to process
*/
public void doAction(ProductOperationType action, String productName) throws IllegalCallerException, InsufficientResourcesException {
if (!containsProduct(productName, action.getProductType())) throw new InsufficientResourcesException(storageOwner.getClass().getSimpleName() + " tried to do action " + action.toString() + " to unavailable product " + productName);
if (!containsProduct(productName, action.getProductType()))
throw new InsufficientResourcesException(storageOwner.getClass().getSimpleName() + " tried to do action " + action.toString() + " to unavailable product " + productName);
Product product = getProduct(productName, action.getProductType());
if (action.getNode().equals(this.storageOwner.getNodeType()) || action.getNode().equals(NodeType.All))
if (action.getProductType().equals(product.getProductType()) || action.getProductType().equals(ProductType.ALL))
@ -122,10 +112,10 @@ public class Storage
/**
* Calls specific ProductOperation on each product in stock.
*
* @param action ProductOperationType
*/
public void doAction(ProductOperationType action)
{
public void doAction(ProductOperationType action) {
this.products.forEach(t -> new Action(this.storageOwner, t, action));
}

View File

@ -3,7 +3,7 @@ package cz.cvut.fel.sit.omo.foodchain.node.helper;
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
/**
* Model for product in Storage for saving ticks in Node
* Model for product in Storage for saving ticks in Node.
*/
public class ProductCache {
private final String name;
@ -16,11 +16,19 @@ public class ProductCache {
this.duration = 0;
}
public String getName() { return name; }
public String getName() {
return name;
}
public ProductType getType() { return type; }
public ProductType getType() {
return type;
}
public int getDuration() { return duration; }
public int getDuration() {
return duration;
}
public void addToDuration() { duration++; }
public void addToDuration() {
duration++;
}
}

View File

@ -6,7 +6,7 @@ import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
import javax.money.MonetaryAmount;
/**
* Model for saving Requirements, that was used in double spending
* Model for saving Requirements, that was used in double spending.
*/
public class RefusedRequirement {
@ -22,13 +22,21 @@ public class RefusedRequirement {
this.price = price;
}
public TransactionType getTransactionType() { return transactionType; }
public TransactionType getTransactionType() {
return transactionType;
}
public ProductType getProductType() { return productType; }
public ProductType getProductType() {
return productType;
}
public String getProductName() { return productName; }
public String getProductName() {
return productName;
}
public MonetaryAmount getPrice() { return price; }
public MonetaryAmount getPrice() {
return price;
}
@Override
public String toString() {

View File

@ -7,7 +7,7 @@ import cz.cvut.fel.sit.omo.foodchain.reporting.ReportTextVisitor;
import java.util.logging.Level;
/**
* Operation for processing products in storage
* Operation for processing products in storage.
*/
public class Action extends OperationBase {
private final Product product;
@ -35,6 +35,7 @@ public class Action extends OperationBase {
/**
* Changes actions duration or ends action.
*
* @return action is in progress
*/
public boolean tick() {

View File

@ -8,7 +8,7 @@ import javax.naming.InsufficientResourcesException;
import java.util.logging.Level;
/**
* Operation for transporting money
* Operation for transporting money.
*/
public class FinancialTransaction extends Transaction {

View File

@ -7,17 +7,16 @@ import java.time.LocalDateTime;
import java.util.logging.Logger;
/**
* Base class for all operations
* 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;
private LocalDateTime timeEnd;
OperationBase(NodeBase node, OperationBase lastOperation) {
nodeCreator = node;
@ -45,7 +44,7 @@ public abstract class OperationBase {
return lastOperation;
}
public String accept(ReportTextVisitor reportVisitor){
public String accept(ReportTextVisitor reportVisitor) {
return reportVisitor.visit(this);
}
}

View File

@ -4,10 +4,9 @@ import cz.cvut.fel.sit.omo.foodchain.node.NodeType;
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
/**
* Enum class for product operations types with parameters
* Enum class for product operations types with parameters.
*/
public enum ProductOperationType
{
public enum ProductOperationType {
STORE_MEAT(NodeType.All, ProductType.MEAT, 3, -8),
STORE_FRUIT(NodeType.All, ProductType.FRUIT, 3, 2),
STORE_VEGETABLE(NodeType.All, ProductType.VEGETABLE, 3, 2),
@ -30,28 +29,26 @@ public enum ProductOperationType
private final int duration;
private final int temperature;
ProductOperationType(NodeType node, ProductType product, int duration, int temperature)
{
ProductOperationType(NodeType node, ProductType product, int duration, int temperature) {
this.node = node;
this.productType = product;
this.duration = duration;
this.temperature = temperature;
}
public int getDuration()
{
public int getDuration() {
return duration;
}
public int getTemperature()
{
public int getTemperature() {
return temperature;
}
public NodeType getNode()
{
public NodeType getNode() {
return node;
}
public ProductType getProductType() { return productType; }
public ProductType getProductType() {
return productType;
}
}

View File

@ -9,7 +9,7 @@ import javax.naming.InsufficientResourcesException;
import java.util.logging.Level;
/**
* Operation for transporting products
* Operation for transporting products.
*/
public class ProductTransaction extends Transaction {
@ -20,7 +20,8 @@ public class ProductTransaction extends Transaction {
super(creator, receiver, transactionType, product.getCurrentOperation());
this.product = product;
type = null;
if (product == null || product.getProductState() != ProductState.IN_REQUIREMENT) throw new InsufficientResourcesException(creator.getClass().getSimpleName() + " tried to sell unavailable product " + product.getName() + " to " + receiver.getClass().getSimpleName());
if (product == null || product.getProductState() != ProductState.IN_REQUIREMENT)
throw new InsufficientResourcesException(creator.getClass().getSimpleName() + " tried to sell unavailable product " + product.getName() + " to " + receiver.getClass().getSimpleName());
product.setCurrentOperation(this);
product.setStateToReadyForDispatch();
creator.getStorage().removeProduct(product);
@ -50,8 +51,8 @@ public class ProductTransaction extends Transaction {
public String toString() {
return "ProductTransaction{" +
"product=" + product.getName() +
", creator="+this.getNodeCreator().getNodeType() +
", receiver="+this.getNodeReceiver().getNodeType() + "}";
", creator=" + this.getNodeCreator().getNodeType() +
", receiver=" + this.getNodeReceiver().getNodeType() + "}";
}
@Override

View File

@ -6,7 +6,7 @@ import cz.cvut.fel.sit.omo.foodchain.signature.Signature;
import cz.cvut.fel.sit.omo.foodchain.signature.SignatureManager;
/**
* Operation for transporting things between nodes
* Operation for transporting things between nodes.
*/
public abstract class Transaction extends OperationBase {

View File

@ -1,7 +1,7 @@
package cz.cvut.fel.sit.omo.foodchain.operation;
/**
* Enum class for transaction types
* Enum class for transaction types.
*/
public enum TransactionType {

View File

@ -12,7 +12,7 @@ import java.io.File;
import java.io.IOException;
/**
* Parser for XML configuration
* Parser for XML configuration.
*/
public class ConfigurationParser {
@ -20,10 +20,11 @@ public class ConfigurationParser {
/**
* Parses xml file to document.
*
* @param name file name
* @throws ParserConfigurationException ParserConfigurationException
* @throws IOException IOException
* @throws SAXException SAXException
* @throws IOException IOException
* @throws SAXException SAXException
*/
public static void parseDocument(String name) throws ParserConfigurationException, IOException, SAXException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
@ -36,6 +37,7 @@ public class ConfigurationParser {
/**
* Returns parsed result with all elements having provided tag.
*
* @param tag element tag
* @return parsed result element
*/
@ -49,9 +51,9 @@ public class ConfigurationParser {
element
.addAttribute(
tmpNode
.getAttributes()
.item(j)
.getNodeName(),
.getAttributes()
.item(j)
.getNodeName(),
tmpNode
.getAttributes()
.item(j)

View File

@ -4,7 +4,7 @@ import java.util.LinkedList;
import java.util.List;
/**
* Wrapper class for parser result elements
* Wrapper class for parser result elements.
*/
public class ParserResult {
@ -16,6 +16,7 @@ public class ParserResult {
/**
* Adds element to list.
*
* @param element element
*/
public void addElement(ParserResultElement element) {

View File

@ -4,7 +4,7 @@ import java.util.HashMap;
import java.util.Map;
/**
* Class for storing all information given in a xml tag
* Class for storing all information given in a xml tag.
*/
public class ParserResultElement {

View File

@ -4,12 +4,13 @@ import cz.cvut.fel.sit.omo.foodchain.channel.ChannelBase;
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
/**
* Pool for storing all channels
* Pool for storing all channels.
*/
public class ChannelPool extends PoolListBase<ChannelBase> {
/**
* Finds channel by its type.
*
* @param type type of channel
* @return channel
*/

View File

@ -3,7 +3,7 @@ package cz.cvut.fel.sit.omo.foodchain.pool;
import cz.cvut.fel.sit.omo.foodchain.node.NodeBase;
/**
*Pool for storing all nodes
* Pool for storing all nodes.
*/
public class NodePool extends PoolListBase<NodeBase> {
}

View File

@ -5,7 +5,7 @@ import cz.cvut.fel.sit.omo.foodchain.util.Singleton;
import java.lang.reflect.InvocationTargetException;
/**
* Database class for storing all pools
* Database class for storing all pools.
*/
public class PoolDatabase {

View File

@ -4,7 +4,8 @@ import java.util.LinkedList;
import java.util.List;
/**
* Base class for all pools
* Base class for all pools.
*
* @param <T> pool type
*/
public abstract class PoolListBase<T> {

View File

@ -3,7 +3,7 @@ package cz.cvut.fel.sit.omo.foodchain.pool;
import cz.cvut.fel.sit.omo.foodchain.product.Product;
/**
* Pool for storing all products
* Pool for storing all products.
*/
public class ProductPool extends PoolListBase<Product> {
}

View File

@ -3,7 +3,7 @@ package cz.cvut.fel.sit.omo.foodchain.pool;
import cz.cvut.fel.sit.omo.foodchain.scenario.Scenario;
/**
* Pool for storing all scenarios
* Pool for storing all scenarios.
*/
public class ScenarioPool extends PoolListBase<Scenario> {
}

View File

@ -11,36 +11,33 @@ import java.util.LinkedList;
import java.util.List;
/**
* Product class
* Product class.
*/
public class Product
{
public class Product {
private final MonetaryAmount startPrice;
private ProductState productState;
private ProductType productType;
private OperationBase currentOperation;
private MonetaryAmount price;
private final MonetaryAmount startPrice;
private String name;
public Product(String name, ProductType productType, double m)
{
public Product(String name, ProductType productType, double m) {
this.name = name;
this.productType = productType;
this.productType = productType;
this.productState = ProductState.AVAILABLE;
this.price = Money.of(m, "USD");
this.startPrice = Money.of(m, "USD");
}
/**
* Passes tick onto current operation
* Passes tick onto current operation.
*
* @return operation is active
*/
public boolean tick() {
try {
return ((Action) currentOperation).tick();
}
catch (Exception e) {
} catch (Exception e) {
return false;
}
}
@ -50,8 +47,7 @@ public class Product
/**
* Set current product state to AVAILABLE. Throws IllegalStateException if the product is not IN_ACTION, READY_FOR_RECEPTION or IN_REQUIREMENT.
*/
public void setStateToAvailable()
{
public void setStateToAvailable() {
if (this.productState.equals(ProductState.IN_ACTION) ||
this.productState.equals(ProductState.READY_FOR_RECEPTION) ||
this.productState.equals(ProductState.IN_REQUIREMENT))
@ -63,9 +59,8 @@ public class Product
/**
* 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))
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!");
@ -74,9 +69,8 @@ public class Product
/**
* 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))
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!");
@ -85,9 +79,8 @@ public class Product
/**
* 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))
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!");
@ -96,9 +89,8 @@ public class Product
/**
* Set current product state to IN_ACTION. Throws IllegalStateException if the product is not AVAILABLE.
*/
public void setStateToInAction()
{
if(this.productState.equals(ProductState.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!");
@ -107,9 +99,8 @@ public class Product
/**
* Set current product state to IN_REQUIREMENT. Throws IllegalStateException if the product is not AVAILABLE.
*/
public void setStateToInRequirement()
{
if(this.productState.equals(ProductState.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!");
@ -117,48 +108,47 @@ public class Product
//Getters & Setters
public ProductState getProductState()
{
public ProductState getProductState() {
return productState;
}
public ProductType getProductType()
{
public ProductType getProductType() {
return productType;
}
public void setProductType(ProductType productType)
{
public void setProductType(ProductType productType) {
this.productType = productType;
}
public String getName()
{
public String getName() {
return name;
}
public void setName(String name)
{
public void setName(String name) {
this.name = name;
}
public OperationBase getCurrentOperation()
{
public OperationBase getCurrentOperation() {
return currentOperation;
}
public void setCurrentOperation(OperationBase currentOperation)
{
public void setCurrentOperation(OperationBase currentOperation) {
this.currentOperation = currentOperation;
}
public MonetaryAmount getPrice() { return price; }
public MonetaryAmount getPrice() {
return price;
}
public void setPrice(MonetaryAmount price) { this.price = price; }
public void setPrice(MonetaryAmount price) {
this.price = price;
}
public MonetaryAmount getStartPrice() { return startPrice; }
public MonetaryAmount getStartPrice() {
return startPrice;
}
public List<OperationBase> getListOfOperations(){
public List<OperationBase> getListOfOperations() {
OperationBase operation = this.getCurrentOperation();
List<OperationBase> operations = new LinkedList<>();
@ -171,7 +161,7 @@ public class Product
return operations;
}
public String accept(ReportTextVisitor visitor){
public String accept(ReportTextVisitor visitor) {
return visitor.visit(this);
}
}

View File

@ -1,9 +1,8 @@
package cz.cvut.fel.sit.omo.foodchain.product;
/**
* Enum class for product states
* Enum class for product states.
*/
public enum ProductState
{
public enum ProductState {
AVAILABLE, READY_FOR_DISPATCH, IN_TRANSIT, READY_FOR_RECEPTION, IN_ACTION, IN_REQUIREMENT
}

View File

@ -1,9 +1,8 @@
package cz.cvut.fel.sit.omo.foodchain.product;
/**
* Enum class for product types
* Enum class for product types.
*/
public enum ProductType
{
public enum ProductType {
MEAT, FRUIT, VEGETABLE, OTHER, ALL // ALL is used only for actions
}

View File

@ -10,42 +10,47 @@ import cz.cvut.fel.sit.omo.foodchain.pool.PoolDatabase;
import cz.cvut.fel.sit.omo.foodchain.product.Product;
/**
* Report visitor class for generating reports
* Report visitor class for generating reports.
*/
public interface ReportTextVisitor {
String ln = System.lineSeparator();
PoolDatabase db = FoodChain.getFactoryManager().getPoolDatabaseInstance();
/**
* Checks node and generate report based on information in node
* Checks node and generate report based on information in node.
*
* @param node Node to generate report
* @return Report in String
*/
String visit(NodeBase node);
/**
* Checks product and generate report based on information in product
* Checks product and generate report based on information in product.
*
* @param product Product to generate report
* @return Report in String
*/
String visit(Product product);
/**
* Checks product transaction and generate report based on information in transaction
* Checks product transaction and generate report based on information in transaction.
*
* @param transaction Transaction to generate report
* @return Report in String
*/
String visit(ProductTransaction transaction);
/**
* Checks action and generate report based on information in action
* Checks action and generate report based on information in action.
*
* @param action Action to generate report
* @return Report in String
*/
String visit(Action action);
/**
* Casts OperationBase to useful type to report
* Casts OperationBase to useful type to report.
*
* @param operationBase Base of Action or Transaction
* @return Report in String
*/
@ -58,7 +63,8 @@ public interface ReportTextVisitor {
}
/**
* Casts Transaction to useful type to report
* Casts Transaction to useful type to report.
*
* @param transaction Base of produc or financial t transaction
* @return Report in String
*/

View File

@ -11,6 +11,7 @@ public class ReportingManager {
/**
* Create new file (or overwrite existing) in this pathname
*
* @param pathname Relative pathname of File
*/
public void createFileTextReport(String pathname) {
@ -26,9 +27,10 @@ public class ReportingManager {
/**
* Configure reports and their order in String
*
* @return Report string with all reports
*/
public String generateReport(){
public String generateReport() {
ReportBuilder reportBuilder = new ReportBuilder();
return reportBuilder

View File

@ -36,6 +36,8 @@ public class SecurityReportVisitor implements ReportTextVisitor {
}
@Override
public String visit(Action action) { return null; }
public String visit(Action action) {
return null;
}
}

View File

@ -10,19 +10,18 @@ import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Requirement class
* Requirement class.
*/
public class Requirement {
private static final Logger LOGGER = Logger.getLogger(Ticker.class.getName());
private static int counter;
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;
private final int id;
public Requirement(NodeBase creator, TransactionType transactionType, ProductType productType, String productName, MonetaryAmount price) {
this.creator = creator;
@ -60,7 +59,9 @@ public class Requirement {
return productName;
}
public MonetaryAmount getPrice() { return price; }
public MonetaryAmount getPrice() {
return price;
}
public int getTTL() {
return TTL;

View File

@ -3,7 +3,7 @@ package cz.cvut.fel.sit.omo.foodchain.scenario;
import cz.cvut.fel.sit.omo.foodchain.node.Customer;
/**
* Step for consuming random product from storage
* Step for consuming random product from storage.
*/
public class ConsumeProductStep extends ScenarioStep {

View File

@ -7,20 +7,20 @@ import javax.naming.InsufficientResourcesException;
import java.util.logging.Level;
/**
* Step for starting action on product(s)
* Step for starting action on product(s).
*/
public class DoActionStep extends ScenarioStep {
private final NodeBase nodeBase;
private final ProductOperationType productOperationType;
private final String productName;
public DoActionStep(NodeBase node, ProductOperationType productOperationType, String name){
public DoActionStep(NodeBase node, ProductOperationType productOperationType, String name) {
this.nodeBase = node;
this.productOperationType = productOperationType;
this.productName = name;
}
public DoActionStep(NodeBase node, ProductOperationType productOperationType){
public DoActionStep(NodeBase node, ProductOperationType productOperationType) {
this(node, productOperationType, null);
}
@ -33,12 +33,10 @@ public class DoActionStep extends ScenarioStep {
try {
if (productName != null) {
nodeBase.doAction(productOperationType, productName);
}
else {
} else {
nodeBase.doAction(productOperationType);
}
}
catch (IllegalCallerException | InsufficientResourcesException e) {
} catch (IllegalCallerException | InsufficientResourcesException e) {
LOGGER.log(Level.SEVERE, e.getMessage());
}
}

View File

@ -7,21 +7,20 @@ import cz.cvut.fel.sit.omo.foodchain.product.Product;
import java.util.logging.Level;
/**
* Step for generating product from pool
* Step for generating product from pool.
*/
public class GenerateProductStep extends ScenarioStep {
private static int counter = 0;
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 {
} else {
product = null;
LOGGER.log(Level.SEVERE, "Insufficient products in pool");
}

View File

@ -1,7 +1,7 @@
package cz.cvut.fel.sit.omo.foodchain.scenario;
/**
* Step for skipping
* Step for skipping.
*/
public class PassStep extends ScenarioStep {
@ -9,5 +9,6 @@ public class PassStep extends ScenarioStep {
* Does nothing.
*/
@Override
void execute() {}
void execute() {
}
}

View File

@ -4,7 +4,7 @@ import java.util.Iterator;
import java.util.List;
/**
* Scenatio class fpr holding and executing steps
* Scenatio class fpr holding and executing steps.
*/
public class Scenario {
List<ScenarioStep> steps;
@ -17,6 +17,7 @@ public class Scenario {
/**
* Executes next step.
*
* @return scenario has steps
*/
boolean execute() {
@ -29,6 +30,7 @@ public class Scenario {
/**
* Executes next step.
*
* @return scenario has steps
*/
public boolean tick() {

View File

@ -3,7 +3,7 @@ package cz.cvut.fel.sit.omo.foodchain.scenario;
import java.util.logging.Logger;
/**
* Scenario step class
* Scenario step class.
*/
public abstract class ScenarioStep {
protected static final Logger LOGGER = Logger.getLogger(ScenarioStep.class.getName());

View File

@ -10,14 +10,14 @@ import javax.naming.InsufficientResourcesException;
import java.util.logging.Level;
/**
* Step for sending requirements
* 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;
private final MonetaryAmount pPrice;
// sell
public SendRequirementStep(NodeBase node, TransactionType tType, ProductType pType, String pName) {

View File

@ -6,7 +6,7 @@ import java.time.LocalDateTime;
import java.util.UUID;
/**
* Signature class validating its transaction
* Signature class validating its transaction.
*/
public class Signature {

View File

@ -3,7 +3,7 @@ package cz.cvut.fel.sit.omo.foodchain.signature;
import cz.cvut.fel.sit.omo.foodchain.operation.Transaction;
/**
* Manager class for creating and validating signatures
* Manager class for creating and validating signatures.
*/
public class SignatureManager {
@ -11,6 +11,7 @@ public class SignatureManager {
/**
* Creates signature for transaction.
*
* @param transaction transaction
* @return signature
*/
@ -20,6 +21,7 @@ public class SignatureManager {
/**
* Check if signature corresponds with its transaction.
*
* @param transaction transaction
* @return signature corresponds with its transaction
*/

View File

@ -4,7 +4,7 @@ import cz.cvut.fel.sit.omo.foodchain.channel.ChannelBase;
import cz.cvut.fel.sit.omo.foodchain.requirement.Requirement;
/**
* Interface for nodes that receives requirements
* Interface for nodes that receives requirements.
*/
public interface ChannelObserver {
void update(Requirement requirement, ChannelBase channel);

View File

@ -1,10 +1,12 @@
package cz.cvut.fel.sit.omo.foodchain.util;
/**
* Interface for channels to work with observers
* Interface for channels to work with observers.
*/
public interface Observable {
void attach(ChannelObserver channelObserver);
void detach(ChannelObserver channelObserver);
void notifyAllObservers();
}

View File

@ -7,29 +7,31 @@ import java.util.logging.Level;
import java.util.logging.LogRecord;
/**
* Custom Logger used for TransactionReport
* Custom Logger used for TransactionReport.
*/
public class ReportLogger extends Handler
{
public class ReportLogger extends Handler {
private static final StringBuilder sb = new StringBuilder();
public static StringBuilder getSb() {
return sb;
}
/**
* Logs message and prints it out.
*
* @param record message to be printed
*/
@Override
public void publish(LogRecord record) {
// Blocking Money logs because spams "Using default formatter toString()." after printing MonetaryAmount in reports
if(record.getSourceClassName().equals(Money.class.getName()) || record.getMessage().contains("MathContext"))return;
if (record.getSourceClassName().equals(Money.class.getName()) || record.getMessage().contains("MathContext"))
return;
sb.append(record.getMessage()).append(System.lineSeparator());
if(record.getLevel().equals(Level.WARNING) || record.getLevel().equals(Level.SEVERE))
{
if (record.getLevel().equals(Level.WARNING) || record.getLevel().equals(Level.SEVERE)) {
System.err.println(record.getMessage());
}
else
{
} else {
System.out.println(record.getMessage());
}
}
@ -41,8 +43,4 @@ public class ReportLogger extends Handler
@Override
public void close() throws SecurityException {
}
public static StringBuilder getSb() {
return sb;
}
}

View File

@ -6,7 +6,7 @@ import java.util.HashMap;
import java.util.Map;
/**
* Singleton helper class
* Singleton helper class.
*/
public class Singleton {

View File

@ -12,7 +12,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Creates artificial time for application
* Creates artificial time for application.
*/
public class Ticker {
protected static final Logger LOGGER = Logger.getLogger(Ticker.class.getName());
@ -43,5 +43,7 @@ public class Ticker {
timer.stop();
}
public static Timer getTimer() { return timer; }
public static Timer getTimer() {
return timer;
}
}