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

COVERAGE SUMMARY FOR SOURCE FILE [DefaultPhysicalFileFactory.java]

nameclass, %method, %block, %line, %
DefaultPhysicalFileFactory.java100% (1/1)68%  (15/22)57%  (445/778)64%  (99.9/155)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class DefaultPhysicalFileFactory100% (1/1)68%  (15/22)57%  (445/778)64%  (99.9/155)
configureCoalescingCaching (FileOperations, Properties): FileOperations 0%   (0/1)0%   (0/37)0%   (0/8)
configureReadAheadCaching (FileOperations, Properties): FileOperations 0%   (0/1)0%   (0/37)0%   (0/8)
createPhysicalFile (File, int): PhysicalFile 0%   (0/1)0%   (0/7)0%   (0/1)
getIllegalAttributeTypeMessage (Locale, String, String, String): String 0%   (0/1)0%   (0/20)0%   (0/1)
getImplementation (): Implementation 0%   (0/1)0%   (0/20)0%   (0/3)
getLocale (): Locale 0%   (0/1)0%   (0/6)0%   (0/1)
getPhysicalFile (File): PhysicalFile 0%   (0/1)0%   (0/6)0%   (0/1)
createPhysicalFile (File, int, Properties): PhysicalFile 100% (1/1)22%  (7/32)29%  (2/7)
getPhysicalFile (File, Properties): PhysicalFile 100% (1/1)23%  (7/31)29%  (2/7)
analyse (File): int 100% (1/1)27%  (7/26)29%  (2/7)
assertValidProperties (): void 100% (1/1)37%  (7/19)66%  (2.7/4)
assertValidProperties (Properties): void 100% (1/1)46%  (48/105)61%  (11/18)
<static initializer> 100% (1/1)76%  (65/86)84%  (4.2/5)
getPhysicalFile (FileOperations, int, Properties): PhysicalFile 100% (1/1)83%  (55/66)86%  (12/14)
createPhysicalFile (FileOperations, int, Properties): PhysicalFile 100% (1/1)85%  (33/39)80%  (8/10)
analyse (FileOperations): int 100% (1/1)86%  (156/181)91%  (42/46)
DefaultPhysicalFileFactory (): void 100% (1/1)100% (3/3)100% (2/2)
createPhysicalFile (FileOperations, int): PhysicalFile 100% (1/1)100% (7/7)100% (1/1)
getDefaultFormat (): int 100% (1/1)100% (7/7)100% (1/1)
getDefaultProperties (): Properties 100% (1/1)100% (18/18)100% (4/4)
getPhysicalFile (FileOperations): PhysicalFile 100% (1/1)100% (6/6)100% (1/1)
getPhysicalFile (FileOperations, Properties): PhysicalFile 100% (1/1)100% (19/19)100% (5/5)

