EMMA Coverage Report (generated Tue Dec 09 03:51:57 CET 2014)
[all classes][org.jdtaus.banking]

COVERAGE SUMMARY FOR SOURCE FILE [Referenznummer10.java]

nameclass, %method, %block, %line, %
Referenznummer10.java100% (1/1)76%  (16/21)86%  (579/671)85%  (126.6/149)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Referenznummer10100% (1/1)76%  (16/21)86%  (579/671)85%  (126.6/149)
doubleValue (): double 0%   (0/1)0%   (0/4)0%   (0/1)
floatValue (): float 0%   (0/1)0%   (0/4)0%   (0/1)
intValue (): int 0%   (0/1)0%   (0/4)0%   (0/1)
toString (Referenznummer10): String 0%   (0/1)0%   (0/11)0%   (0/3)
valueOf (String): Referenznummer10 0%   (0/1)0%   (0/12)0%   (0/3)
Referenznummer10 (Number): void 100% (1/1)62%  (10/16)80%  (4/5)
valueOf (Number): Referenznummer10 100% (1/1)83%  (24/29)88%  (7/8)
format (int, StringBuffer): StringBuffer 100% (1/1)85%  (64/75)86%  (12/14)
parse (String, ParsePosition): Referenznummer10 100% (1/1)88%  (187/213)88%  (59/67)
parse (String): Referenznummer10 100% (1/1)91%  (50/55)90%  (9/10)
checkReferenznummer10 (Number): boolean 100% (1/1)92%  (23/25)96%  (4.8/5)
equals (Object): boolean 100% (1/1)92%  (23/25)95%  (3.8/4)
<static initializer> 100% (1/1)100% (49/49)100% (2/2)
compareTo (Object): int 100% (1/1)100% (38/38)100% (9/9)
format (int): String 100% (1/1)100% (8/8)100% (1/1)
getCache (): Map 100% (1/1)100% (19/19)100% (5/5)
hashCode (): int 100% (1/1)100% (9/9)100% (1/1)
internalString (): String 100% (1/1)100% (13/13)100% (1/1)
longValue (): long 100% (1/1)100% (3/3)100% (1/1)
toDigits (long): int [] 100% (1/1)100% (48/48)100% (6/6)
toString (): String 100% (1/1)100% (11/11)100% (1/1)

