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