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;
22
23 import java.lang.ref.Reference;
24 import java.lang.ref.SoftReference;
25 import java.text.DecimalFormat;
26 import java.text.ParseException;
27 import java.text.ParsePosition;
28 import java.util.Collections;
29 import java.util.HashMap;
30 import java.util.Map;
31
32
33
34
35
36
37
38
39
40 public final class Referenznummer11 extends Number implements Comparable
41 {
42
43
44
45
46
47
48 public static final int ELECTRONIC_FORMAT = 6001;
49
50
51
52
53
54
55
56
57 public static final int LETTER_FORMAT = 6002;
58
59
60 public static final int MAX_DIGITS = 11;
61
62
63 public static final int MAX_CHARACTERS = 14;
64
65
66 private static final double[] EXP10 =
67 {
68 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000,
69 1000000000, 10000000000L
70 };
71
72
73 private static final long serialVersionUID = -6729406850413828467L;
74
75
76 private static volatile Reference cacheReference = new SoftReference( null );
77
78
79
80
81
82 private long ref;
83
84
85
86
87
88
89
90
91
92
93 private Referenznummer11( final Number referenceCode )
94 {
95 if ( !Referenznummer11.checkReferenznummer11( referenceCode ) )
96 {
97 throw new IllegalArgumentException( referenceCode.toString() );
98 }
99
100 this.ref = referenceCode.longValue();
101 }
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 public static Referenznummer11 parse( final String referenceCode, final ParsePosition pos )
118 {
119 if ( referenceCode == null )
120 {
121 throw new NullPointerException( "referenceCode" );
122 }
123 if ( pos == null )
124 {
125 throw new NullPointerException( "pos" );
126 }
127
128 Referenznummer11 ret = null;
129 boolean sawSpace = false;
130 boolean failed = false;
131 final ParsePosition fmtPos = new ParsePosition( 0 );
132 final int len = referenceCode.length();
133 final int startIndex = pos.getIndex();
134 final int maxIndex = startIndex + MAX_CHARACTERS;
135 final StringBuffer digits = new StringBuffer( MAX_DIGITS );
136 int mode = ELECTRONIC_FORMAT;
137 int part = 0;
138 int partStart = 0;
139 int partEnd = 2;
140 int digit = 0;
141 int i = startIndex;
142
143 for ( ; i < len && i < maxIndex && digits.length() < MAX_DIGITS; i++ )
144 {
145 final char c = referenceCode.charAt( i );
146
147 if ( Character.isDigit( c ) )
148 {
149 sawSpace = false;
150
151 if ( mode == LETTER_FORMAT )
152 {
153 if ( digit < partStart || digit > partEnd )
154 {
155 failed = true;
156 }
157 else
158 {
159 digits.append( c );
160 }
161 }
162 else
163 {
164 digits.append( c );
165 }
166
167 digit++;
168 }
169 else if ( c == ' ' )
170 {
171 if ( sawSpace || i == startIndex || ( mode == ELECTRONIC_FORMAT && digit != 3 ) )
172 {
173 failed = true;
174 }
175 else
176 {
177 mode = LETTER_FORMAT;
178 switch ( part )
179 {
180 case 0:
181 partStart = 3;
182 partEnd = 5;
183 break;
184 case 1:
185 partStart = 6;
186 partEnd = 8;
187 break;
188 case 2:
189 partStart = 9;
190 partEnd = 10;
191 break;
192 default:
193 failed = true;
194 break;
195 }
196 part++;
197
198 if ( digit < partStart || digit > partEnd )
199 {
200 failed = true;
201 }
202 }
203
204 sawSpace = true;
205 }
206 else
207 {
208 failed = true;
209 }
210
211 if ( failed )
212 {
213 pos.setErrorIndex( i );
214 break;
215 }
216 }
217
218 if ( !failed )
219 {
220 final Number num = new DecimalFormat( "###########" ).parse( digits.toString(), fmtPos );
221 if ( num != null && fmtPos.getErrorIndex() == -1 )
222 {
223 final String key = num.toString();
224 ret = (Referenznummer11) getCache().get( key );
225
226 if ( ret == null )
227 {
228 if ( !Referenznummer11.checkReferenznummer11( num ) )
229 {
230 pos.setErrorIndex( startIndex );
231 ret = null;
232 }
233 else
234 {
235 pos.setIndex( i );
236 ret = new Referenznummer11( num );
237 getCache().put( key, ret );
238 }
239 }
240 else
241 {
242 pos.setIndex( i );
243 }
244 }
245 else
246 {
247 pos.setErrorIndex( startIndex );
248 }
249 }
250
251 return ret;
252 }
253
254
255
256
257
258
259
260
261
262
263
264
265
266 public static Referenznummer11 parse( final String referenceCode ) throws ParseException
267 {
268 if ( referenceCode == null )
269 {
270 throw new NullPointerException( "referenceCode" );
271 }
272
273 Referenznummer11 ref = (Referenznummer11) getCache().get( referenceCode );
274
275 if ( ref == null )
276 {
277 final ParsePosition pos = new ParsePosition( 0 );
278 ref = Referenznummer11.parse( referenceCode, pos );
279 if ( ref == null || pos.getErrorIndex() != -1 || pos.getIndex() < referenceCode.length() )
280 {
281 throw new ParseException( referenceCode,
282 pos.getErrorIndex() != -1 ? pos.getErrorIndex() : pos.getIndex() );
283
284 }
285 else
286 {
287 getCache().put( referenceCode, ref );
288 }
289 }
290
291 return ref;
292 }
293
294
295
296
297
298
299
300
301
302
303
304
305 public static Referenznummer11 valueOf( final Number referenceCode )
306 {
307 final String key = referenceCode.toString();
308 Referenznummer11 ret = (Referenznummer11) getCache().get( key );
309
310 if ( ret == null )
311 {
312 ret = new Referenznummer11( referenceCode );
313 getCache().put( key, ret );
314 }
315
316 return ret;
317 }
318
319
320
321
322
323
324
325
326
327
328
329
330
331 public static Referenznummer11 valueOf( final String referenceCode )
332 {
333 try
334 {
335 return Referenznummer11.parse( referenceCode );
336 }
337 catch ( final ParseException e )
338 {
339 throw (IllegalArgumentException) new IllegalArgumentException( referenceCode ).initCause( e );
340 }
341 }
342
343
344
345
346
347
348
349
350 public static boolean checkReferenznummer11( final Number referenceCode )
351 {
352 boolean valid = referenceCode != null;
353
354 if ( valid )
355 {
356 final long num = referenceCode.longValue();
357 valid = num >= 0L && num < 100000000000L;
358 }
359
360 return valid;
361 }
362
363
364
365
366
367
368 public int intValue()
369 {
370 return (int) this.ref;
371 }
372
373
374
375
376
377
378 public long longValue()
379 {
380 return this.ref;
381 }
382
383
384
385
386
387
388 public float floatValue()
389 {
390 return this.ref;
391 }
392
393
394
395
396
397
398 public double doubleValue()
399 {
400 return this.ref;
401 }
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417 public StringBuffer format( final int style, final StringBuffer toAppendTo )
418 {
419 if ( toAppendTo == null )
420 {
421 throw new NullPointerException( "toAppendTo" );
422 }
423 if ( style != Referenznummer11.ELECTRONIC_FORMAT && style != Referenznummer11.LETTER_FORMAT )
424 {
425 throw new IllegalArgumentException( Integer.toString( style ) );
426 }
427
428 if ( this.ref == 0L )
429 {
430 toAppendTo.append( '0' );
431 }
432 else
433 {
434 final int[] digits = Referenznummer11.toDigits( this.ref );
435 for ( int i = digits.length - 1, lastDigit = 0; i >= 0; i-- )
436 {
437 if ( digits[i] != 0 || lastDigit > 0 )
438 {
439 toAppendTo.append( digits[i] );
440 lastDigit++;
441 }
442
443 if ( style == Referenznummer11.LETTER_FORMAT && ( lastDigit == 3 || lastDigit == 6 || lastDigit == 9 ) )
444 {
445 toAppendTo.append( ' ' );
446 }
447 }
448 }
449
450 return toAppendTo;
451 }
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468 public String format( final int style )
469 {
470 return this.format( style, new StringBuffer() ).toString();
471 }
472
473
474
475
476
477
478
479
480
481
482
483
484
485 public static String toString( final Referenznummer11 referenznummer11 )
486 {
487 if ( referenznummer11 == null )
488 {
489 throw new NullPointerException( "referenznummer11" );
490 }
491
492 return referenznummer11.format( ELECTRONIC_FORMAT );
493 }
494
495
496
497
498
499
500
501
502 private static int[] toDigits( final long number )
503 {
504 int i;
505 int j;
506 long subst;
507 final int[] ret = new int[ MAX_DIGITS ];
508
509 for ( i = MAX_DIGITS - 1; i >= 0; i-- )
510 {
511 for ( j = i + 1, subst = 0L; j < MAX_DIGITS; j++ )
512 {
513 subst += ret[j] * EXP10[j];
514 }
515 ret[i] = (int) Math.floor( ( number - subst ) / EXP10[i] );
516 }
517
518 return ret;
519 }
520
521
522
523
524
525
526 private String internalString()
527 {
528 return new StringBuffer( 500 ).append( "{referenceNumber=" ).
529 append( this.ref ).append( '}' ).toString();
530
531 }
532
533
534
535
536
537
538 private static Map getCache()
539 {
540 Map cache = (Map) cacheReference.get();
541 if ( cache == null )
542 {
543 cache = Collections.synchronizedMap( new HashMap( 1024 ) );
544 cacheReference = new SoftReference( cache );
545 }
546
547 return cache;
548 }
549
550
551
552
553
554
555
556
557
558
559
560
561 public int compareTo( final Object o )
562 {
563 if ( o == null )
564 {
565 throw new NullPointerException( "o" );
566 }
567 if ( !( o instanceof Referenznummer11 ) )
568 {
569 throw new ClassCastException( o.getClass().getName() );
570 }
571
572 int result = 0;
573 final Referenznummer11 that = (Referenznummer11) o;
574
575 if ( !this.equals( that ) )
576 {
577 result = this.ref > that.ref ? 1 : -1;
578 }
579
580 return result;
581 }
582
583
584
585
586
587
588
589
590 public boolean equals( final Object o )
591 {
592 boolean equal = o == this;
593
594 if ( !equal && o instanceof Referenznummer11 )
595 {
596 equal = this.ref == ( (Referenznummer11) o ).ref;
597 }
598
599 return equal;
600 }
601
602
603
604
605
606
607 public int hashCode()
608 {
609 return (int) ( this.ref ^ ( this.ref >>> 32 ) );
610 }
611
612
613
614
615
616
617 public String toString()
618 {
619 return super.toString() + this.internalString();
620 }
621
622 }