1/*
2 *  jDTAUS Banking API
3 *  Copyright (C) 2005 Christian Schulte
4 *  <cs@schulte.it>
5 *
6 *  This library is free software; you can redistribute it and/or
7 *  modify it under the terms of the GNU Lesser General Public
8 *  License as published by the Free Software Foundation; either
9 *  version 2.1 of the License, or any later version.
10 *
11 *  This library is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 *  Lesser General Public License for more details.
15 *
16 *  You should have received a copy of the GNU Lesser General Public
17 *  License along with this library; if not, write to the Free Software
18 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 *
20 */
21package org.jdtaus.banking;
22 
23import java.lang.ref.Reference;
24import java.lang.ref.SoftReference;
25import java.text.DecimalFormat;
26import java.text.ParseException;
27import java.text.ParsePosition;
28import java.util.Collections;
29import java.util.HashMap;
30import java.util.Map;
31 
32/**
33 * Unique entity identifier.
34 * <p>A Referenznummer10 is a positive integer with a maximum of ten digits.</p>
35 *
36 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
37 * @version $JDTAUS: Referenznummer10.java 8661 2012-09-27 11:29:58Z schulte $
38 */
39public final class Referenznummer10 extends Number implements Comparable
40{
41 
42    /**
43     * Constant for the electronic format of a Referenznummer10.
44     * <p>The electronic format of a Referenznummer10 is a ten digit number with leading zeros omitted (e.g. 6789).</p>
45     */
46    public static final int ELECTRONIC_FORMAT = 5001;
47 
48    /**
49     * Constant for the letter format of a Referenznummer10.
50     * <p>The letter format of a Referenznummer10 is a ten digit number with leading zeros omitted separated by spaces
51     * between the first three digits and the second three digits, the second three digits and the third three digits,
52     * and between the third three digits and the last digit (e.g. 123 456 789 0).</p>
53     */
54    public static final int LETTER_FORMAT = 5002;
55 
56    /** Maximum number of digits of a Referenznummer10. */
57    public static final int MAX_DIGITS = 10;
58 
59    /** Maximum number of characters of a Referenznummer10. */
60    public static final int MAX_CHARACTERS = 13;
61 
62    /** {@code 10^0..10^9}. */
63    private static final double[] EXP10 =
64    {
65        1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000,
66        1000000000
67    };
68 
69    /** Serial version UID for backwards compatibility with 1.0.x classes. */
70    private static final long serialVersionUID = -72660089907415650L;
71 
72    /** Used to cache instances. */
73    private static volatile Reference cacheReference = new SoftReference( null );
74 
75    /**
76     * Reference code.
77     * @serial
78     */
79    private long ref;
80 
81    /**
82     * Creates a new {@code Referenznummer10} instance.
83     *
84     * @param referenceCode The long to create an instance from.
85     *
86     * @throws IllegalArgumentException if {@code referenceCode} is negative, zero or greater than 9999999999.
87     *
88     * @see #checkReferenznummer10(Number)
89     */
90    private Referenznummer10( final Number referenceCode )
91    {
92        if ( !Referenznummer10.checkReferenznummer10( referenceCode ) )
93        {
94            throw new IllegalArgumentException( referenceCode.toString() );
95        }
96 
97        this.ref = referenceCode.longValue();
98    }
99 
100    /**
101     * Parses text from a string to produce a {@code Referenznummer10}.
102     * <p>The method attempts to parse text starting at the index given by {@code pos}. If parsing succeeds, then the
103     * index of {@code pos} is updated to the index after the last character used (parsing does not necessarily use all
104     * characters up to the end of the string), and the parsed value is returned. The updated {@code pos} can be used to
105     * indicate the starting point for the next call to this method.</p>
106     *
107     * @param referenceCode A Referenznummer10 in either electronic or letter format.
108     * @param pos A {@code ParsePosition} object with index and error index information as described above.
109     *
110     * @return The parsed value, or {@code null} if the parse fails.
111     *
112     * @throws NullPointerException if either {@code referenceCode} or {@code pos} is {@code null}.
113     */
114    public static Referenznummer10 parse( final String referenceCode, final ParsePosition pos )
115    {
116        if ( referenceCode == null )
117        {
118            throw new NullPointerException( "referenceCode" );
119        }
120        if ( pos == null )
121        {
122            throw new NullPointerException( "pos" );
123        }
124 
125        Referenznummer10 ret = null;
126        boolean sawSpace = false;
127        boolean failed = false;
128 
129        final ParsePosition fmtPos = new ParsePosition( 0 );
130        final int len = referenceCode.length();
131        final int startIndex = pos.getIndex();
132        final int maxIndex = startIndex + MAX_CHARACTERS;
133        final StringBuffer digits = new StringBuffer( MAX_DIGITS );
134        int mode = ELECTRONIC_FORMAT;
135        int part = 0;
136        int partStart = 0;
137        int partEnd = 2;
138        int digit = 0;
139        int i = startIndex;
140 
141        for ( ; i < len && i < maxIndex && digits.length() < MAX_DIGITS; i++ )
142        {
143            final char c = referenceCode.charAt( i );
144 
145            if ( Character.isDigit( c ) )
146            {
147                sawSpace = false;
148 
149                if ( mode == LETTER_FORMAT )
150                {
151                    if ( digit < partStart || digit > partEnd )
152                    {
153                        failed = true;
154                    }
155                    else
156                    {
157                        digits.append( c );
158                    }
159                }
160                else
161                {
162                    digits.append( c );
163                }
164 
165                digit++;
166            }
167            else if ( c == ' ' )
168            {
169                if ( sawSpace || i == startIndex || ( mode == ELECTRONIC_FORMAT && digit != 3 ) )
170                {
171                    failed = true;
172                }
173                else
174                {
175                    mode = LETTER_FORMAT;
176                    switch ( part )
177                    {
178                        case 0:
179                            partStart = 3;
180                            partEnd = 5;
181                            break;
182                        case 1:
183                            partStart = 6;
184                            partEnd = 8;
185                            break;
186                        case 2:
187                            partStart = 9;
188                            partEnd = 9;
189                            break;
190                        default:
191                            failed = true;
192                            break;
193                    }
194                    part++;
195 
196                    if ( digit < partStart || digit > partEnd )
197                    {
198                        failed = true;
199                    }
200                }
201 
202                sawSpace = true;
203            }
204            else
205            {
206                failed = true;
207            }
208 
209            if ( failed )
210            {
211                pos.setErrorIndex( i );
212                break;
213            }
214        }
215 
216        if ( !failed )
217        {
218            final Number num = new DecimalFormat( "##########" ).parse( digits.toString(), fmtPos );
219            if ( num != null && fmtPos.getErrorIndex() == -1 )
220            {
221                final String key = num.toString();
222                ret = (Referenznummer10) getCache().get( key );
223 
224                if ( ret == null )
225                {
226                    if ( !Referenznummer10.checkReferenznummer10( num ) )
227                    {
228                        pos.setErrorIndex( startIndex );
229                        ret = null;
230                    }
231                    else
232                    {
233                        pos.setIndex( i );
234                        ret = new Referenznummer10( num );
235                        getCache().put( key, ret );
236                    }
237                }
238                else
239                {
240                    pos.setIndex( i );
241                }
242            }
243            else
244            {
245                pos.setErrorIndex( startIndex );
246            }
247        }
248 
249        return ret;
250    }
251 
252    /**
253     * Parses text from the beginning of the given string to produce a {@code Referenznummer10}.
254     * <p>Unlike the {@link #parse(String, ParsePosition)} method this method throws a {@code ParseException} if
255     * {@code referenceCode} cannot be parsed or is of invalid length.</p>
256     *
257     * @param referenceCode A Referenznummer10 in either electronic or letter format.
258     *
259     * @return The parsed value.
260     *
261     * @throws NullPointerException if {@code referenceCode} is {@code null}.
262     * @throws ParseException if the parse fails or {@code referenceCode} is of invalid length.
263     */
264    public static Referenznummer10 parse( final String referenceCode ) throws ParseException
265    {
266        if ( referenceCode == null )
267        {
268            throw new NullPointerException( "referenceCode" );
269        }
270 
271        Referenznummer10 ref = (Referenznummer10) getCache().get( referenceCode );
272 
273        if ( ref == null )
274        {
275            final ParsePosition pos = new ParsePosition( 0 );
276            ref = Referenznummer10.parse( referenceCode, pos );
277            if ( ref == null || pos.getErrorIndex() != -1 || pos.getIndex() < referenceCode.length() )
278            {
279                throw new ParseException( referenceCode,
280                                          pos.getErrorIndex() != -1 ? pos.getErrorIndex() : pos.getIndex() );
281 
282            }
283            else
284            {
285                getCache().put( referenceCode, ref );
286            }
287        }
288 
289        return ref;
290    }
291 
292    /**
293     * Returns an instance for the Referenznummer10 identified by the given number.
294     *
295     * @param referenceCode A number identifying a Referenznummer10.
296     *
297     * @return An instance for {@code referenceCode}.
298     *
299     * @throws NullPointerException if {@code referenceCode} is {@code null}.
300     * @throws IllegalArgumentException if {@code referenceCode} is negative, zero or greater than 9999999999.
301     *
302     * @see #checkReferenznummer10(Number)
303     */
304    public static Referenznummer10 valueOf( final Number referenceCode )
305    {
306        if ( referenceCode == null )
307        {
308            throw new NullPointerException( "referenceCode" );
309        }
310 
311        final String key = referenceCode.toString();
312        Referenznummer10 ret = (Referenznummer10) getCache().get( key );
313 
314        if ( ret == null )
315        {
316            ret = new Referenznummer10( referenceCode );
317            getCache().put( key, ret );
318        }
319 
320        return ret;
321    }
322 
323    /**
324     * Parses text from the beginning of the given string to produce a {@code Referenznummer10}.
325     * <p>Unlike the {@link #parse(String)} method this method throws an {@code IllegalArgumentException} if
326     * {@code referenceCode} cannot be parsed or is of invalid length.</p>
327     *
328     * @param referenceCode A Referenznummer10 in either electronic or letter format.
329     *
330     * @return The parsed value.
331     *
332     * @throws NullPointerException if {@code referenceCode} is {@code null}.
333     * @throws IllegalArgumentException if the parse fails or {@code referenceCode} is of invalid length.
334     */
335    public static Referenznummer10 valueOf( final String referenceCode )
336    {
337        try
338        {
339            return Referenznummer10.parse( referenceCode );
340        }
341        catch ( final ParseException e )
342        {
343            throw (IllegalArgumentException) new IllegalArgumentException( referenceCode ).initCause( e );
344        }
345    }
346 
347    /**
348     * Checks a given number to conform to a Referenznummer10.
349     *
350     * @param referenceCode The number to check.
351     *
352     * @return {@code true} if {@code referenceCode} is a valid Referenznummer10; {@code false} if not.
353     */
354    public static boolean checkReferenznummer10( final Number referenceCode )
355    {
356        boolean valid = referenceCode != null;
357 
358        if ( valid )
359        {
360            final long num = referenceCode.longValue();
361            valid = num >= 0L && num < 10000000000L;
362        }
363 
364        return valid;
365    }
366 
367    /**
368     * Returns this Referenznummer10 as an int value.
369     *
370     * @return This Referenznummer10 as an int value.
371     */
372    public int intValue()
373    {
374        return (int) this.ref;
375    }
376 
377    /**
378     * Returns this Referenznummer10 as a long value.
379     *
380     * @return This Referenznummer10 as a long value.
381     */
382    public long longValue()
383    {
384        return this.ref;
385    }
386 
387    /**
388     * Returns this Referenznummer10 as a float value.
389     *
390     * @return This Referenznummer10 as a float value.
391     */
392    public float floatValue()
393    {
394        return this.ref;
395    }
396 
397    /**
398     * Returns this Referenznummer10 as a double value.
399     *
400     * @return This Referenznummer10 as a double value.
401     */
402    public double doubleValue()
403    {
404        return this.ref;
405    }
406 
407    /**
408     * Formats a Referenznummer10 and appends the resulting text to the given string buffer.
409     *
410     * @param style The style to use ({@code ELECTRONIC_FORMAT} or {@code LETTER_FORMAT}).
411     * @param toAppendTo The buffer to which the formatted text is to be appended.
412     *
413     * @return The value passed in as {@code toAppendTo}.
414     *
415     * @throws NullPointerException if {@code toAppendTo} is {@code null}.
416     * @throws IllegalArgumentException if {@code style} is neither {@code ELECTRONIC_FORMAT} nor {@code LETTER_FORMAT}.
417     *
418     * @see #ELECTRONIC_FORMAT
419     * @see #LETTER_FORMAT
420     */
421    public StringBuffer format( final int style, final StringBuffer toAppendTo )
422    {
423        if ( toAppendTo == null )
424        {
425            throw new NullPointerException( "toAppendTo" );
426        }
427        if ( style != Referenznummer10.ELECTRONIC_FORMAT && style != Referenznummer10.LETTER_FORMAT )
428        {
429            throw new IllegalArgumentException( Integer.toString( style ) );
430        }
431 
432        if ( this.ref == 0L )
433        {
434            toAppendTo.append( '0' );
435        }
436        else
437        {
438            final int[] digits = Referenznummer10.toDigits( this.ref );
439            for ( int i = digits.length - 1, lastDigit = 0; i >= 0; i-- )
440            {
441                if ( digits[i] != 0 || lastDigit > 0 )
442                {
443                    toAppendTo.append( digits[i] );
444                    lastDigit++;
445                }
446 
447                if ( style == Referenznummer10.LETTER_FORMAT && ( lastDigit == 3 || lastDigit == 6 || lastDigit == 9 ) )
448                {
449                    toAppendTo.append( ' ' );
450                }
451            }
452        }
453 
454        return toAppendTo;
455    }
456 
457    /**
458     * Formats a Referenznummer10 to produce a string. Same as
459     * <blockquote>
460     * {@link #format(int, StringBuffer) format<code>(style, new StringBuffer()).toString()</code>}
461     * </blockquote>
462     *
463     * @param style The style to use ({@code ELECTRONIC_FORMAT} or {@code LETTER_FORMAT}).
464     *
465     * @return The formatted string.
466     *
467     * @throws IllegalArgumentException if {@code style} is neither {@code ELECTRONIC_FORMAT} nor {@code LETTER_FORMAT}.
468     *
469     * @see #ELECTRONIC_FORMAT
470     * @see #LETTER_FORMAT
471     */
472    public String format( final int style )
473    {
474        return this.format( style, new StringBuffer() ).toString();
475    }
476 
477    /**
478     * Formats a Referenznummer10 to produce a string. Same as
479     * <blockquote>
480     * {@link #format(int) referenznummer10.format(ELECTRONIC_FORMAT)}
481     * </blockquote>
482     *
483     * @param referenznummer10 The {@code Referenznummer10} instance to format.
484     *
485     * @return The formatted string.
486     *
487     * @throws NullPointerException if {@code referenznummer10} is {@code null}.
488     */
489    public static String toString( final Referenznummer10 referenznummer10 )
490    {
491        if ( referenznummer10 == null )
492        {
493            throw new NullPointerException( "referenznummer10" );
494        }
495 
496        return referenznummer10.format( ELECTRONIC_FORMAT );
497    }
498 
499    /**
500     * Creates an array holding the digits of {@code number}.
501     *
502     * @param number The number to return the digits for.
503     *
504     * @return An array holding the digits of {@code number}.
505     */
506    private static int[] toDigits( final long number )
507    {
508        int i;
509        int j;
510        long subst;
511        final int[] ret = new int[ MAX_DIGITS ];
512 
513        for ( i = MAX_DIGITS - 1; i >= 0; i-- )
514        {
515            for ( j = i + 1, subst = 0L; j < MAX_DIGITS; j++ )
516            {
517                subst += ret[j] * EXP10[j];
518            }
519            ret[i] = (int) Math.floor( ( number - subst ) / EXP10[i] );
520        }
521 
522        return ret;
523    }
524 
525    /**
526     * Creates a string representing the properties of the instance.
527     *
528     * @return A string representing the properties of the instance.
529     */
530    private String internalString()
531    {
532        return new StringBuffer( 500 ).append( "{referenceNumber=" ).append( this.ref ).append( '}' ).toString();
533    }
534 
535    /**
536     * Gets the current cache instance.
537     *
538     * @return Current cache instance.
539     */
540    private static Map getCache()
541    {
542        Map cache = (Map) cacheReference.get();
543        if ( cache == null )
544        {
545            cache = Collections.synchronizedMap( new HashMap( 1024 ) );
546            cacheReference = new SoftReference( cache );
547        }
548 
549        return cache;
550    }
551 
552    /**
553     * Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer
554     * as this object is less than, equal to, or greater than the specified object.<p>
555     *
556     * @param o The Object to be compared.
557     * @return  A negative integer, zero, or a positive integer as this object is less than, equal to, or greater than
558     * the specified object.
559     *
560     * @throws NullPointerException if {@code o} is {@code null}.
561     * @throws ClassCastException if the specified object's type prevents it from being compared to this Object.
562     */
563    public int compareTo( final Object o )
564    {
565        if ( o == null )
566        {
567            throw new NullPointerException( "o" );
568        }
569        if ( !( o instanceof Referenznummer10 ) )
570        {
571            throw new ClassCastException( o.getClass().getName() );
572        }
573 
574        int result = 0;
575        final Referenznummer10 that = (Referenznummer10) o;
576 
577        if ( !this.equals( that ) )
578        {
579            result = this.ref > that.ref ? 1 : -1;
580        }
581 
582        return result;
583    }
584 
585    /**
586     * Indicates whether some other object is equal to this one.
587     *
588     * @param o The reference object with which to compare.
589     *
590     * @return {@code true} if this object is the same as {@code o}; {@code false} otherwise.
591     */
592    public boolean equals( final Object o )
593    {
594        boolean equal = o == this;
595 
596        if ( !equal && o instanceof Referenznummer10 )
597        {
598            equal = this.ref == ( (Referenznummer10) o ).ref;
599        }
600 
601        return equal;
602    }
603 
604    /**
605     * Returns a hash code value for this object.
606     *
607     * @return A hash code value for this object.
608     */
609    public int hashCode()
610    {
611        return (int) ( this.ref ^ ( this.ref >>> 32 ) );
612    }
613 
614    /**
615     * Returns a string representation of the object.
616     *
617     * @return A string representation of the object.
618     */
619    public String toString()
620    {
621        return super.toString() + this.internalString();
622    }
623 
624}

[all classes][org.jdtaus.banking]
EMMA 2.1.5320 (stable) (C) Vladimir Roubtsov