Skip to content
Open

Lab2 #34

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions lab-02/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?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>by.polina_kostyukovich.docks_and_hobos</groupId>
<artifactId>lab-02</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>

<properties>
<maven.compiler.source>19</maven.compiler.source>
<maven.compiler.target>19</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package by.polina_kostyukovich.docks_and_hobos;

import by.polina_kostyukovich.docks_and_hobos.controllers.Controller;
import org.json.simple.parser.ParseException;

import java.io.IOException;

public class Main {
public static void main(String[] args) throws IOException, ParseException {
if (args.length != 1) {
throw new IllegalArgumentException("Illegal number of arguments");
}

Controller controller = new Controller(args[0]);
controller.startRunning();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package by.polina_kostyukovich.docks_and_hobos;

import by.polina_kostyukovich.docks_and_hobos.actors.*;
import by.polina_kostyukovich.docks_and_hobos.controllers.HoboController;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import java.io.FileReader;
import java.io.IOException;
import java.util.*;

public class Model {
public void readData(String filename) throws IOException, ParseException {
JSONParser parser = new JSONParser();
JSONObject info = (JSONObject) parser.parse(new FileReader(filename));

final int maxShipsInTunnel = (int) (long) info.get("Max ships in tunnel");
tunnel = new Tunnel(maxShipsInTunnel);

final int generatingTime = (int) (long) info.get("Generating time");
final int minShipCapacity = (int) (long) info.get("Min ship capacity");
final int maxShipCapacity = (int) (long) info.get("Max ship capacity");
Object[] cargoTypesJson = ((JSONArray) info.get("Cargo types")).toArray();
ArrayList<String> cargoTypes = new ArrayList<>(cargoTypesJson.length);
for (Object type : cargoTypesJson) {
cargoTypes.add((String) type);
}
shipGenerator = new ShipGenerator(generatingTime, cargoTypes, minShipCapacity, maxShipCapacity, tunnel);

final int numberOfDocks = (int) (long) info.get("Number of docks");
final int unloadingSpeed = (int) (long) info.get("Unloading speed");
final int dockCapacity = (int) (long) info.get("Dock capacity");
docks = new ArrayList<>(numberOfDocks);
for (int i = 0; i < numberOfDocks; ++i) {
docks.add(new Dock(unloadingSpeed, dockCapacity, i));
}

final int numberOfHobos = (int) (long) info.get("Number of hobos");
Object[] ingredientsCountJson = ((JSONArray) info.get("Ingredients count")).toArray();
Map<String, Integer> ingredientsCount = new HashMap<>(ingredientsCountJson.length);
for (Object ingredientCount : ingredientsCountJson) {
JSONObject ingredientCountJson = (JSONObject) ingredientCount;
ingredientsCount.put((String) ingredientCountJson.get("Cargo type"),
(int) (long) ingredientCountJson.get("Cargo amount"));
}
final int stealingTime = (int) (long) info.get("Stealing time");
final int eatingTime = (int) (long) info.get("Eating time");
ArrayList<Hobo> hobos = new ArrayList<>(numberOfHobos);
for (int i = 0; i < numberOfHobos; ++i) {
hobos.add(new Hobo(stealingTime, i));
}
hoboController = new HoboController(hobos, ingredientsCount, docks, eatingTime, cargoTypes);
}

public ShipGenerator getShipGenerator() {
return shipGenerator;
}

public Tunnel getTunnel() {
return tunnel;
}

public ArrayList<Dock> getDocks() {
return docks;
}

public HoboController getHoboController() {
return hoboController;
}

public Dock getFreeDock() {
return docks.stream()
.filter(Dock::isFree)
.findAny().orElse(null);
}

public boolean hasFreeDock() {
return docks.stream()
.anyMatch(Dock::isFree);
}

private ShipGenerator shipGenerator;
private Tunnel tunnel;
private ArrayList<Dock> docks;
private HoboController hoboController;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package by.polina_kostyukovich.docks_and_hobos.actors;

public class Cargo {
private final String type;
private int amount;

public Cargo(String type, int amount) {
if (type == null) {
throw new IllegalArgumentException("Parameter type is null");
}

this.type = type;
this.amount = amount;
}

public void setAmount(int amount) {
this.amount = amount;
}

public int getAmount() {
return amount;
}

public String getType() {
return type;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package by.polina_kostyukovich.docks_and_hobos.actors;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Dock implements Runnable {
public Dock(int unloadingTime, int capacity, int id) {
this.unloadingSpeed = unloadingTime;
this.capacity = capacity;
this.id = id;
}

@Override
public void run() {
Cargo addedCargo = new Cargo(cargoToAdd.getType(), 0);
while (cargoToAdd.getAmount() > 0 && getTotalCargoAmount() < capacity) {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
int addedAmount = Math.min(
Math.min(capacity - getTotalCargoAmount(), cargoToAdd.getAmount()), unloadingSpeed);
cargos.computeIfPresent(cargoToAdd.getType(), (type, count) -> count + addedAmount);
cargos.putIfAbsent(cargoToAdd.getType(), addedAmount);
cargoToAdd.setAmount(cargoToAdd.getAmount() - addedAmount);
addedCargo.setAmount(addedCargo.getAmount() + addedAmount);
}
isFree = true;
String strToLog = "Dock #" + id + " ended unloading " + addedCargo.getAmount() + " ones of "
+ addedCargo.getType();
LOGGER.log(Level.INFO, strToLog);
}

public Map<String, Integer> getCargos() {
return cargos;
}

public int getUnloadingSpeed() {
return unloadingSpeed;
}

public boolean isFree() {
return isFree && getTotalCargoAmount() < capacity;
}

public void setCargoToAdd(Cargo cargoToAdd) {
if (cargoToAdd == null) {
throw new IllegalArgumentException("Parameter cargoToAdd is null");
}

this.cargoToAdd = cargoToAdd;
}

public void setFree(boolean isFree) {
this.isFree = isFree;
}

public int getTotalCargoAmount() {
return cargos.values().stream()
.mapToInt(n -> n)
.sum();
}

public static Logger getLogger() {
return LOGGER;
}

private final int id;
private final int unloadingSpeed;
private final int capacity;
private final ConcurrentMap<String, Integer> cargos = new ConcurrentHashMap<>();
private boolean isFree = true;
private Cargo cargoToAdd;
private static final Logger LOGGER = Logger.getLogger(Dock.class.getName());
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package by.polina_kostyukovich.docks_and_hobos.actors;

import by.polina_kostyukovich.docks_and_hobos.controllers.HoboController;

import java.util.logging.Level;
import java.util.logging.Logger;

public class Hobo implements Runnable {
public Hobo(int stealingTime, int id) {
this.stealingTime = stealingTime;
this.id = id;
}

@Override
public void run() {
try {
Thread.sleep(stealingTime * 1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
cargoToBeStolen.getDock().getCargos().compute(cargoToBeStolen.getCargoType(), (type, count) -> count - 1);
cargoToBeStolen.decrementStealingHobosNumber();
LOGGER.log(Level.FINE, "Hobo #" + id + " stole one " + cargoToBeStolen.getCargoType());
isFree = true;
}

public boolean isFree() {
return isFree;
}

public void setCargoToBeStolen(HoboController.CargoToBeStolen cargoToBeStolen) {
if (cargoToBeStolen == null) {
throw new IllegalArgumentException("cargoToBeStolen is null");
}

this.cargoToBeStolen = cargoToBeStolen;
}

public void setFree(boolean isFree) {
this.isFree = isFree;
}

public static Logger getLogger() {
return LOGGER;
}

private final int id;
private final int stealingTime;
private boolean isFree = true;
private HoboController.CargoToBeStolen cargoToBeStolen;
private static final Logger LOGGER = Logger.getLogger(Hobo.class.getName());
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package by.polina_kostyukovich.docks_and_hobos.actors;

public class Ship {
private final Cargo cargo;

public Ship(Cargo cargo) {
if (cargo == null) {
throw new IllegalArgumentException("Parameter cargo is null");
}

this.cargo = cargo;
}

public Cargo getCargo() {
return cargo;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package by.polina_kostyukovich.docks_and_hobos.actors;

import java.util.ArrayList;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ShipGenerator implements Runnable {
public ShipGenerator(int generatingTime, ArrayList<String> cargoTypes, int minShipCapacity, int maxShipCapacity,
Tunnel tunnel) {
if (cargoTypes == null || tunnel == null) {
throw new IllegalArgumentException("Some parameter in ShipGenerator constructor is null");
}

this.generatingTime = generatingTime;
this.cargoTypes = cargoTypes;
this.minShipCapacity = minShipCapacity;
this.maxShipCapacity = maxShipCapacity;
this.tunnel = tunnel;
}

@Override
public void run() {
while (true) {
try {
Thread.sleep(1000L * generatingTime);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
Ship newShip = generateShip();
String strToLog;
if (tunnel.addShip(newShip)) {
strToLog = "Added ship: type - " + newShip.getCargo().getType() + ", amount - "
+ newShip.getCargo().getAmount();
} else {
strToLog = "Killed ship :(";
}
LOGGER.log(Level.INFO, strToLog);
}
}

private Ship generateShip() {
int capacity = (int) (Math.random() * (maxShipCapacity - minShipCapacity + 1) + minShipCapacity);
String type = cargoTypes.get((new Random()).nextInt(cargoTypes.size()));
return new Ship(new Cargo(type, capacity));
}

public int getGeneratingTime() {
return generatingTime;
}

public static Logger getLogger() {
return LOGGER;
}

private final int generatingTime;
private final ArrayList<String> cargoTypes;
private final int minShipCapacity;
private final int maxShipCapacity;
private final Tunnel tunnel;
private static final Logger LOGGER = Logger.getLogger(ShipGenerator.class.getName());
}
Loading