1/*
2 *  jDTAUS Banking RI DTAUS
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.dtaus.ri.zka;
22 
23import java.io.EOFException;
24import java.io.File;
25import java.io.IOException;
26import java.io.RandomAccessFile;
27import java.util.Iterator;
28import java.util.Locale;
29import java.util.Map;
30import org.jdtaus.banking.dtaus.CorruptedException;
31import org.jdtaus.banking.dtaus.PhysicalFile;
32import org.jdtaus.banking.dtaus.PhysicalFileException;
33import org.jdtaus.banking.dtaus.PhysicalFileFactory;
34import org.jdtaus.banking.dtaus.spi.Fields;
35import org.jdtaus.banking.messages.IllegalDataMessage;
36import org.jdtaus.banking.messages.IllegalFileLengthMessage;
37import org.jdtaus.core.container.ContainerFactory;
38import org.jdtaus.core.container.Implementation;
39import org.jdtaus.core.container.ModelFactory;
40import org.jdtaus.core.container.PropertyException;
41import org.jdtaus.core.io.FileOperations;
42import org.jdtaus.core.io.util.CoalescingFileOperations;
43import org.jdtaus.core.io.util.RandomAccessFileOperations;
44import org.jdtaus.core.io.util.ReadAheadFileOperations;
45import org.jdtaus.core.nio.util.Charsets;
46import org.jdtaus.core.text.Message;
47 
48/**
49 * Default {@code PhysicalFileFactory} implementation.
50 *
51 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
52 * @version $JDTAUS: DefaultPhysicalFileFactory.java 8865 2014-01-10 17:13:42Z schulte $
53 */
54public final class DefaultPhysicalFileFactory implements PhysicalFileFactory
55{
56 
57    /**
58     * Constant for the name of attribute {@code readAheadCaching}.
59     * <p>
60     * The {@code readAheadCaching} attribute is used to enabled or disable the
61     * use of a read-ahead caching algorithm. Its expected value is of type
62     * {@code Boolean}.
63     * </p>
64     */
65    public static final String ATTRIBUTE_READAHEAD_CACHING =
66        DefaultPhysicalFileFactory.class.getName() + ".readAheadCaching";
67 
68    /**
69     * Constant for the name of attribute {@code readAheadCacheSize}.
70     * <p>
71     * The {@code readAheadCacheSize} attribute is used to specify the
72     * size of the read-ahead cache. Its expected value is of type
73     * {@code Integer}.
74     * </p>
75     */
76    public static final String ATTRIBUTE_READAHEAD_CACHESIZE =
77        DefaultPhysicalFileFactory.class.getName() + ".readAheadCacheSize";
78 
79    /**
80     * Constant for the name of attribute {@code coalescingCaching}.
81     * <p>
82     * The {@code coalescingCaching} attribute is used to enabled or disable the
83     * use of a coalescing caching algorithm. Its expected value is of type
84     * {@code Boolean}.
85     * </p>
86     */
87    public static final String ATTRIBUTE_COALESCING_CACHING =
88        DefaultPhysicalFileFactory.class.getName() + ".coalescingCaching";
89 
90    /**
91     * Constant for the name of attribute {@code coalescingBlockSize}.
92     * <p>
93     * The {@code coalescingBlockSize} attribute is used to specify the
94     * value of property {@code blockSize} to use when constructing the
95     * coalescing cache implementation. Its expected value is of type
96     * {@code Integer}.
97     * </p>
98     */
99    public static final String ATTRIBUTE_COALESCING_BLOCKSIZE =
100        DefaultPhysicalFileFactory.class.getName() + ".coalescingBlockSize";
101 
102    /**
103     * Constant for the name of attribute {@code spaceCharactersAllowed}.
104     * <p>
105     * The {@code spaceCharactersAllowed} attribute is used to specify numeric
106     * fields for which space characters are to be allowed. It is used as
107     * a prefix with the hexadecimal field constant appended. Its expected value
108     * is of type {@code Boolean}.
109     * </p>
110     */
111    public static final String ATTRIBUTE_SPACE_CHARACTERS_ALLOWED =
112        DefaultPhysicalFileFactory.class.getName() + ".spaceCharactersAllowed.";
113 
114    /** Implementation meta-data. */
115    private Implementation implementation;
116 
117    public int analyse( final File file ) throws PhysicalFileException, IOException
118    {
119        if ( file == null )
120        {
121            throw new NullPointerException( "file" );
122        }
123 
124        this.assertValidProperties();
125        final FileOperations ops = new RandomAccessFileOperations( new RandomAccessFile( file, "r" ) );
126        final int format = this.analyse( ops );
127        ops.close();
128        return format;
129    }
130 
131    public int analyse( final FileOperations fileOperations ) throws PhysicalFileException, IOException
132    {
133        int blockSize = 128;
134        long remainder = 0;
135        int read = 0;
136        int ret = FORMAT_DISK;
137        int total = 0;
138 
139        final Message[] messages;
140        final byte[] buf = new byte[ 4 ];
141        final String str;
142        final long length;
143 
144        if ( fileOperations == null )
145        {
146            throw new NullPointerException( "fileOperations" );
147        }
148 
149        this.assertValidProperties();
150        length = fileOperations.getLength();
151        try
152        {
153            ThreadLocalMessages.getMessages().clear();
154            ThreadLocalMessages.setErrorsEnabled( false );
155 
156            if ( length >= 128 )
157            { // mindestens ein Disketten-Satzabschnitt.
158                // die ersten 4 Byte lesen.
159                fileOperations.setFilePointer( 0L );
160                do
161                {
162                    read = fileOperations.read( buf, total, buf.length - total );
163                    if ( read == FileOperations.EOF )
164                    {
165                        throw new EOFException();
166                    }
167                    else
168                    {
169                        total += read;
170                    }
171                }
172                while ( total < buf.length );
173 
174                // Diskettenformat prüfen "0128".
175                str = Charsets.decode( buf, "ISO646-DE" );
176                if ( "0128".equals( str ) )
177                {
178                    remainder = length % blockSize;
179                }
180                else
181                {
182                    final int size = ( ( buf[0] & 0xFF ) << 8 ) | ( buf[1] & 0xFF );
183                    if ( size == 150 )
184                    {
185                        ret = FORMAT_TAPE;
186                        blockSize = 150;
187                        remainder = 0; // Variable blocksize.
188                    }
189                    else
190                    {
191                        if ( ThreadLocalMessages.isErrorsEnabled() )
192                        {
193                            throw new CorruptedException( this.getImplementation(), 0L );
194                        }
195                        else
196                        {
197                            final Message msg = new IllegalDataMessage(
198                                Fields.FIELD_A1, IllegalDataMessage.TYPE_CONSTANT, 0L, str );
199 
200                            ThreadLocalMessages.getMessages().addMessage( msg );
201                        }
202                    }
203                }
204            }
205            else
206            {
207                if ( ThreadLocalMessages.isErrorsEnabled() )
208                {
209                    throw new CorruptedException( this.getImplementation(), length );
210                }
211                else
212                {
213                    final Message msg = new IllegalFileLengthMessage( length, blockSize );
214                    ThreadLocalMessages.getMessages().addMessage( msg );
215                }
216            }
217 
218            if ( remainder > 0 )
219            {
220                if ( ThreadLocalMessages.isErrorsEnabled() )
221                {
222                    throw new CorruptedException( this.getImplementation(), length );
223                }
224                else
225                {
226                    final Message msg = new IllegalFileLengthMessage( length, blockSize );
227                    ThreadLocalMessages.getMessages().addMessage( msg );
228                }
229            }
230 
231            messages = ThreadLocalMessages.getMessages().getMessages();
232            if ( messages.length > 0 )
233            {
234                throw new PhysicalFileException( messages );
235            }
236 
237            return ret;
238        }
239        finally
240        {
241            ThreadLocalMessages.setErrorsEnabled( true );
242        }
243    }
244 
245    public PhysicalFile createPhysicalFile( final File file, final int format )
246        throws IOException
247    {
248        return this.createPhysicalFile( file, format, this.getDefaultProperties() );
249    }
250 
251    public PhysicalFile createPhysicalFile( final File file, final int format, final java.util.Properties properties )
252        throws IOException
253    {
254        if ( file == null )
255        {
256            throw new NullPointerException( "file" );
257        }
258 
259        this.assertValidProperties();
260        this.assertValidProperties( properties );
261 
262        FileOperations ops = new RandomAccessFileOperations( new RandomAccessFile( file, "rw" ) );
263        ops = this.configureCoalescingCaching( ops, properties );
264        return this.createPhysicalFile( ops, format, properties );
265    }
266 
267    public PhysicalFile createPhysicalFile(
268        final FileOperations ops, final int format ) throws IOException
269    {
270        return this.createPhysicalFile( ops, format,
271                                        this.getDefaultProperties() );
272 
273    }
274 
275    public PhysicalFile createPhysicalFile( FileOperations ops, final int format, final java.util.Properties properties )
276        throws IOException
277    {
278        if ( ops == null )
279        {
280            throw new NullPointerException( "ops" );
281        }
282        if ( format != FORMAT_DISK && format != FORMAT_TAPE )
283        {
284            throw new IllegalArgumentException( Integer.toString( format ) );
285        }
286 
287        this.assertValidProperties();
288        this.assertValidProperties( properties );
289 
290        try
291        {
292            ops.setLength( 0L );
293            return this.getPhysicalFile( ops, format, properties );
294        }
295        catch ( PhysicalFileException e )
296        {
297            throw new AssertionError( e );
298        }
299    }
300 
301    public PhysicalFile getPhysicalFile( final File file ) throws PhysicalFileException, IOException
302    {
303        return this.getPhysicalFile( file, this.getDefaultProperties() );
304    }
305 
306    public PhysicalFile getPhysicalFile( final FileOperations ops ) throws PhysicalFileException, IOException
307    {
308        return this.getPhysicalFile( ops, this.getDefaultProperties() );
309    }
310 
311    public PhysicalFile getPhysicalFile( final FileOperations ops, final java.util.Properties properties )
312        throws PhysicalFileException, IOException
313    {
314        if ( ops == null )
315        {
316            throw new NullPointerException( "ops" );
317        }
318 
319        this.assertValidProperties();
320        this.assertValidProperties( properties );
321        return this.getPhysicalFile( ops, this.getDefaultFormat(), properties );
322    }
323 
324    public PhysicalFile getPhysicalFile( final File file, final java.util.Properties properties )
325        throws PhysicalFileException, IOException
326    {
327        if ( file == null )
328        {
329            throw new NullPointerException( "file" );
330        }
331 
332        this.assertValidProperties();
333        this.assertValidProperties( properties );
334 
335        FileOperations ops = new RandomAccessFileOperations( new RandomAccessFile( file, "rw" ) );
336        ops = this.configureReadAheadCaching( ops, properties );
337        return this.getPhysicalFile( ops, properties );
338    }
339 
340    /**
341     * Checks configured properties.
342     *
343     * @throws PropertyException for illegal property values.
344     */
345    private void assertValidProperties()
346    {
347        final int defaultFormat = this.getDefaultFormat();
348        if ( defaultFormat != FORMAT_DISK && defaultFormat != FORMAT_TAPE )
349        {
350            throw new PropertyException( "defaultFormat", new Integer( defaultFormat ) );
351        }
352    }
353 
354    /**
355     * Checks that given properties are valid.
356     *
357     * @param properties the properties to check.
358     *
359     * @throws NullPointerException if {@code properties} is {@code null}.
360     * @throws IllegalArgumentException if {@code properties} holds invalid values.
361     */
362    private void assertValidProperties( final java.util.Properties properties )
363    {
364        if ( properties == null )
365        {
366            throw new NullPointerException( "properties" );
367        }
368 
369        for ( Iterator it = properties.entrySet().iterator(); it.hasNext(); )
370        {
371            final Map.Entry entry = (Map.Entry) it.next();
372            final String name = (String) entry.getKey();
373            final String value = (String) entry.getValue();
374 
375            if ( name.startsWith( ATTRIBUTE_SPACE_CHARACTERS_ALLOWED ) )
376            {
377                try
378                {
379                    Integer.parseInt( name.substring( name.lastIndexOf( '.' ) + 1 ), 16 );
380                }
381                catch ( NumberFormatException e )
382                {
383                    throw (IllegalArgumentException) new IllegalArgumentException(
384                        name + ": " + e.getMessage() ).initCause( e );
385 
386                }
387            }
388 
389            if ( value != null && ( ATTRIBUTE_READAHEAD_CACHESIZE.equals( name ) ||
390                                    ATTRIBUTE_COALESCING_BLOCKSIZE.equals( name ) ) )
391            {
392                try
393                {
394                    Integer.parseInt( value );
395                }
396                catch ( NumberFormatException e )
397                {
398                    throw (IllegalArgumentException) new IllegalArgumentException( this.getIllegalAttributeTypeMessage(
399                        this.getLocale(), name, ( value != null ? value.getClass().getName() : null ),
400                        Integer.class.getName() ) ).initCause( e );
401 
402                }
403            }
404        }
405    }
406 
407    private java.util.Properties getDefaultProperties()
408    {
409        final java.util.Properties properties = new java.util.Properties();
410        properties.setProperty( ATTRIBUTE_READAHEAD_CACHING, Boolean.toString( true ) );
411        properties.setProperty( ATTRIBUTE_COALESCING_CACHING, Boolean.toString( true ) );
412        return properties;
413    }
414 
415    private FileOperations configureReadAheadCaching( FileOperations ops, final java.util.Properties properties )
416        throws IOException
417    {
418        final String readAheadCaching = properties.getProperty( ATTRIBUTE_READAHEAD_CACHING );
419        final String readAheadCacheSize = properties.getProperty( ATTRIBUTE_READAHEAD_CACHESIZE );
420        final boolean isReadAheadCaching =
421            readAheadCaching != null && Boolean.valueOf( readAheadCaching ).booleanValue();
422 
423        if ( isReadAheadCaching )
424        {
425            if ( readAheadCacheSize != null )
426            {
427                ops = new ReadAheadFileOperations( ops, Integer.parseInt( readAheadCacheSize ) );
428            }
429            else
430            {
431                ops = new ReadAheadFileOperations( ops );
432            }
433        }
434 
435        return ops;
436    }
437 
438    private FileOperations configureCoalescingCaching( FileOperations ops, final java.util.Properties properties )
439        throws IOException
440    {
441        final String coalescingCaching = properties.getProperty( ATTRIBUTE_COALESCING_CACHING );
442        final String coalescingBlockSize = properties.getProperty( ATTRIBUTE_COALESCING_BLOCKSIZE );
443        final boolean isCoalescingCaching =
444            coalescingCaching != null && Boolean.valueOf( coalescingCaching ).booleanValue();
445 
446        if ( isCoalescingCaching )
447        {
448            if ( coalescingBlockSize != null )
449            {
450                ops = new CoalescingFileOperations( ops, Integer.parseInt( coalescingBlockSize ) );
451            }
452            else
453            {
454                ops = new CoalescingFileOperations( ops );
455            }
456        }
457 
458        return ops;
459    }
460 
461    private PhysicalFile getPhysicalFile( final FileOperations ops, int format, final java.util.Properties properties )
462        throws PhysicalFileException, IOException
463    {
464        if ( ops == null )
465        {
466            throw new NullPointerException( "ops" );
467        }
468        if ( format != FORMAT_DISK && format != FORMAT_TAPE )
469        {
470            throw new IllegalArgumentException( Integer.toString( format ) );
471        }
472 
473        this.assertValidProperties( properties );
474 
475        final DefaultPhysicalFile ret;
476        final Message[] messages;
477        format = ops.getLength() > 0 ? this.analyse( ops ) : format;
478 
479        try
480        {
481            ThreadLocalMessages.getMessages().clear();
482            ThreadLocalMessages.setErrorsEnabled( false );
483            ret = new DefaultPhysicalFile( format, ops, properties );
484            messages = ThreadLocalMessages.getMessages().getMessages();
485            if ( messages.length > 0 )
486            {
487                throw new PhysicalFileException( messages );
488            }
489 
490            return ret;
491        }
492        finally
493        {
494            ThreadLocalMessages.setErrorsEnabled( true );
495        }
496    }
497 
498    protected Implementation getImplementation()
499    {
500        if ( this.implementation == null )
501        {
502            this.implementation = ModelFactory.getModel().getModules().
503                getImplementation( DefaultPhysicalFileFactory.class.getName() );
504 
505        }
506 
507        return this.implementation;
508    }
509 
510    //--Constructors------------------------------------------------------------
511 
512// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausConstructors
513    // This section is managed by jdtaus-container-mojo.
514 
515    /** Standard implementation constructor <code>org.jdtaus.banking.dtaus.ri.zka.DefaultPhysicalFileFactory</code>. */
516    public DefaultPhysicalFileFactory()
517    {
518        super();
519    }
520 
521// </editor-fold>//GEN-END:jdtausConstructors
522 
523    //------------------------------------------------------------Constructors--
524    //--Properties--------------------------------------------------------------
525 
526// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausProperties
527    // This section is managed by jdtaus-container-mojo.
528 
529    /**
530     * Gets the value of property <code>defaultFormat</code>.
531     *
532     * @return The format to use for empty files.
533     */
534    private int getDefaultFormat()
535    {
536        return ( (java.lang.Integer) ContainerFactory.getContainer().
537            getProperty( this, "defaultFormat" ) ).intValue();
538 
539    }
540 
541// </editor-fold>//GEN-END:jdtausProperties
542 
543    //--------------------------------------------------------------Properties--
544    //--Dependencies------------------------------------------------------------
545 
546// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausDependencies
547    // This section is managed by jdtaus-container-mojo.
548 
549    /**
550     * Gets the configured <code>Locale</code> implementation.
551     *
552     * @return The configured <code>Locale</code> implementation.
553     */
554    private Locale getLocale()
555    {
556        return (Locale) ContainerFactory.getContainer().
557            getDependency( this, "Locale" );
558 
559    }
560 
561// </editor-fold>//GEN-END:jdtausDependencies
562 
563    //------------------------------------------------------------Dependencies--
564    //--Messages----------------------------------------------------------------
565 
566// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausMessages
567    // This section is managed by jdtaus-container-mojo.
568 
569    /**
570     * Gets the text of message <code>illegalAttributeType</code>.
571     * <blockquote><pre>Ungültiger Attribut-Typ {1} für Attribut {0}. Erwartet Typ {2}.</pre></blockquote>
572     * <blockquote><pre>The type {1} for attribute {0} is invalid. Expected {2}.</pre></blockquote>
573     *
574     * @param locale The locale of the message instance to return.
575     * @param attributeName format parameter.
576     * @param typeName format parameter.
577     * @param expectedTypeName format parameter.
578     *
579     * @return the text of message <code>illegalAttributeType</code>.
580     */
581    private String getIllegalAttributeTypeMessage( final Locale locale,
582            final java.lang.String attributeName,
583            final java.lang.String typeName,
584            final java.lang.String expectedTypeName )
585    {
586        return ContainerFactory.getContainer().
587            getMessage( this, "illegalAttributeType", locale,
588                new Object[]
589                {
590                    attributeName,
591                    typeName,
592                    expectedTypeName
593                });
594 
595    }
596 
597// </editor-fold>//GEN-END:jdtausMessages
598 
599    //----------------------------------------------------------------Messages--
600}

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