-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathServerMain.java
261 lines (212 loc) · 9.36 KB
/
ServerMain.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
// Luca Lombardo, mat. 546688
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ServerMain {
public static void main(String args[]) {
Object userSync = new Object(); // Variabile per la sincronizzazione su utenti registrati e loggati
Object projectSync = new Object(); // Variabile per la sincronizzazione sui progetti
ServerRemote service = null;
ArrayList<User> members = new ArrayList<User>(); // Lista degli utenti registrati al servizio
ArrayList<User> loggedUsers = new ArrayList<User>(); // Lista degli utenti loggati
ArrayList<Project> projects = new ArrayList<Project>(); // Lista dei progetti
int[] ip = {224, 0, 0, 1}; // Ip multicast di partenza, passato ai ServerThread e usato nella creazione di nuovi progetti
String tn = Thread.currentThread().getName(); // Thread attuale
// Se esiste il file degli utenti registrati, leggine i contenuti e popola la lista di membri
String fpath = "members.json";
File f = new File(fpath);
// Sincronizza l'accesso agli utenti registrati
synchronized(userSync) {
// Cerca il file degli utenti registrati
if(f.isFile()) {
System.out.printf("%S SERVER: file members trovato.\n", tn);
String read = "";
try {
read = new String(Files.readAllBytes(Paths.get(fpath)));
members = new ObjectMapper().readValue(read, new TypeReference<ArrayList<User>>(){});
} catch (IOException e) {
System.err.printf("%S SERVER: errore lettura file.\n", tn);
e.printStackTrace();
}
}
else {
System.out.printf("%S SERVER: file members non trovato. Verra' creato con la registrazione.\n", tn);
}
}
// Cerca la directory projects
String projectsPath = "projects";
File projectDirectory = new File(projectsPath);
// Sincronizza l'accesso ai progetti
synchronized(projectSync) {
if (projectDirectory.exists()) {
System.out.printf("%S SERVER: cartella projects trovata.\n", tn);
// Cerca i progetti
File[] pDirectories = new File("projects/").listFiles(File::isDirectory);
// Aggiorna la lista interna dei progetti
for (File pf : pDirectories) {
projects.add(new Project(pf.getName()));
File[] pFiles = pf.listFiles();
if (pFiles != null) {
for (File ch : pFiles) {
// Se il file e' la lista dei membri...
if (ch.getName().equals(pf.getName() + "Members.json")) {
String read = "";
try {
String fileName = ("projects/" + pf.getName() + "/" + pf.getName() + "Members.json");
read = new String(Files.readAllBytes(Paths.get(fileName)));
Project progetto = null;
for (Project p : projects) {
if (p.getName().equals(pf.getName())) {
progetto = p;
}
}
// Leggi la lista dei membri dal file .json e aggiorna la struttura dati interna
progetto.setProjectMembers(new ObjectMapper().readValue(read, new TypeReference<ArrayList<User>>(){}));
} catch (IOException e) {
System.err.printf("%S SERVER: errore lettura file projectMembers.\n", tn);
e.printStackTrace();
}
}
// Se il file e' l'indirizzo multicast...
else if (ch.getName().equals(pf.getName() + "Multicast.json")) {
String read = "";
try {
String fileName = ("projects/" + pf.getName() + "/" + pf.getName() + "Multicast.json");
read = new String(Files.readAllBytes(Paths.get(fileName)));
Project progetto = null;
for (Project p : projects) {
if (p.getName().equals(pf.getName())) {
progetto = p;
}
}
// Leggi l'indirizzo ip multicast dal file json
int[] currentIp = new ObjectMapper().readValue(read, new TypeReference<int[]>(){});
progetto.setMulticastIp(currentIp);
System.out.printf("%S SERVER: ho trovato il progetto %s con ip %s.\n", tn, progetto.getName(), progetto.getMulticastIp());
// Tieni in memoria l'ip multicast maggiore: serve per la creazione di nuovi progetti
if (currentIp[1] > ip[1]) {
ip = currentIp.clone();
}
else if (currentIp[2] > ip[2]) {
ip = currentIp.clone();
}
else if (currentIp[3] > ip[3]) {
ip =currentIp.clone();
}
} catch (IOException e) {
System.err.printf("%S SERVER: errore lettura file projectMulticast.\n", tn);
e.printStackTrace();
}
}
// Se il file e' una card...
else {
String read = "";
try {
String fileName = ("projects/" + pf.getName() + "/" + ch.getName());
read = new String(Files.readAllBytes(Paths.get(fileName)));
Project progetto = null;
for (Project p : projects) {
if (p.getName().equals(pf.getName())) {
progetto = p;
}
}
// Leggi la card dal file .json
Card card = new ObjectMapper().readValue(read, new TypeReference<Card>(){});
ArrayList<String> history = card.getHistory();
// Trova a quale lista appartiene la card
String lastList = history.get(history.size() -1);
// Aggiorna la corrispondente lista del progetto
switch (lastList.toLowerCase()) {
case "todo":
ArrayList<Card> todo = progetto.getToDo();
todo.add(card);
progetto.setToDo(todo);
break;
case "inprogress":
ArrayList<Card> inprogress = progetto.getInProgress();
inprogress.add(card);
progetto.setInProgress(inprogress);
break;
case "toberevised":
ArrayList<Card> toberevised = progetto.getToBeRevised();
toberevised.add(card);
progetto.setToBeRevised(toberevised);
break;
case "done":
ArrayList<Card> done = progetto.getDone();
done.add(card);
progetto.setDone(done);
break;
default:
System.err.printf("%S SERVER: errore! La card non appartiene ad alcuna lista.\n", tn);
break;
}
} catch (IOException e) {
System.err.printf("%S SERVER: errore lettura file projectMembers.\n", tn);
e.printStackTrace();
}
}
}
}
else {
System.err.printf("%S SERVER: errore lettura directory!\n", tn);
}
}
}
// Se la cartella projects non esiste, creala
else {
System.out.printf("%S SERVER: cartella projects non trovata.\n", tn);
projectDirectory.mkdir();
System.out.printf("%S SERVER: cartella projects creata.\n", tn);
}
}
// Crea il registro per RMI
try {
service = new ServerRemote(userSync, members, loggedUsers);
ServerRemoteInterface stub = (ServerRemoteInterface) UnicastRemoteObject.exportObject(service, 0);
LocateRegistry.createRegistry(6000);
Registry r = LocateRegistry.getRegistry(6000);
r.rebind("WORTH", stub);
System.out.printf("%S SERVER: registro pronto.\n", tn);
} catch (RemoteException e) {
System.err.printf("%S SERVER: errore creazione registry.\n", tn);
e.printStackTrace();
}
// Crea la threadpool
try (ServerSocket listener = new ServerSocket(10000)) {
System.out.printf("%S SERVER: creo la ThreadPool...\n", tn);
int numThreads = 8;
// Se il server e' stato avviato senza nessun argomento, utilizza un numero di default come dimensione della FixedThreadPool
if (args.length == 0) {
System.out.printf("%S SERVER: nessun argomento passato, lascio parametro al valore di default (8).\n", tn);
}
// Altrimenti, imposta la dimensione della pool uguale all'argomento passato
else {
try {
numThreads = Integer.parseInt(args[0]);
} catch (NumberFormatException e) {
System.out.printf("%S SERVER: l'argomento passato non e' valido. Lascio parametro al valore di default (8).\n", tn);
}
}
ThreadPoolExecutor pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(numThreads);
// Faccio partire i thread
while (true) {
pool.execute(new ServerThread(listener.accept(), userSync, projectSync, members, loggedUsers, projects, service, ip));
}
} catch (IOException e) {
System.err.printf("%S SERVER: errore IO.\n", tn);
e.printStackTrace();
}
}
}