diff --git a/Seminar7/code/Server/.idea/.gitignore b/Seminar7/code/Server/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/Seminar7/code/Server/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/Seminar7/code/Server/.idea/misc.xml b/Seminar7/code/Server/.idea/misc.xml
new file mode 100644
index 0000000..03f397c
--- /dev/null
+++ b/Seminar7/code/Server/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Seminar7/code/Server/.idea/modules.xml b/Seminar7/code/Server/.idea/modules.xml
new file mode 100644
index 0000000..7ec00e1
--- /dev/null
+++ b/Seminar7/code/Server/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Seminar7/code/Server/.idea/vcs.xml b/Seminar7/code/Server/.idea/vcs.xml
new file mode 100644
index 0000000..c2365ab
--- /dev/null
+++ b/Seminar7/code/Server/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Seminar7/code/Server/out/production/Server/ClientResolver.class b/Seminar7/code/Server/out/production/Server/ClientResolver.class
new file mode 100644
index 0000000..c5a5a53
Binary files /dev/null and b/Seminar7/code/Server/out/production/Server/ClientResolver.class differ
diff --git a/Seminar7/code/Server/out/production/Server/Computer.class b/Seminar7/code/Server/out/production/Server/Computer.class
new file mode 100644
index 0000000..31fc3ed
Binary files /dev/null and b/Seminar7/code/Server/out/production/Server/Computer.class differ
diff --git a/Seminar7/code/Server/out/production/Server/ComputerBuilder.class b/Seminar7/code/Server/out/production/Server/ComputerBuilder.class
new file mode 100644
index 0000000..bbb31ea
Binary files /dev/null and b/Seminar7/code/Server/out/production/Server/ComputerBuilder.class differ
diff --git a/Seminar7/code/Server/out/production/Server/Main.class b/Seminar7/code/Server/out/production/Server/Main.class
new file mode 100644
index 0000000..8072f8b
Binary files /dev/null and b/Seminar7/code/Server/out/production/Server/Main.class differ
diff --git a/Seminar7/code/Server/out/production/Server/ServerHandler.class b/Seminar7/code/Server/out/production/Server/ServerHandler.class
new file mode 100644
index 0000000..776302f
Binary files /dev/null and b/Seminar7/code/Server/out/production/Server/ServerHandler.class differ
diff --git a/Seminar7/code/Server/out/production/Server/Store.class b/Seminar7/code/Server/out/production/Server/Store.class
new file mode 100644
index 0000000..d80240d
Binary files /dev/null and b/Seminar7/code/Server/out/production/Server/Store.class differ
diff --git a/Seminar7/code/Server/out/production/Server/StoreSeeder.class b/Seminar7/code/Server/out/production/Server/StoreSeeder.class
new file mode 100644
index 0000000..4f86982
Binary files /dev/null and b/Seminar7/code/Server/out/production/Server/StoreSeeder.class differ
diff --git a/Seminar7/code/Server/out/production/Server/StreamCommunicator.class b/Seminar7/code/Server/out/production/Server/StreamCommunicator.class
new file mode 100644
index 0000000..0b1e980
Binary files /dev/null and b/Seminar7/code/Server/out/production/Server/StreamCommunicator.class differ
diff --git a/Seminar7/code/Server/src/ClientResolver.java b/Seminar7/code/Server/src/ClientResolver.java
new file mode 100644
index 0000000..57eda9f
--- /dev/null
+++ b/Seminar7/code/Server/src/ClientResolver.java
@@ -0,0 +1,34 @@
+import java.io.PrintStream;
+import java.net.Socket;
+import java.util.Scanner;
+
+public class ClientResolver implements Runnable {
+ private Socket clientSocket;
+ private Store store;
+
+ public ClientResolver(Socket socket, Store store)
+ {
+ this.clientSocket = socket;
+ this.store = store;
+ }
+
+ public void run()
+ {
+ Scanner in = null;
+ PrintStream out = null;
+ try {
+ in = new Scanner(clientSocket.getInputStream());
+ out = new PrintStream(clientSocket.getOutputStream());
+ StreamCommunicator communicator = new StreamCommunicator(in, out);
+
+ var server = new ServerHandler(communicator, this.store);
+ server.startCommunication();
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ System.out.println("Connection closed.");
+ } finally {
+ in.close();
+ out.close();
+ }
+ }
+}
diff --git a/Seminar7/code/Server/src/Computer.java b/Seminar7/code/Server/src/Computer.java
new file mode 100644
index 0000000..c592ebc
--- /dev/null
+++ b/Seminar7/code/Server/src/Computer.java
@@ -0,0 +1,76 @@
+import java.time.LocalDate;
+
+public class Computer {
+ private int id;
+ private String brand;
+ private String model;
+ private boolean isUsed;
+ private LocalDate manufacturedDate;
+ private int quantity;
+
+ public Computer() { }
+
+ public Computer(String brand, String model, boolean isUsed, LocalDate manufacturedDate, int quantity) {
+ this.setBrand(brand);
+ this.setModel(model);
+ this.setUsed(isUsed);
+ this.setManufacturedDate(manufacturedDate);
+ this.setQuantity(quantity);
+ }
+
+ public int getId() {
+ return id;
+ }
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getBrand() {
+ return brand;
+ }
+ public void setBrand(String brand) {
+ this.brand = brand;
+ }
+
+ public String getModel() {
+ return model;
+ }
+ public void setModel(String model) {
+ this.model = model;
+ }
+
+ public boolean isUsed() {
+ return isUsed;
+ }
+ public void setUsed(boolean used) {
+ isUsed = used;
+ }
+
+ public LocalDate getManufacturedDate() {
+ return manufacturedDate;
+ }
+ public void setManufacturedDate(LocalDate manufacturedDate) {
+ this.manufacturedDate = manufacturedDate;
+ }
+
+ public int getQuantity() {
+ return quantity;
+ }
+ public void setQuantity(int quantity) {
+ this.quantity = quantity;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Computer: #").append(this.getId()).append("\t")
+ .append(this.getBrand()).append(" ").append(this.getModel()).append("\t")
+ .append("Year of manufacturing: ").append(this.getManufacturedDate().toString()).append("\t")
+ .append("Quantity: ").append(this.getQuantity()).append("\t");
+ if(this.isUsed()) {
+ sb.append("Computer is used").append("\t");
+ }
+
+ return sb.toString();
+ }
+}
diff --git a/Seminar7/code/Server/src/ComputerBuilder.java b/Seminar7/code/Server/src/ComputerBuilder.java
new file mode 100644
index 0000000..2c161ad
--- /dev/null
+++ b/Seminar7/code/Server/src/ComputerBuilder.java
@@ -0,0 +1,14 @@
+import java.time.LocalDate;
+
+public class ComputerBuilder {
+ public static Computer build(StreamCommunicator communicator) {
+ Computer computer = new Computer();
+ computer.setBrand(communicator.communicateMessage("Enter brand:"));
+ computer.setModel(communicator.communicateMessage("Enter model:"));
+ computer.setManufacturedDate(LocalDate.parse(
+ communicator.communicateMessage("Enter date (in format: yyyy-mm-dd):")));
+ computer.setUsed(Boolean.parseBoolean(communicator.communicateMessage("Is used:")));
+ computer.setQuantity(Integer.parseInt(communicator.communicateMessage("Quantity:")));
+ return computer;
+ }
+}
diff --git a/Seminar7/code/Server/src/Main.java b/Seminar7/code/Server/src/Main.java
new file mode 100644
index 0000000..99c652c
--- /dev/null
+++ b/Seminar7/code/Server/src/Main.java
@@ -0,0 +1,29 @@
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+
+public class Main {
+ private static final int SOCKET_PORT = 5038; //Any random free port
+
+ public static void main(String[] args) {
+ ServerSocket server = null;
+ Store store = StoreSeeder.getSeededStore();
+
+ try {
+ server = new ServerSocket(SOCKET_PORT);
+
+ while (true) {
+ Socket client = server.accept();
+ System.out.println("Connection established: " + client.getInetAddress().getHostAddress());
+
+ ClientResolver resolver = new ClientResolver(client, store);
+ new Thread(resolver).start();
+ }
+ } catch (SocketException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Seminar7/code/Server/src/ServerHandler.java b/Seminar7/code/Server/src/ServerHandler.java
new file mode 100644
index 0000000..dee0e11
--- /dev/null
+++ b/Seminar7/code/Server/src/ServerHandler.java
@@ -0,0 +1,45 @@
+import java.io.PrintStream;
+import java.util.Scanner;
+
+public class ServerHandler {
+ private StreamCommunicator communicator;
+ private Store store;
+
+ public ServerHandler(StreamCommunicator communicator, Store store) {
+ this.communicator = communicator;
+ this.store = store;
+ }
+
+ public void startCommunication() {
+ int choice = Integer.parseInt(communicator.communicateMessage("Write 1 for administrator and 2 for client"));
+ switch(choice) {
+ case 1:
+ this.communicateAdmin();
+ break;
+ case 2:
+ this.communicateCustomer();
+ break;
+ default:
+ communicator.communicateMessage("Not an option");
+ }
+ }
+
+ private void communicateAdmin() {
+ communicator.addMessage("Entering a new computer details.");
+ Computer computer = ComputerBuilder.build(communicator);
+ this.store.addComputer(computer);
+ }
+
+ private void communicateCustomer() {
+ communicator.communicateMessage("Buying a computer.",
+ this.store.getAvailableComputers(),
+ "Which computer would you like to buy");
+ int computerId = Integer.parseInt(communicator.communicateMessage());
+ int quantity = Integer.parseInt(communicator.communicateMessage("How many?"));
+ try {
+ store.sellComputers(computerId, quantity);
+ } catch (Exception ex) {
+ communicator.communicateMessage(ex.getMessage());
+ }
+ }
+}
diff --git a/Seminar7/code/Server/src/Store.java b/Seminar7/code/Server/src/Store.java
new file mode 100644
index 0000000..c04f25d
--- /dev/null
+++ b/Seminar7/code/Server/src/Store.java
@@ -0,0 +1,43 @@
+import java.util.*;
+
+public class Store {
+ private List availableComputers = Collections.synchronizedList(new ArrayList<>());
+
+ public void addComputer(Computer computer) {
+ computer.setId(this.availableComputers.size());
+ this.availableComputers.add(computer);
+ }
+
+ public String getAvailableComputers() {
+ StringBuffer sb = new StringBuffer();
+ for (var computer : this.availableComputers) {
+ sb.append(computer);
+ }
+
+ return sb.toString();
+ }
+
+ public void sellComputers(int computerId, int desiredQuantity) {
+ synchronized (this.availableComputers) {
+ var computerInStock = this.availableComputers.stream()
+ .filter(c -> c.getId() == computerId).findFirst();
+
+ if (computerInStock.isEmpty()) {
+ throw new IllegalArgumentException("Computer with id " + computerId + " doesn't exist.");
+ }
+
+ Computer computer = computerInStock.get();
+ int newQuantity = computer.getQuantity() - desiredQuantity;
+ if (newQuantity < 0) {
+ throw new IllegalArgumentException("There are only " + computer.getQuantity() + " computers left."
+ + " We cannot sell you " + desiredQuantity);
+ }
+
+ if(newQuantity == 0) {
+ this.availableComputers.remove(computer);
+ } else {
+ computer.setQuantity(newQuantity);
+ }
+ }
+ }
+}
diff --git a/Seminar7/code/Server/src/StoreSeeder.java b/Seminar7/code/Server/src/StoreSeeder.java
new file mode 100644
index 0000000..dc8f300
--- /dev/null
+++ b/Seminar7/code/Server/src/StoreSeeder.java
@@ -0,0 +1,17 @@
+import java.time.LocalDate;
+
+public class StoreSeeder {
+ public static Store getSeededStore() {
+ Store store = new Store();
+ populate(store);
+ return store;
+ }
+
+ private static void populate(Store store) {
+ store.addComputer(new Computer("Lenovo", "T15", false, LocalDate.now(), 5));
+ store.addComputer(new Computer("Asus", "Zenbook",
+ true, LocalDate.of(2020, 10, 1), 2));
+ store.addComputer(new Computer("Apple", "Macbook Pro",
+ false, LocalDate.of(2021, 10, 31), 30));
+ }
+}
diff --git a/Seminar7/code/Server/src/StreamCommunicator.java b/Seminar7/code/Server/src/StreamCommunicator.java
new file mode 100644
index 0000000..c773bba
--- /dev/null
+++ b/Seminar7/code/Server/src/StreamCommunicator.java
@@ -0,0 +1,32 @@
+import java.io.PrintStream;
+import java.lang.invoke.StringConcatException;
+import java.util.*;
+
+public class StreamCommunicator {
+ private Scanner in;
+ private PrintStream out;
+ private List messages;
+
+ public StreamCommunicator(Scanner in, PrintStream out) {
+ this.in = in;
+ this.out = out;
+ this.messages = new ArrayList<>();
+ }
+
+ public void addMessage(String message) {
+ this.messages.add(message);
+ }
+
+ public String communicateMessage() {
+ var result = this.communicateMessage(this.messages.toArray(String[]::new));
+ this.messages.clear();
+ return result;
+ }
+
+ public String communicateMessage(String ...messsages) {
+ String messageToSend = Arrays.stream(messsages).reduce("",
+ (String total, String current) -> total + current);
+ out.println(messageToSend);
+ return in.nextLine();
+ }
+}
diff --git a/Seminar7/notes/Seminar0701.png b/Seminar7/notes/Seminar0701.png
new file mode 100644
index 0000000..7eb3b85
Binary files /dev/null and b/Seminar7/notes/Seminar0701.png differ
diff --git a/Seminar7/notes/Seminar0702.png b/Seminar7/notes/Seminar0702.png
new file mode 100644
index 0000000..c301ff3
Binary files /dev/null and b/Seminar7/notes/Seminar0702.png differ
diff --git a/Seminar7/notes/Seminar0703.png b/Seminar7/notes/Seminar0703.png
new file mode 100644
index 0000000..2d00f0c
Binary files /dev/null and b/Seminar7/notes/Seminar0703.png differ