1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.jdtaus.banking.util;
22
23 import java.io.IOException;
24 import java.io.InputStreamReader;
25 import java.io.LineNumberReader;
26 import java.io.UnsupportedEncodingException;
27 import java.net.URL;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.Locale;
31 import java.util.Map;
32 import org.jdtaus.banking.BankleitzahlInfo;
33 import org.jdtaus.banking.messages.UpdatesBankleitzahlenDateiMessage;
34 import org.jdtaus.core.container.ContainerFactory;
35 import org.jdtaus.core.container.PropertyException;
36 import org.jdtaus.core.logging.spi.Logger;
37 import org.jdtaus.core.monitor.spi.Task;
38 import org.jdtaus.core.monitor.spi.TaskMonitor;
39
40
41
42
43
44
45
46
47
48
49
50
51 public final class BankleitzahlenDatei
52 {
53
54
55
56
57
58
59
60
61
62
63 private Logger getLogger()
64 {
65 return (Logger) ContainerFactory.getContainer().
66 getDependency( this, "Logger" );
67
68 }
69
70
71
72
73
74
75 private TaskMonitor getTaskMonitor()
76 {
77 return (TaskMonitor) ContainerFactory.getContainer().
78 getDependency( this, "TaskMonitor" );
79
80 }
81
82
83
84
85
86
87 private Locale getLocale()
88 {
89 return (Locale) ContainerFactory.getContainer().
90 getDependency( this, "Locale" );
91
92 }
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107 private java.lang.String getDefaultEncoding()
108 {
109 return (java.lang.String) ContainerFactory.getContainer().
110 getProperty( this, "defaultEncoding" );
111
112 }
113
114
115
116
117
118
119
120 private Map records = new HashMap( 20000 );
121 private BankleitzahlInfo[] cachedRecords;
122
123
124 private String encoding;
125
126
127
128
129
130
131
132
133
134
135
136
137
138 public BankleitzahlenDatei( final URL resource ) throws IOException
139 {
140 super();
141 this.assertValidProperties();
142 this.readBankfile( resource );
143 }
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 public BankleitzahlenDatei( final URL resource, final String encoding )
160 throws IOException
161 {
162 super();
163 this.encoding = encoding;
164 this.assertValidProperties();
165 this.readBankfile( resource );
166 }
167
168
169
170
171
172
173 public String getEncoding()
174 {
175 if ( this.encoding == null )
176 {
177 this.encoding = this.getDefaultEncoding();
178 }
179
180 return this.encoding;
181 }
182
183
184
185
186
187
188 public BankleitzahlInfo[] getRecords()
189 {
190 if ( this.cachedRecords == null )
191 {
192 this.cachedRecords = (BankleitzahlInfo[]) this.records.values().
193 toArray( new BankleitzahlInfo[ this.records.size() ] );
194
195 }
196
197 return this.cachedRecords;
198 }
199
200
201
202
203
204
205
206
207
208
209
210
211 public BankleitzahlInfo getRecord( final Integer serialNumber )
212 {
213 if ( serialNumber == null )
214 {
215 throw new NullPointerException( "serialNumber" );
216 }
217
218 return (BankleitzahlInfo) this.records.get( serialNumber );
219 }
220
221
222
223
224
225
226
227
228
229
230
231
232 public void update( final BankleitzahlenDatei file )
233 {
234 if ( file == null )
235 {
236 throw new NullPointerException( "file" );
237 }
238
239 int i;
240 final boolean log = this.getLogger().isDebugEnabled();
241 BankleitzahlInfo oldVersion;
242 BankleitzahlInfo newVersion;
243
244 int progress = 0;
245 Task task = new Task();
246 task.setIndeterminate( false );
247 task.setCancelable( false );
248 task.setDescription( new UpdatesBankleitzahlenDateiMessage() );
249 task.setMinimum( 0 );
250 task.setMaximum( file.getRecords().length );
251 task.setProgress( progress );
252
253 try
254 {
255 this.getTaskMonitor().monitor( task );
256
257 for ( i = file.getRecords().length - 1; i >= 0; i-- )
258 {
259 task.setProgress( progress++ );
260 newVersion = file.getRecords()[i];
261 if ( 'A' == newVersion.getChangeLabel() )
262 {
263 oldVersion = (BankleitzahlInfo) this.records.get(
264 newVersion.getSerialNumber() );
265
266 if ( oldVersion != null &&
267 oldVersion.getChangeLabel() != 'D' )
268 {
269 throw new IllegalArgumentException(
270 this.getCannotAddDuplicateRecordMessage(
271 this.getLocale(),
272 newVersion.getSerialNumber() ) );
273
274 }
275
276 this.records.put( newVersion.getSerialNumber(), newVersion );
277
278 if ( log )
279 {
280 this.getLogger().debug(
281 this.getAddRecordInfoMessage(
282 this.getLocale(),
283 String.valueOf( newVersion.getChangeLabel() ),
284 newVersion.getSerialNumber() ) );
285
286 }
287 }
288 else if ( 'M' == newVersion.getChangeLabel() ||
289 'D' == newVersion.getChangeLabel() )
290 {
291 if ( this.records.put( newVersion.getSerialNumber(),
292 newVersion ) == null )
293 {
294 throw new IllegalArgumentException(
295 this.getCannotModifyNonexistentRecordMessage(
296 this.getLocale(), newVersion.getSerialNumber() ) );
297
298 }
299
300 if ( log )
301 {
302 this.getLogger().debug(
303 this.getModifyRecordInfoMessage(
304 this.getLocale(),
305 String.valueOf( newVersion.getChangeLabel() ),
306 newVersion.getSerialNumber() ) );
307
308 }
309
310 }
311 else if ( 'U' == newVersion.getChangeLabel() &&
312 !this.records.containsKey( newVersion.getSerialNumber() ) )
313 {
314 throw new IllegalArgumentException(
315 this.getCannotModifyNonexistentRecordMessage(
316 this.getLocale(), newVersion.getSerialNumber() ) );
317
318 }
319 }
320 }
321 finally
322 {
323 this.getTaskMonitor().finish( task );
324 }
325
326 progress = 0;
327 task = new Task();
328 task.setIndeterminate( false );
329 task.setCancelable( false );
330 task.setDescription( new UpdatesBankleitzahlenDateiMessage() );
331 task.setMinimum( 0 );
332 task.setMaximum( this.records.size() );
333 task.setProgress( progress );
334
335 try
336 {
337 this.getTaskMonitor().monitor( task );
338 for ( Iterator it = this.records.values().iterator(); it.hasNext();)
339 {
340 task.setProgress( progress++ );
341 oldVersion = (BankleitzahlInfo) it.next();
342
343 if ( 'D' == oldVersion.getChangeLabel() )
344 {
345 newVersion = file.getRecord( oldVersion.getSerialNumber() );
346 if ( newVersion == null )
347 {
348 it.remove();
349
350 if ( log )
351 {
352 this.getLogger().debug(
353 this.getRemoveRecordInfoMessage(
354 this.getLocale(),
355 String.valueOf( oldVersion.getChangeLabel() ),
356 oldVersion.getSerialNumber() ) );
357
358 }
359 }
360 }
361 }
362 }
363 finally
364 {
365 this.getTaskMonitor().finish( task );
366 }
367
368 this.cachedRecords = null;
369 }
370
371
372
373
374
375
376 private void assertValidProperties()
377 {
378 if ( this.getEncoding() == null || this.getEncoding().length() == 0 )
379 {
380 throw new PropertyException( "encoding", this.getEncoding() );
381 }
382
383 try
384 {
385 "".getBytes( this.getEncoding() );
386 }
387 catch ( UnsupportedEncodingException e )
388 {
389 throw new PropertyException( "encoding", this.getEncoding(), e );
390 }
391 }
392
393
394
395
396
397
398
399
400
401
402
403
404 private void readBankfile( final URL resource ) throws IOException
405 {
406 if ( resource == null )
407 {
408 throw new NullPointerException( "resource" );
409 }
410
411 this.records.clear();
412
413 if ( this.getLogger().isDebugEnabled() )
414 {
415 this.getLogger().debug( this.getFileNameInfoMessage(
416 this.getLocale(), resource.toExternalForm() ) );
417
418 }
419
420 LineNumberReader reader = null;
421
422 try
423 {
424 reader = new LineNumberReader( new InputStreamReader(
425 resource.openStream(), this.getEncoding() ) );
426
427 String line;
428 boolean emptyLine = false;
429 while ( ( line = reader.readLine() ) != null )
430 {
431 if ( line.trim().length() == 0 )
432 {
433 emptyLine = true;
434 continue;
435 }
436
437 if ( emptyLine )
438 {
439 throw new IllegalArgumentException(
440 this.getUnexpectedDataMessage(
441 this.getLocale(), new Integer( reader.getLineNumber() ),
442 resource.toExternalForm() ) );
443
444 }
445
446
447 final BankleitzahlInfo rec = new BankleitzahlInfo();
448 rec.parse( line );
449
450 if ( this.records.put( rec.getSerialNumber(), rec ) != null )
451 {
452 throw new IllegalArgumentException(
453 this.getCannotAddDuplicateRecordMessage(
454 this.getLocale(), rec.getSerialNumber() ) );
455
456 }
457 }
458 }
459 finally
460 {
461 this.cachedRecords = null;
462
463 if ( reader != null )
464 {
465 reader.close();
466 }
467 }
468 }
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486 private String getFileNameInfoMessage( final Locale locale,
487 final java.lang.String fileName )
488 {
489 return ContainerFactory.getContainer().
490 getMessage( this, "fileNameInfo", locale,
491 new Object[]
492 {
493 fileName
494 });
495
496 }
497
498
499
500
501
502
503
504
505
506
507
508
509 private String getAddRecordInfoMessage( final Locale locale,
510 final java.lang.String label,
511 final java.lang.Number serialNumber )
512 {
513 return ContainerFactory.getContainer().
514 getMessage( this, "addRecordInfo", locale,
515 new Object[]
516 {
517 label,
518 serialNumber
519 });
520
521 }
522
523
524
525
526
527
528
529
530
531
532
533
534 private String getModifyRecordInfoMessage( final Locale locale,
535 final java.lang.String label,
536 final java.lang.Number serialNumber )
537 {
538 return ContainerFactory.getContainer().
539 getMessage( this, "modifyRecordInfo", locale,
540 new Object[]
541 {
542 label,
543 serialNumber
544 });
545
546 }
547
548
549
550
551
552
553
554
555
556
557
558
559 private String getRemoveRecordInfoMessage( final Locale locale,
560 final java.lang.String label,
561 final java.lang.Number serialNumber )
562 {
563 return ContainerFactory.getContainer().
564 getMessage( this, "removeRecordInfo", locale,
565 new Object[]
566 {
567 label,
568 serialNumber
569 });
570
571 }
572
573
574
575
576
577
578
579
580
581
582
583 private String getCannotAddDuplicateRecordMessage( final Locale locale,
584 final java.lang.Number serialNumber )
585 {
586 return ContainerFactory.getContainer().
587 getMessage( this, "cannotAddDuplicateRecord", locale,
588 new Object[]
589 {
590 serialNumber
591 });
592
593 }
594
595
596
597
598
599
600
601
602
603
604
605 private String getCannotModifyNonexistentRecordMessage( final Locale locale,
606 final java.lang.Number serialNumber )
607 {
608 return ContainerFactory.getContainer().
609 getMessage( this, "cannotModifyNonexistentRecord", locale,
610 new Object[]
611 {
612 serialNumber
613 });
614
615 }
616
617
618
619
620
621
622
623
624
625
626
627
628 private String getUnexpectedDataMessage( final Locale locale,
629 final java.lang.Number lineNumber,
630 final java.lang.String resourceName )
631 {
632 return ContainerFactory.getContainer().
633 getMessage( this, "unexpectedData", locale,
634 new Object[]
635 {
636 lineNumber,
637 resourceName
638 });
639
640 }
641
642
643
644
645 }