Projekt

Obecné

Profil

Stáhnout (16.4 KB) Statistiky
| Větev: | Revize:
1
package data;
2

    
3
import gui.Window;
4

    
5
import java.io.BufferedWriter;
6
import java.io.File;
7
import java.io.IOException;
8
import java.nio.charset.Charset;
9
import java.nio.file.Files;
10
import java.nio.file.Path;
11
import java.nio.file.StandardOpenOption;
12
import java.time.LocalDate;
13
import java.time.format.DateTimeFormatter;
14
import java.util.ArrayList;
15
import java.util.List;
16

    
17
/**
18
 *
19
 * Trida prochazi seznam spoju, casovych kodu, linek a pevnych kodu a na jejich zaklade naplnuje a generuje bitmapy,
20
 * ktere zapisuje do vystupniho souboru
21
 *
22
 * @author  Daniel Stus, Marek Sobota, Lukas Scurko, Jan Jirman
23
 * @version 1.0
24
 *
25
 */
26
public class BitmapBuilder {
27

    
28
    //-------------- Atributy --------------/
29

    
30
    /** Seznam uchovavajici vsechny zaznamy souboru pevnykod.txt */
31
    private ArrayList<JDFPevnykodRecord> pevnykod = new ArrayList<>();
32

    
33
    /** Seznam uchovavajici vsechny zaznamy pozadovanych linek souboru caskody.txt */
34
    private ArrayList<JDFCaskodyRecord> caskody = new ArrayList<>();
35

    
36
    /** Seznam uchovavajici vsechny zaznamy pozadovanych linek souboru spoje.txt */
37
    private ArrayList<JDFSpojeRecord> spoje = new ArrayList<>();
38

    
39
    /** Seznam uchovavajici vsechny vygenerovane bitmapy */
40
    private ArrayList<Bitmap> bitmaps = new ArrayList<>();
41

    
42
    /** Seznam uchovavajici vsechny uzivatelem zadane linky pro generaci */
43
    private List<String> lineList;
44

    
45
    /** Cesta k vystupnimu souboru pro vypis vygenerovanych bitmap */
46
    private Path outputFile;
47

    
48
    /** Instance GUI pro vypis kontrolnich zprav */
49
    private Window window;
50

    
51

    
52
    //-------------- Konstruktor -------------/
53

    
54

    
55
    /**
56
     * Konstruktor, prebira instanci okna pro vypisy, vytvari a kontroluje vystupni soubor
57
     *
58
     * @param window Instance tridy pro vypisy
59
     * @param outputPath Cesta k vystupnimu souboru
60
     */
61
    public BitmapBuilder(Window window, File outputPath){
62
    	this.window = window;
63
    	window.printMessage("Vytvořen BitmapBuilder");
64

    
65
    	// Vytvoření výstupního souboru
66
    	this.outputFile = outputPath.toPath();
67
        try {
68
            if (Files.notExists(outputFile)) {
69
                Files.createFile(outputFile);
70
                window.printMessage("Vytvořen soubor: "+outputFile.toString());
71
            }
72
            else {
73
                window.printMessage("Výstupní soubor již existuje, přepisuji...");
74
                Files.deleteIfExists(outputFile);
75
                Files.createFile(outputFile);
76
            }
77

    
78
        } catch (IOException e) {
79
            e.printStackTrace();
80
            window.printMessage("Neočekávaná chyba při práci s výstupním souborem");
81
        }
82
    }
83

    
84
    //----------------- Metody ----------------/
85

    
86
    /**
87
     * Metoda naplni seznam pevnych kodu
88
     *
89
     * @param loadedData kompletni nactena dana souboru pevnykod
90
     */
91
    public void getPevnyKod(ArrayList<String[]> loadedData){
92
        JDFPevnykodRecord pevnykodRecord;
93
        for(String[] record : loadedData){
94
                pevnykodRecord = new JDFPevnykodRecord(record);
95
                pevnykod.add(pevnykodRecord);
96
        }
97
        window.printMessage("Načten soubor Pevnykod.txt");
98
    }
99

    
100
    /**
101
     * Metoda naplni seznam caskody, vsemi zaznamy odpovidajicih pozadovanym linkam a caskodum s numerickou hodnotou
102
     *
103
     * @param loadedData kompletni nactena dana souboru caskody
104
     */
105
    public void getCaskody(ArrayList<String[]> loadedData){
106
        JDFCaskodyRecord caskodyRecord;
107
        for(String[] record : loadedData){
108
            if (lineList.contains(record[0]) && record[4].matches("\\d+")) {
109
                caskodyRecord = new JDFCaskodyRecord(record);
110
                caskody.add(caskodyRecord);
111
            }
112
        }
113
        window.printMessage("Načteny požadované linky ze souboru Caskody.txt");
114
    }
115

    
116
    /**
117
     * Metoda naplni seznam spoju, vsemi zaznamy odpovidajicih pozadovanym linkam
118
     *
119
     * @param loadedData kompletni nactena dana souboru spoje
120
     */
121
    public void getSpoje(ArrayList<String[]> loadedData){
122
        JDFSpojeRecord spojeRecord;
123
        for(String[] record : loadedData){
124
            if (lineList.contains(record[0])) {
125
                spojeRecord = new JDFSpojeRecord(record);
126
                spoje.add(spojeRecord);
127
            }
128
        }
129
        window.printMessage("Načteny požadované linky ze souboru Spoje.txt");
130
    }
131

    
132
    /**
133
     * Naplni seznam uzivatelsky zadanych linek
134
     *
135
     * @param lines seznam uzivatelskych linek
136
     */
137
    public boolean getLineList(List<String> lines){
138
        this.lineList = lines;
139
        window.printMessage("Načten uživatelský seznam linek");
140
        window.printMessage("Nalezené linky: "+lineList);
141
        if(lineList.size() < 1){
142
        	window.printMessage("Seznam linek je prázdný!");
143
        	return false;
144
        }
145
        return true;
146

    
147
    }
148

    
149

    
150
    /**
151
     * Metoda overi jestli je obdobi casoveho omezeni spada do obdobi pro generovanou bitmapu
152
     *
153
     * @param dateFrom pocatek generovaneho obdobi bitmapy
154
     * @param dateTo konec generovaneho obdobi bitmapy
155
     * @param dateFromHardCode pocatek obdobi caskoveho omezeni
156
     * @param dateToHardCode konec obdobi casoveho omezeni
157
     * @return Vrati {@code true} pokud casove omezeni spada do odobi generavaneho bitmapou, {@code false} pokud casove omezeni nespada do obdobi generovaneho bitmapou
158
     */
159
    public boolean isInRange(LocalDate dateFrom, LocalDate dateTo, String dateFromHardCode, String dateToHardCode) {
160
        //Formát datumu v Caskody.txt např: - 09022018
161
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMyyyy");
162

    
163
        LocalDate hardCodeDateFrom;
164
        LocalDate hardCodeDateTo;
165

    
166
            //Naparsuj pouze pokud datum do existuje
167
            if (!dateToHardCode.equals("")) {
168
                hardCodeDateFrom = LocalDate.parse(dateFromHardCode, formatter);
169
                hardCodeDateTo = LocalDate.parse(dateToHardCode, formatter);
170

    
171
                if (hardCodeDateFrom.isBefore(dateFrom) && hardCodeDateTo.isAfter(dateTo)) {
172
                    return true;
173
                }
174

    
175
                if (!hardCodeDateFrom.isBefore(dateFrom) && !hardCodeDateTo.isAfter(dateTo)) {
176
                    return true;
177
                }
178

    
179
                if (hardCodeDateFrom.isBefore(dateFrom) && !hardCodeDateTo.isAfter(dateTo) && hardCodeDateTo.isAfter(dateFrom)) {
180
                    return true;
181
                }
182

    
183
                if (hardCodeDateFrom.isAfter(dateFrom) && hardCodeDateTo.isAfter(dateTo) && !hardCodeDateFrom.isAfter(dateTo)) {
184
                    return true;
185
                }
186

    
187
            }
188

    
189
            //Pokud se jedná pouze o jeden den
190
            else {
191
                hardCodeDateFrom = LocalDate.parse(dateFromHardCode, formatter);
192

    
193
                if (!hardCodeDateFrom.isBefore(dateFrom) && !hardCodeDateFrom.isAfter(dateTo)) {
194
                    return true;
195
                }
196

    
197
            }
198

    
199
        return false;
200

    
201
    }
202

    
203
    /**
204
     * Metoda orizne, nastavi a vrati obdobi pro casove omezeni, tak aby spadalo do obdobi generavaneho bitmapou, pro naplneni
205
     *
206
     * @param dateFrom pocatek generovaneho obdobi bitmapy
207
     * @param dateTo konec generovaneho obdobi bitmapy
208
     * @param dateFromHardCode pocatek obdobi casoveho omezeni
209
     * @param dateToHardCode konec obdobi casoveho omezeni
210
     * @return pole s pocatkem a koncem obdobi casoveho omezeni, index 0 -> pocatek, index 1 -> konec
211
     */
212
    private LocalDate[] setHardCodeRange(LocalDate dateFrom, LocalDate dateTo, String dateFromHardCode, String dateToHardCode) {
213
        //Formát datumu v Caskody.txt např: - 09022018
214
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMyyyy");
215

    
216
        LocalDate[] hardCodeRange = new LocalDate[2];
217
        LocalDate hardCodeDateFrom;
218
        LocalDate hardCodeDateTo;
219

    
220
            //Naparsuj pouze pokud datum existuje
221
            if (!dateToHardCode.equals("")) {
222
                hardCodeDateFrom = LocalDate.parse(dateFromHardCode, formatter);
223
                hardCodeDateTo = LocalDate.parse(dateToHardCode, formatter);
224

    
225

    
226
                if (!hardCodeDateFrom.isBefore(dateFrom) && !hardCodeDateFrom.isAfter(dateTo)) {
227
                    hardCodeRange[0] = hardCodeDateFrom;
228
                }
229
                else hardCodeRange[0] = dateFrom;
230

    
231
                if (!hardCodeDateTo.isAfter(dateTo) && !hardCodeDateTo.isBefore(dateFrom)) {
232
                    hardCodeRange[1] = hardCodeDateTo;
233
                }
234
                else hardCodeRange[1] = dateTo;
235

    
236
            }
237

    
238
            //Existuje vždy
239
            else {
240
                hardCodeDateFrom = LocalDate.parse(dateFromHardCode, formatter);
241
                hardCodeRange[0] = hardCodeDateFrom;
242
                hardCodeRange[1] = null;
243
            }
244

    
245
            return hardCodeRange;
246

    
247
        }
248

    
249
    /**
250
     * Metoda overi zda-li zadany retezec odpovida cislene hodnote
251
     *
252
     * @param inputData retezec pro overeni
253
     * @return Vrati {@code true} pokud je retezec cislem, v opacnem pripade vrati {@code false}
254
     */
255
    private static boolean isNumeric(String inputData) {
256
        return inputData.matches("[-+]?\\d+(\\.\\d+)?");
257
    }
258

    
259

    
260
    /**
261
     * Zavola prislusne metody bitmapy pro naplneni podle casoveho kodu
262
     *
263
     * @param bitmap bitmapa pro naplneni
264
     * @param dateFrom pocatek obdobi pro naplneni
265
     * @param dateTo konec obdobi pro naplneni
266
     * @param TimeCodeType cislo casoveho kodu
267
     */
268
    private void fillBitmap (Bitmap bitmap, LocalDate dateFrom, LocalDate dateTo, int TimeCodeType) {
269

    
270
        switch (TimeCodeType) {
271
            case 1: {
272
                if (dateTo!=null) bitmap.setHardCodeDays(dateFrom, dateTo, 1);
273
                else bitmap.setDay(dateFrom, 1);
274
                break;
275
            }
276
            case 2: {
277
                bitmap.setHardCodeDays(bitmap.getDateFrom(), bitmap.getDateTo(), 1);
278
                if (dateTo!=null) bitmap.setDaysInRange(dateFrom, dateTo, 1);
279
                else bitmap.setDay(dateFrom, 1);
280
                break;
281
            }
282
            case 3: {
283
                bitmap.setDay(dateFrom, 1);
284
                break;
285
            }
286
            case 4: {
287
                bitmap.setHardCodeDays(bitmap.getDateFrom(), bitmap.getDateTo(), 1);
288
                if (dateTo!=null) bitmap.unsetDaysInRange(dateFrom, dateTo);
289
                else bitmap.setDay(dateFrom, 0);
290
                break;
291
            }
292
            case 5: {
293
                bitmap.setHardCodeWeeks(1, 1);
294
                break;
295
            }
296
            case 6: {
297
                bitmap.setHardCodeWeeks(1, 0);
298
                break;
299
            }
300
            case 7: {
301
                bitmap.setHardCodeWeeksInRange(dateFrom, dateTo, 1, 1);
302
                break;
303
            }
304
            case 8: {
305
                bitmap.setHardCodeWeeksInRange(dateFrom, dateTo, 1, 0);
306
                break;
307
            }
308
            default: break;
309
        }
310

    
311
    }
312

    
313
    /**
314
     * Metoda projde seznamy spoju, caskodu, pevnychkodu a linek na jejichz zaklade vygeneruje a naplni bitmapy v zadanem obdobi
315
     * vysledne bitmapy vypise v pozadovanem formatu do vystupniho souboru
316
     *
317
     * @param dateFrom pocatek obdobi pro bitmapu
318
     * @param dateTo konec obdobi pro bitmapu
319
     */
320
    public void writeBitmaps(LocalDate dateFrom, LocalDate dateTo) {
321
        
322
        try(BufferedWriter writer = Files.newBufferedWriter(outputFile, Charset.defaultCharset(), StandardOpenOption.APPEND)) {
323
            DateTimeFormatter format = DateTimeFormatter.ofPattern("d.M.yyyy");
324
            String currentLine =  spoje.get(0).getNumberLine();
325
            String currentTimeCode;
326
            String previousTimeCode;
327
            LocalDate[] hardCodeRange;
328

    
329
            //Výpis období do výstupního souboru, ve formátu: Období;dateFrom(d.M.yyyy);dateTo(d.M.yyyy)
330
            writer.write("Období;" + dateFrom.format(format)+ ";" + dateTo.format(format) + "\r\n\r\n");
331

    
332
            window.printMessage("Zpracovávám bitmapy...");
333
            window.printMessage("Zpracovávám linku: "+currentLine);
334

    
335

    
336
            //Pro každý spoj
337
            for (JDFSpojeRecord spoj : spoje) {
338
                currentTimeCode = "00";
339

    
340
                //Pokud se jedná o novou linku - Vypiš _______ ??? (Je potřeba) ???
341
                if (!currentLine.equals(spoj.getNumberLine())) {
342
                    currentLine = spoj.getNumberLine();
343
                    window.printMessage("Zpracovávám linku: "+currentLine);
344
                }
345

    
346
                //Výpis právě prozkoumávaného spoje
347
                String currentJoin = spoj.getNumberJoin();
348
                window.printMessage("- spoj: "+currentJoin);
349

    
350
                Bitmap generatedBitmap = new Bitmap(dateFrom, dateTo, currentLine, currentJoin, currentTimeCode, spoj.hardCodesToString(pevnykod), spoj.getNumberLineVersion());
351
                int numberOfTimeCodes = 0; //Počet časových kódu daného spoje
352
                int timeCodesInRange = 0; //Počet časových kódu aplikovaných na spoj
353

    
354
                previousTimeCode = "";
355

    
356
                for (JDFCaskodyRecord caskod : caskody) {
357

    
358

    
359
                    // Zda se jedná o aktuálně zkoumanou linku a spoj
360
                    if (currentLine.equals(caskod.getNumberLine()) && currentJoin.equals(caskod.getNumberJoin())) {
361

    
362
                        currentTimeCode =  caskod.getTimeCode();
363
                        generatedBitmap.setTimeCode(currentTimeCode);
364
                        numberOfTimeCodes++;
365

    
366
                        // Pokud se jedná o stejný spoj, ale jiný časový kód vytvoř novou bitmapu a přidej předchozí
367
                        if (!currentTimeCode.equals(previousTimeCode) && isNumeric(currentTimeCode) && !previousTimeCode.equals("")) {
368
                            bitmaps.add(generatedBitmap);
369
                            generatedBitmap = new Bitmap(dateFrom, dateTo, currentLine, currentJoin, currentTimeCode, spoj.hardCodesToString(pevnykod), spoj.getNumberLineVersion());
370
                        }
371

    
372

    
373
                         //Pokud je zkoumaný časový kód v rozsahu bitmapy
374
                        if (isInRange(dateFrom, dateTo, caskod.getStartDate(), caskod.getEndDate())) {
375
                            timeCodesInRange++;
376
                            hardCodeRange = setHardCodeRange(dateFrom, dateTo, caskod.getStartDate(), caskod.getEndDate());
377
                            fillBitmap(generatedBitmap, hardCodeRange[0], hardCodeRange[1], Integer.parseInt(caskod.getTypeTimeCode()));
378
                        }
379

    
380
                        previousTimeCode = currentTimeCode;
381
                    }
382
                }
383

    
384

    
385

    
386
                //Pokud nemá žádné časové omezení a žádný pevnýkód -> naplň jedničkami
387
                if (numberOfTimeCodes == 0 && spoj.getHardCodes().size() == 0) {
388
                    generatedBitmap.fillWithOnes();
389
                    bitmaps.add(generatedBitmap);
390
                }
391

    
392
                //Pokud nemá spoj žádná omezení -> napln bitmapu podle pevnych kodu a přidej
393
                else if (timeCodesInRange == 0 && spoj.getHardCodes().size() > 0) {
394
                    generatedBitmap.setHardCodeDays(dateFrom, dateTo, 1);
395
                    bitmaps.add(generatedBitmap);
396
                }
397

    
398
                //Jinak bitmapa byla již naplněna -> přidej
399
                else {
400
                    bitmaps.add(generatedBitmap);
401
                }
402
            }
403

    
404
                //Celkový počet vygenerovaných bitmap
405
                window.printMessage("Celkem vygenerováno: "+bitmaps.size()+" Bitmap");
406

    
407
            for (Bitmap bitmap : bitmaps) {
408
                writer.write(bitmap.toString()+"\r\n");
409
            }
410

    
411

    
412
        } catch (IOException e) {
413
            e.printStackTrace();
414
            window.printMessage("Neočekávaná chyba při zapisování bitmapy");
415
        }
416
        window.printMessage("Bitmapy úspěšně zapsány");
417
    }
418

    
419
    /**
420
     * Vrati seznam uzivatelskych linek pro generovani
421
     *
422
     * @return seznam uzivatelskych linek pro generovani
423
     */
424
    public List<String> getLineList() {
425
        return lineList;
426
    }
427

    
428
    /**
429
     * Nastavi seznam uzivatelskych linek na hodnotu {@code lineList}
430
     *
431
     * @param lineList seznam uzivatelskych linek
432
     */
433
    public void setLineList(List<String> lineList) {
434
        this.lineList = lineList;
435
    }
436

    
437
    /**
438
     * Vrati cestu k vystupnimu souboru
439
     *
440
     * @return cesta k vystupnimu souboru
441
     */
442
    public Path getOutputFile() {
443
        return outputFile;
444
    }
445

    
446
    /**
447
     * Nastavi cestu vystupniho souboru na hodnut {@code outputFile}
448
     *
449
     * @param outputFile cesta vystupniho souboru
450
     */
451
    public void setOutputFile(Path outputFile) {
452
        this.outputFile = outputFile;
453
    }
454
}
(2-2/8)