-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFileHandler.java
288 lines (264 loc) · 18.8 KB
/
FileHandler.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
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
///////////////////
// FileHandler: handles all file processing (excluding reading/writing)
///////////////////
public class FileHandler extends OS {
ReadFile fileReader = new ReadFile();
WriteFile fileWriter = new WriteFile();
String[] configTokenHistory = new String[validKeys.configKeyDeclarations.length]; //string array that is used to determine if there are too many/few assignments of a given config declaration
//verifyConfigFile - verify the configuration file
public boolean verifyConfigFile() {
fileReader.read(config.fileName); //actually read the config file and store it in the class's string var
String[] splitByLineBreak = stringHelper.splitOnDelimeter(fileReader.lastReadFile, "\\\n"); //array of strings containing each line read in from the config file
System.arraycopy(validKeys.configKeyDeclarations, 0, configTokenHistory, 0, validKeys.configKeyDeclarations.length); //make a second copy of configKeyDeclarations tocd configTokenHistory since we need two working arrays to accomplish error checking
int lineNum = 0; //used for error logging
//verify the config file extension is valid
String fileExtension = stringHelper.splitOnDelimeter(config.fileName, "\\.")[1];
if (!fileExtension.equals("conf")) {
console.error("Config file does not end in .conf");
}
//loop through each line in configuration file
for (int i = 0; i < splitByLineBreak.length; i++) {
lineNum++;
//if the current line is not a comment
if (stringHelper.substringIsInString(splitByLineBreak[i], ":")) {
String[] splitByColon = stringHelper.splitOnDelimeter(splitByLineBreak[i], "[\\s]*:[\\s]*"); //array of 2 cells - 1st is the left hand side of a config line (key), 2nd is the right hand side of a config line (value)
int returnedIndex = stringHelper.findTokenIndexInArray(validKeys.configKeyDeclarations, splitByColon[0]); //the index of the token found in configKeyDeclarations (= -1 if not found in array)
//if the token is not invalid
if (returnedIndex != -1) {
//if the token has already been used before
if (configTokenHistory[returnedIndex].equals("0")) {
console.error("Duplicate parameter declaration in " + config.fileName + " on line " + lineNum + ": \n \"" + splitByColon[0] + "\"");
} else {
//remove the token from the history array so that it can't be used twice
configTokenHistory[returnedIndex] = "0";
}
//if it is of type ______, try to parse it & verify the validity of the value
if (validKeys.configTypeDeclarations[returnedIndex].equals("double")) {
try {
Double.parseDouble(splitByColon[1]);
} catch (Exception e) {
console.error("There was an error parsing the double provided in " + config.fileName + " on line " + lineNum + ": \n \"" + splitByColon[1] + "\" next to declaration \"" + splitByColon[0] + "\"");
}
} else if (validKeys.configTypeDeclarations[returnedIndex].equals("int")) {
try {
Integer.parseInt(splitByColon[1]);
} catch (Exception e) {
console.error("There was an error parsing the int provided in " + config.fileName + " on line " + lineNum + ": \n \"" + splitByColon[1] + "\" next to declaration \"" + splitByColon[0] + "\"");
}
} else if (validKeys.configTypeDeclarations[returnedIndex].equals("fileName")) {
if (!stringHelper.substringIsInString(splitByColon[1], ".")) {
console.error("There was an error parsing the filename provided in " + config.fileName + " on line " + lineNum + ": \n \"" + splitByColon[1] + "\" next to declaration \"" + splitByColon[0] + "\"");
} else {
if (splitByColon[0].equals("Log File Path")) {
//verify the log file extension is valid
String logFileExtension = stringHelper.splitOnDelimeter(splitByColon[1], "\\.")[1];
if (!logFileExtension.equals("lgf")) {
console.error("Log file name does not end in .lgf");
}
} else if (splitByColon[0].equals("File Path")) {
//verify the input file extension is valid
String inputFileExtension = stringHelper.splitOnDelimeter(splitByColon[1], "\\.")[1];
if (!inputFileExtension.equals("mdf")) {
console.error("Input file does not end in .mdf");
}
}
}
} else if (validKeys.configTypeDeclarations[returnedIndex].equals("logOption")) {
if (!splitByColon[1].equals("Log to Both") && !splitByColon[1].equals("Log to Monitor") && !splitByColon[1].equals("Log to File")) {
console.error("There was an error parsing the log option provided in " + config.fileName + " on line " + lineNum + " (invalid option specified): \n \"" + splitByColon[1] + "\" next to declaration \"" + splitByColon[0] + "\"");
}
} else if (validKeys.configTypeDeclarations[returnedIndex].equals("schedulingCode")) {
if (!splitByColon[1].equals("FIFO") && !splitByColon[1].equals("PS") && !splitByColon[1].equals("SJF")) {
console.error("There was an error parsing the log option provided in " + config.fileName + " on line " + lineNum + " (invalid option specified): \n \"" + splitByColon[1] + "\" next to declaration \"" + splitByColon[0] + "\"");
}
}
} else {
console.error("Invalid parameter declaration in " + config.fileName + " on line " + lineNum + ": \n \"" + splitByColon[0] + "\"");
}
}
}
//make sure all the tokens that must be present were used
for (int i = 0; i < configTokenHistory.length; i++) {
if (!configTokenHistory[i].equals("0") && validKeys.configDefaultAllowed[i].equals("0")) {
console.error("Missing parameter declaration in " + config.fileName + ": \n \"" + configTokenHistory[i] + "\"");
}
}
return true;
}
//loadConfigFile - load the verified configuration file into the system
public void loadConfigFile() {
String[] splitByLineBreak = stringHelper.splitOnDelimeter(fileReader.lastReadFile, "\\\n"); //array of strings containing each line read in from the config file
//loop through each line in the file
for (int i = 0; i < splitByLineBreak.length - 1; i++) {
//if line is not a comment
if (stringHelper.substringIsInString(splitByLineBreak[i], ":")) {
String[] splitByColon = stringHelper.splitOnDelimeter(splitByLineBreak[i], "[\\s]*:[\\s]*"); //array of 2 cells - 1st is the left hand side of a config line (key), 2nd is the right hand side of a config line (value)
//make begin and end count for 0 time
config.times.put("begin", 0);
config.times.put("finish", 0);
//check to find which config value should be filled
if (splitByColon[0].equals("Version/Phase")) {
config.version = Double.parseDouble(splitByColon[1]);
} else if (splitByColon[0].equals("File Path")) {
config.inputFileName = splitByColon[1];
} else if (splitByColon[0].equals("Monitor display time {msec}")) {
config.times.put("monitor", Integer.parseInt(splitByColon[1]));
} else if (splitByColon[0].equals("Processor cycle time {msec}")) {
config.times.put("run", Integer.parseInt(splitByColon[1]));
} else if (splitByColon[0].equals("Scanner cycle time {msec}")) {
config.times.put("scanner", Integer.parseInt(splitByColon[1]));
} else if (splitByColon[0].equals("Hard drive cycle time {msec}")) {
config.times.put("hard drive", Integer.parseInt(splitByColon[1]));
} else if (splitByColon[0].equals("Keyboard cycle time {msec}")) {
config.times.put("keyboard", Integer.parseInt(splitByColon[1]));
} else if (splitByColon[0].equals("Memory cycle time {msec}")) {
config.times.put("allocate", Integer.parseInt(splitByColon[1]));
config.times.put("block", Integer.parseInt(splitByColon[1]));
} else if (splitByColon[0].equals("Projector cycle time {msec}")) {
config.times.put("projector", Integer.parseInt(splitByColon[1]));
} else if (splitByColon[0].equals("Log")) {
config.logOption = splitByColon[1];
} else if (splitByColon[0].equals("Log File Path")) {
config.logFileName = splitByColon[1];
} else if (splitByColon[0].equals("System memory {kbytes}")) {
config.systemMemory = Integer.parseInt(splitByColon[1]);
} else if (splitByColon[0].equals("System memory {Mbytes}")) {
config.systemMemory = Integer.parseInt(splitByColon[1]) * 1000;
} else if (splitByColon[0].equals("System memory {Gbytes}")) {
config.systemMemory = Integer.parseInt(splitByColon[1]) * 1000000;
} else if (splitByColon[0].equals("Memory block size {kbytes}")) {
config.blockSize = Integer.parseInt(splitByColon[1]);
} else if (splitByColon[0].equals("Memory block size {Mbytes}")) {
config.blockSize = Integer.parseInt(splitByColon[1]) * 1000;
} else if (splitByColon[0].equals("Memory block size {Gbytes}")) {
config.blockSize = Integer.parseInt(splitByColon[1]) * 1000000;
} else if (splitByColon[0].equals("Projector quantity")) {
config.projectorQuantity = Integer.parseInt(splitByColon[1]);
} else if (splitByColon[0].equals("Hard drive quantity")) {
config.hardDriveQuantity = Integer.parseInt(splitByColon[1]);
} else if (splitByColon[0].equals("Processor Quantum Number {msec}")) {
config.quantumNumber = Integer.parseInt(splitByColon[1]);
} else if (splitByColon[0].equals("CPU Scheduling Code")) {
config.schedulingCode = splitByColon[1];
} else {
//should never reach this after verifying the file
console.error("Invalid parameter declaration in " + config.fileName + ": \n \"" + splitByColon[0] + "\"");
}
}
}
//set the default values of items missing in the config file
fillDefaultValues();
//make the log file
fileWriter.createFile(config.logFileName);
//set the max block size for the memory allocator
memoryBlock.setMaxBlockSize(config.systemMemory);
//initialize the semaphore's number of available permits
locks.projector.init(config.projectorQuantity);
locks.hardDrive.init(config.hardDriveQuantity);
//tell the user if there will be no further monitor/file output
if (config.logOption.equals("Log to File")) {
console.writeConsoleLog("✓ Output from this point on will show only in the log file", "log");
} else if (config.logOption.equals("Log to Monitor")) {
console.writeFileLog("✓ Output will only show in the monitor window", "log");
}
}
//verifyInputFile - verify the input file
public boolean verifyInputFile() {
fileReader.read(config.inputFileName); //actually read the input file and store it in the class's string var
String[] splitByLineBreak = stringHelper.splitOnDelimeter(fileReader.lastReadFile, "\\\n");
int lineNum = 0;
//make sure the file is not empty
if (splitByLineBreak.length <= 1) {
console.error("Input file is empty");
}
for (int i = 0; i < splitByLineBreak.length; i++) {
lineNum++;
if (stringHelper.substringIsInString(splitByLineBreak[i], "{")) {
//pre-process the line data to fix white space issues
splitByLineBreak[i] = stringHelper.removeBadWhitespace(splitByLineBreak[i], validKeys.inputDescriptorDeclarations);
String[] splitBySemiColon = stringHelper.splitOnDelimeter(splitByLineBreak[i], "\\;|\\.");
for (int j = 0; j < splitBySemiColon.length; j++) {
//check to make sure the string matches the general regex pattern
if (!splitBySemiColon[j].matches("^[A-Z][\\s]*\\{[a-z]+(\\ *[a-z]*)\\}[\\s]*\\d+")) {
console.error("Syntax error in \"" + config.inputFileName + "\" on line " + lineNum + " for process:\n \"" + splitBySemiColon[j] + "\"");
}
//define the items based off of the resulting string
String metaCode = splitBySemiColon[j].substring(0,1);
String numCycles = splitBySemiColon[j].replaceAll("\\D+","");
String descriptor = splitBySemiColon[j];
descriptor = descriptor.substring(descriptor.indexOf("{") + 1);
descriptor = descriptor.substring(0, descriptor.indexOf("}"));
//check the values individually
if (stringHelper.findTokenIndexInArray(validKeys.inputMetaCodeDeclarations, metaCode) == -1) {
console.error("Invalid meta code in \"" + config.inputFileName + "\" on line " + lineNum + " for process:\n \""+ metaCode + "\" in \"" + splitBySemiColon[j] + "\"");
}
if (stringHelper.findTokenIndexInArray(validKeys.inputDescriptorDeclarations, descriptor) == -1) {
console.error("Invalid descriptor value in \"" + config.inputFileName + "\" on line " + lineNum + " for process:\n \"" + descriptor + "\" in \"" + splitBySemiColon[j] + "\"");
}
try {
Integer.parseInt(numCycles);
} catch (Exception e) {
console.error("There was an error parsing the numCycles int in \"" + config.inputFileName + "\" on line " + lineNum + " for process:\n\"" + splitBySemiColon[j] + "\"");
}
}
}
}
return true;
}
//loadInputFile - load the verified input file into the system
public void loadInputFile() {
String[] splitByLineBreak = stringHelper.splitOnDelimeter(fileReader.lastReadFile, "\\\n");
for (int i = 0; i < splitByLineBreak.length; i++) {
if (stringHelper.substringIsInString(splitByLineBreak[i], "{")) {
//pre-process the line data to fix white space issues
splitByLineBreak[i] = stringHelper.removeBadWhitespace(splitByLineBreak[i], validKeys.inputDescriptorDeclarations);
String[] splitBySemiColon = stringHelper.splitOnDelimeter(splitByLineBreak[i], "\\;|\\.");
for (int j = 0; j < splitBySemiColon.length; j++) {
//define the items based off of the resulting string
char metaCode = splitBySemiColon[j].substring(0,1).charAt(0);
int numCycles = Integer.parseInt(splitBySemiColon[j].replaceAll("\\D+",""));
String descriptor = splitBySemiColon[j];
descriptor = descriptor.substring(descriptor.indexOf("{") + 1);
descriptor = descriptor.substring(0, descriptor.indexOf("}"));
//if start or end, make begin or finish
if (descriptor.equals("start")) {
descriptor = "begin";
} else if (descriptor.equals("end")) {
descriptor = "finish";
}
//make a new (temp) task and add the data to it
Task newTask = new Task();
newTask.code = metaCode;
newTask.numCycles = numCycles;
newTask.description = descriptor;
//add the temp task to the task list
taskQueue.enqueue(newTask);
}
}
}
}
//fillDefaultValues - fills the default values that are missing from the config file
public void fillDefaultValues() {
for (int i = 0; i < configTokenHistory.length; i++) {
if (!configTokenHistory[i].equals("0") && validKeys.configDefaultAllowed[i].equals("1")) {
console.warn("Config file did not supply " + configTokenHistory[i] + ".\n OS will use default value: " + validKeys.configDefaultValueDeclarations[i]);
if (configTokenHistory[i].equals("Memory cycle time {msec}")) {
config.times.put("allocate", Integer.parseInt(validKeys.configDefaultValueDeclarations[i]));
config.times.put("block", Integer.parseInt(validKeys.configDefaultValueDeclarations[i]));
} else if (configTokenHistory[i].equals("System memory {kbytes}|System memory {Mbytes}|System memory {Gbytes}")) {
config.systemMemory = Integer.parseInt(validKeys.configDefaultValueDeclarations[i]);
} else if (configTokenHistory[i].equals("Memory block size {kbytes}|Memory block size {Mbytes}|Memory block size {Gbytes}")) {
config.blockSize = Integer.parseInt(validKeys.configDefaultValueDeclarations[i]);
} else if (configTokenHistory[i].equals("Projector quantity")) {
config.projectorQuantity = Integer.parseInt(validKeys.configDefaultValueDeclarations[i]);
} else if (configTokenHistory[i].equals("Hard drive quantity")) {
config.hardDriveQuantity = Integer.parseInt(validKeys.configDefaultValueDeclarations[i]);
} else if (configTokenHistory[i].equals("Processor Quantum Number")) {
config.quantumNumber = Integer.parseInt(validKeys.configDefaultValueDeclarations[i]);
} else if (configTokenHistory[i].equals("CPU Scheduling Code")) {
config.schedulingCode = validKeys.configDefaultValueDeclarations[i];
}
}
}
}
}