View Javadoc

1   /*
2    *  jDTAUS Banking RI Bankleitzahlenverzeichnis
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   */
21  package org.jdtaus.banking.ri.blzdirectory;
22  
23  import java.io.IOException;
24  import java.net.URL;
25  import java.text.DateFormat;
26  import java.text.DecimalFormat;
27  import java.text.NumberFormat;
28  import java.text.ParseException;
29  import java.text.SimpleDateFormat;
30  import java.util.ArrayList;
31  import java.util.Collection;
32  import java.util.Date;
33  import java.util.HashMap;
34  import java.util.Iterator;
35  import java.util.LinkedList;
36  import java.util.List;
37  import java.util.Locale;
38  import java.util.Map;
39  import java.util.regex.Pattern;
40  import java.util.regex.PatternSyntaxException;
41  import org.jdtaus.banking.Bankleitzahl;
42  import org.jdtaus.banking.BankleitzahlExpirationException;
43  import org.jdtaus.banking.BankleitzahlInfo;
44  import org.jdtaus.banking.BankleitzahlenVerzeichnis;
45  import org.jdtaus.banking.messages.OutdatedBankleitzahlenVerzeichnisMessage;
46  import org.jdtaus.banking.messages.ReadsBankleitzahlenDateiMessage;
47  import org.jdtaus.banking.messages.SearchesBankleitzahlInfosMessage;
48  import org.jdtaus.banking.util.BankleitzahlenDatei;
49  import org.jdtaus.core.container.ContainerFactory;
50  import org.jdtaus.core.container.PropertyException;
51  import org.jdtaus.core.logging.spi.Logger;
52  import org.jdtaus.core.monitor.spi.Task;
53  import org.jdtaus.core.monitor.spi.TaskMonitor;
54  import org.jdtaus.core.text.Message;
55  import org.jdtaus.core.text.MessageEvent;
56  import org.jdtaus.core.text.spi.ApplicationLogger;
57  
58  /**
59   * {@code BankleitzahlenVerzeichnis} implementation backed by bank files.
60   * <p>This implementation uses bank file resources provided by any available {@link BankfileProvider}
61   * implementation.</p>
62   *
63   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
64   * @version $JDTAUS: BankfileBankleitzahlenVerzeichnis.java 8811 2012-12-04 00:48:00Z schulte $
65   */
66  public class BankfileBankleitzahlenVerzeichnis implements BankleitzahlenVerzeichnis
67  {
68  
69      /** Flag indicating that initialization has been performed. */
70      private boolean initialized;
71  
72      /** {@code BankleitzahlenDatei} delegate. */
73      private BankleitzahlenDatei bankFile;
74  
75      /** Maps bank codes to a list of outdated records. */
76      private final Map outdated = new HashMap( 5000 );
77  
78      /** Date of expiration. */
79      private Date dateOfExpiration;
80  
81      /** Timestamp providers got checked for modifications. */
82      private long lastModificationCheck = System.currentTimeMillis();
83  
84      /** Number of milliseconds to pass before providers are checked for modifications. */
85      private Long reloadIntervalMillis;
86  
87      /** Provider checked for modifications. */
88      private BankfileProvider provider;
89  
90      /** Last modification of the provider checked for modifications. */
91      private long lastModifiedMillis;
92  
93      /** Number of bank codes for which progress monitoring gets enabled. */
94      private Long monitoringThreshold;
95  
96      /**
97       * Creates a new {@code BankfileBankleitzahlenVerzeichnis} instance taking the number of milliseconds to pass before
98       * resources are checked for modifications and the number of bank codes for which progress monitoring gets enabled.
99       *
100      * @param reloadIntervalMillis Number of milliseconds to pass before resources are checked for modifications.
101      * @param monitoringThreshold Number of bank codes for which progress monitoring gets enabled.
102      */
103     public BankfileBankleitzahlenVerzeichnis( final long reloadIntervalMillis, final long monitoringThreshold )
104     {
105         this();
106         if ( reloadIntervalMillis > 0 )
107         {
108             this.reloadIntervalMillis = new Long( reloadIntervalMillis );
109         }
110         if ( monitoringThreshold > 0 )
111         {
112             this.monitoringThreshold = new Long( monitoringThreshold );
113         }
114     }
115 
116     /**
117      * Gets the number of milliseconds to pass before providers are checked for modifications.
118      *
119      * @return The number of milliseconds to pass before providers are checked for modifications.
120      */
121     public long getReloadIntervalMillis()
122     {
123         if ( this.reloadIntervalMillis == null )
124         {
125             this.reloadIntervalMillis = this.getDefaultReloadIntervalMillis();
126         }
127 
128         return this.reloadIntervalMillis.longValue();
129     }
130 
131     /**
132      * Gets the number of bank codes for which progress monitoring gets enabled.
133      *
134      * @return The number of bank codes for which progress monitoring gets enabled.
135      */
136     public long getMonitoringThreshold()
137     {
138         if ( this.monitoringThreshold == null )
139         {
140             this.monitoringThreshold = this.getDefaultMonitoringThreshold();
141         }
142 
143         return this.monitoringThreshold.longValue();
144     }
145 
146     public Date getDateOfExpiration()
147     {
148         this.assertValidProperties();
149         this.assertInitialized();
150         return (Date) this.dateOfExpiration.clone();
151     }
152 
153     public BankleitzahlInfo getHeadOffice( final Bankleitzahl bankCode ) throws BankleitzahlExpirationException
154     {
155         if ( bankCode == null )
156         {
157             throw new NullPointerException( "bankCode" );
158         }
159 
160         this.assertValidProperties();
161         this.assertInitialized();
162 
163         BankleitzahlInfo ret = null;
164         final BankleitzahlInfo[] matches = this.findByBankCode( bankCode, false );
165 
166         if ( matches.length == 1 )
167         {
168             ret = matches[0];
169         }
170         else
171         {
172             this.checkReplacement( bankCode );
173         }
174 
175         return ret;
176     }
177 
178     public BankleitzahlInfo[] getBranchOffices( final Bankleitzahl bankCode ) throws BankleitzahlExpirationException
179     {
180         if ( bankCode == null )
181         {
182             throw new NullPointerException( "bankCode" );
183         }
184 
185         this.assertValidProperties();
186         this.assertInitialized();
187 
188         final BankleitzahlInfo[] matches = this.findByBankCode( bankCode, true );
189 
190         if ( matches.length == 0 )
191         {
192             this.checkReplacement( bankCode );
193         }
194 
195         return matches;
196     }
197 
198     public final BankleitzahlInfo[] search( final String name, final String postalCode, final String city,
199                                             final boolean branchOffices )
200     {
201         return this.searchBankleitzahlInfos( name, postalCode, city, Boolean.valueOf( !branchOffices ),
202                                              Boolean.valueOf( branchOffices ) );
203 
204     }
205 
206     public BankleitzahlInfo[] searchBankleitzahlInfos( final String name, final String postalCode, final String city,
207                                                        final Boolean headOffices, final Boolean branchOffices )
208     {
209         this.assertValidProperties();
210         this.assertInitialized();
211 
212         final BankleitzahlInfo[] records =
213             this.bankFile == null ? new BankleitzahlInfo[ 0 ] : this.bankFile.getRecords();
214 
215         final Collection col = new ArrayList( records.length );
216 
217         if ( records.length > 0 )
218         {
219             final Task task = new Task();
220             task.setCancelable( true );
221             task.setDescription( new SearchesBankleitzahlInfosMessage() );
222             task.setIndeterminate( false );
223             task.setMinimum( 0 );
224             task.setMaximum( records.length - 1 );
225             task.setProgress( 0 );
226 
227             try
228             {
229                 if ( task.getMaximum() > this.getMonitoringThreshold() )
230                 {
231                     this.getTaskMonitor().monitor( task );
232                 }
233 
234                 final NumberFormat plzFmt = new DecimalFormat( "00000" );
235                 final Pattern namePattern =
236                     name != null ? Pattern.compile( ".*" + name.toUpperCase() + ".*" ) : null;
237 
238                 final Pattern postalPattern =
239                     postalCode != null ? Pattern.compile( ".*" + postalCode.toUpperCase() + ".*" ) : null;
240 
241                 final Pattern cityPattern =
242                     city != null ? Pattern.compile( ".*" + city.toUpperCase() + ".*" ) : null;
243 
244                 for ( int i = records.length - 1; i >= 0 && !task.isCancelled(); i-- )
245                 {
246                     final String plz = plzFmt.format( records[i].getPostalCode() );
247                     task.setProgress( task.getMaximum() - i );
248 
249                     if ( ( namePattern == null
250                            ? true : namePattern.matcher( records[i].getName().toUpperCase() ).matches() )
251                          && ( postalPattern == null
252                               ? true : postalPattern.matcher( plz ).matches() )
253                          && ( cityPattern == null
254                               ? true : cityPattern.matcher( records[i].getCity().toUpperCase() ).matches() )
255                          && ( headOffices == null
256                               ? true : records[i].isHeadOffice() == headOffices.booleanValue() )
257                          && ( branchOffices == null
258                               ? true : records[i].isHeadOffice() != branchOffices.booleanValue() ) )
259                     {
260                         col.add( records[i].clone() );
261                     }
262                 }
263 
264                 if ( task.isCancelled() )
265                 {
266                     col.clear();
267                 }
268             }
269             catch ( final PatternSyntaxException e )
270             {
271                 throw (IllegalArgumentException) new IllegalArgumentException( e.getMessage() ).initCause( e );
272             }
273             finally
274             {
275                 if ( task.getMaximum() > this.getMonitoringThreshold() )
276                 {
277                     this.getTaskMonitor().finish( task );
278                 }
279             }
280         }
281 
282         return (BankleitzahlInfo[]) col.toArray( new BankleitzahlInfo[ col.size() ] );
283     }
284 
285     /**
286      * Initializes the instance.
287      *
288      * @throws RuntimeException if initialization fails.
289      *
290      * @see #assertValidProperties()
291      */
292     private synchronized void assertInitialized()
293     {
294         Task task = null;
295         boolean logExpirationMessage = false;
296 
297         try
298         {
299             if ( this.provider == null
300                  || System.currentTimeMillis() - this.lastModificationCheck > this.getReloadIntervalMillis() )
301             {
302                 this.lastModificationCheck = System.currentTimeMillis();
303                 if ( this.provider == null || this.provider.getLastModifiedMillis() != this.lastModifiedMillis )
304                 {
305                     this.outdated.clear();
306                     this.bankFile = null;
307                     this.dateOfExpiration = null;
308                     this.initialized = false;
309 
310                     if ( this.provider != null )
311                     {
312                         this.getLogger().info( this.getReloadInfoMessage( this.getLocale(), new Date(
313                             this.lastModifiedMillis ), new Date( this.provider.getLastModifiedMillis() ) ) );
314 
315                     }
316                 }
317             }
318 
319             if ( !this.initialized )
320             {
321                 final DateFormat dateFormat = new SimpleDateFormat( this.getDateOfExpirationPattern() );
322                 this.dateOfExpiration = dateFormat.parse( this.getDateOfExpirationText() );
323                 final BankfileProvider bankfileProvider = this.getLatestBankfileProvider();
324 
325                 if ( bankfileProvider != null && bankfileProvider.getBankfileCount() > 0 )
326                 {
327                     this.provider = bankfileProvider;
328                     this.lastModifiedMillis = bankfileProvider.getLastModifiedMillis();
329                     this.dateOfExpiration =
330                         bankfileProvider.getDateOfExpiration( bankfileProvider.getBankfileCount() - 1 );
331 
332                     final URL[] rsrc = new URL[ bankfileProvider.getBankfileCount() ];
333                     for ( int i = 0; i < rsrc.length; i++ )
334                     {
335                         rsrc[i] = bankfileProvider.getBankfile( i );
336                     }
337 
338                     task = new Task();
339                     task.setIndeterminate( false );
340                     task.setCancelable( false );
341                     task.setDescription( new ReadsBankleitzahlenDateiMessage() );
342                     task.setMinimum( 0 );
343                     task.setProgress( 0 );
344                     task.setMaximum( rsrc.length );
345                     this.getTaskMonitor().monitor( task );
346 
347                     int progress = 0;
348                     long processedRecords = 0L;
349                     task.setProgress( progress++ );
350                     this.bankFile = new BankleitzahlenDatei( rsrc[0] );
351                     processedRecords += this.bankFile.getRecords().length;
352                     for ( int i = 1; i < rsrc.length; i++ )
353                     {
354                         task.setProgress( progress++ );
355                         final BankleitzahlenDatei update = new BankleitzahlenDatei( rsrc[i] );
356 
357                         // Build mapping of outdated records.
358                         final BankleitzahlInfo[] records = this.bankFile.getRecords();
359 
360                         for ( int j = records.length - 1; j >= 0; j-- )
361                         {
362                             if ( records[j].getChangeLabel() == 'D'
363                                  && update.getRecord( records[j].getSerialNumber() ) == null )
364                             {
365                                 List l = (List) this.outdated.get( records[j].getBankCode() );
366 
367                                 if ( l == null )
368                                 {
369                                     l = new LinkedList();
370                                     this.outdated.put( records[j].getBankCode(), l );
371                                 }
372 
373                                 l.add( records[j] );
374                             }
375                         }
376 
377                         this.bankFile.update( update );
378                         processedRecords += update.getRecords().length;
379                     }
380 
381                     // Remove all outdated records for which another record with the same Bankleitzahl still exists.
382                     for ( final Iterator it = this.outdated.keySet().iterator(); it.hasNext(); )
383                     {
384                         final Bankleitzahl key = (Bankleitzahl) it.next();
385                         if ( this.findByBankCode( key, false ).length > 0 )
386                         {
387                             it.remove();
388                         }
389                     }
390 
391                     // Log outdated records.
392                     if ( this.getLogger().isDebugEnabled() )
393                     {
394                         for ( final Iterator it = this.outdated.keySet().iterator(); it.hasNext(); )
395                         {
396                             final Bankleitzahl blz = (Bankleitzahl) it.next();
397                             this.getLogger().debug( this.getOutdatedInfoMessage(
398                                 this.getLocale(), blz.format( Bankleitzahl.LETTER_FORMAT ) ) );
399 
400                         }
401                     }
402 
403                     logExpirationMessage = true;
404                     this.initialized = true;
405 
406                     this.getLogger().info( this.getBankfileInfoMessage(
407                         this.getLocale(), new Long( processedRecords ), new Integer( rsrc.length ) ) );
408 
409                 }
410                 else
411                 {
412                     this.getLogger().warn( this.getNoBankfilesFoundMessage( this.getLocale() ) );
413                 }
414             }
415         }
416         catch ( final ParseException e )
417         {
418             throw new RuntimeException( e );
419         }
420         catch ( final IOException e )
421         {
422             throw new RuntimeException( e );
423         }
424         finally
425         {
426             if ( task != null )
427             {
428                 this.getTaskMonitor().finish( task );
429             }
430         }
431 
432         // Log an application message if the directory is outdated.
433         if ( logExpirationMessage )
434         {
435             if ( new Date().after( this.getDateOfExpiration() ) )
436             {
437                 this.getApplicationLogger().log( new MessageEvent( this, new Message[]
438                     {
439                         new OutdatedBankleitzahlenVerzeichnisMessage( this.getDateOfExpiration() )
440                     }, MessageEvent.WARNING ) );
441 
442             }
443         }
444     }
445 
446     /**
447      * Checks configured properties.
448      *
449      * @throws PropertyException if configured properties hold invalid values.
450      */
451     private void assertValidProperties()
452     {
453         if ( this.getReloadIntervalMillis() < 0L )
454         {
455             throw new PropertyException( "reloadIntervalMillis", Long.toString( this.getReloadIntervalMillis() ) );
456         }
457         if ( this.getDateOfExpirationText() == null || this.getDateOfExpirationText().length() == 0 )
458         {
459             throw new PropertyException( "dateOfExpirationText", this.getDateOfExpirationText() );
460         }
461         if ( this.getDateOfExpirationPattern() == null || this.getDateOfExpirationPattern().length() == 0 )
462         {
463             throw new PropertyException( "dateOfExpirationPattern", this.getDateOfExpirationPattern() );
464         }
465 
466         try
467         {
468             final DateFormat dateFormat = new SimpleDateFormat( this.getDateOfExpirationPattern() );
469             dateFormat.parse( this.getDateOfExpirationText() );
470         }
471         catch ( final ParseException e )
472         {
473             throw new PropertyException( "dateOfExpirationText", this.getDateOfExpirationText(), e );
474         }
475     }
476 
477     /**
478      * Throws a {@code BankleitzahlExpirationException} if {@code bankCode} is outdated and if a valid replacement
479      * record exists in the directory.
480      *
481      * @param bankCode the Bankleitzahl to check for expiration.
482      *
483      * @throws NullPointerException if {@code bankCode} is {@code null}.
484      */
485     private void checkReplacement( final Bankleitzahl bankCode ) throws BankleitzahlExpirationException
486     {
487         if ( bankCode == null )
488         {
489             throw new NullPointerException( "bankCode" );
490         }
491 
492         final List l = (List) this.outdated.get( bankCode );
493 
494         if ( l != null )
495         {
496             // Finds the most recent record specifying a replacing Bankleitzahl.
497             BankleitzahlInfo current = null;
498             BankleitzahlInfo record = null;
499 
500             for ( final Iterator it = l.iterator(); it.hasNext(); )
501             {
502                 current = (BankleitzahlInfo) it.next();
503                 if ( current.getReplacingBankCode() != null )
504                 {
505                     record = current;
506                 }
507             }
508 
509             // Only throw an exception for records specifying a replacing Bankleitzahl which is not outdated.
510             if ( record != null )
511             {
512                 final BankleitzahlInfo[] replacement = this.findByBankCode( record.getReplacingBankCode(), false );
513                 assert replacement.length == 0 || replacement.length == 1 :
514                     "Multiple head offices for '" + record.getReplacingBankCode() + "'.";
515 
516                 if ( replacement.length == 1 )
517                 {
518                     throw new BankleitzahlExpirationException( record, replacement[0] );
519                 }
520             }
521         }
522     }
523 
524     /**
525      * Gets the {@code BankfileProvider} with the latest date of expiration from the available
526      * {@code BankfileProvider}s.
527      *
528      * @return The {@code BankfileProvider} with the latest date of expiration or {@code null}, if no providers are
529      * available.
530      *
531      * @throws IOException if getting the provider fails.
532      *
533      * @see BankfileProvider
534      */
535     private BankfileProvider getLatestBankfileProvider() throws IOException
536     {
537         final BankfileProvider[] providers = this.getBankfileProvider();
538         BankfileProvider latest = null;
539 
540         for ( int i = providers.length - 1; i >= 0; i-- )
541         {
542             if ( providers[i].getBankfileCount() > 0
543                  && ( latest == null || latest.getDateOfExpiration( latest.getBankfileCount() - 1 ).
544                 before( providers[i].getDateOfExpiration( providers[i].getBankfileCount() - 1 ) ) ) )
545             {
546                 latest = providers[i];
547             }
548         }
549 
550         return latest;
551     }
552 
553     /**
554      * Gets all records matching {@code bankCode} with {@code isHeadOffice() != branchOffices}.
555      *
556      * @param bankCode the bank code to return matching records for.
557      * @param branchOffices {@code true} to return all known branch offices matching {@code bankCode}; {@code false} to
558      * return all known head offices matching {@code bankCode}.
559      */
560     private BankleitzahlInfo[] findByBankCode( final Bankleitzahl bankCode, final boolean branchOffices )
561     {
562         final BankleitzahlInfo[] records =
563             this.bankFile == null ? new BankleitzahlInfo[ 0 ] : this.bankFile.getRecords();
564 
565         final Collection col = new ArrayList( records.length );
566 
567         for ( int i = records.length - 1; i >= 0; i-- )
568         {
569             if ( records[i].getBankCode().equals( bankCode ) && records[i].isHeadOffice() != branchOffices
570                  && !col.add( records[i] ) )
571             {
572                 throw new IllegalStateException( this.getDuplicateRecordMessage(
573                     this.getLocale(), records[i].getSerialNumber(), bankCode.format( Bankleitzahl.LETTER_FORMAT ) ) );
574 
575             }
576         }
577 
578         return (BankleitzahlInfo[]) col.toArray( new BankleitzahlInfo[ col.size() ] );
579     }
580 
581     //--Constructors------------------------------------------------------------
582 
583 // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausConstructors
584     // This section is managed by jdtaus-container-mojo.
585 
586     /** Standard implementation constructor <code>org.jdtaus.banking.ri.blzdirectory.BankfileBankleitzahlenVerzeichnis</code>. */
587     public BankfileBankleitzahlenVerzeichnis()
588     {
589         super();
590     }
591 
592 // </editor-fold>//GEN-END:jdtausConstructors
593 
594     //------------------------------------------------------------Constructors--
595     //--Dependencies------------------------------------------------------------
596 
597 // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausDependencies
598     // This section is managed by jdtaus-container-mojo.
599 
600     /**
601      * Gets the configured <code>Logger</code> implementation.
602      *
603      * @return The configured <code>Logger</code> implementation.
604      */
605     private Logger getLogger()
606     {
607         return (Logger) ContainerFactory.getContainer().
608             getDependency( this, "Logger" );
609 
610     }
611 
612     /**
613      * Gets the configured <code>ApplicationLogger</code> implementation.
614      *
615      * @return The configured <code>ApplicationLogger</code> implementation.
616      */
617     private ApplicationLogger getApplicationLogger()
618     {
619         return (ApplicationLogger) ContainerFactory.getContainer().
620             getDependency( this, "ApplicationLogger" );
621 
622     }
623 
624     /**
625      * Gets the configured <code>TaskMonitor</code> implementation.
626      *
627      * @return The configured <code>TaskMonitor</code> implementation.
628      */
629     private TaskMonitor getTaskMonitor()
630     {
631         return (TaskMonitor) ContainerFactory.getContainer().
632             getDependency( this, "TaskMonitor" );
633 
634     }
635 
636     /**
637      * Gets the configured <code>BankfileProvider</code> implementation.
638      *
639      * @return The configured <code>BankfileProvider</code> implementation.
640      */
641     private BankfileProvider[] getBankfileProvider()
642     {
643         return (BankfileProvider[]) ContainerFactory.getContainer().
644             getDependency( this, "BankfileProvider" );
645 
646     }
647 
648     /**
649      * Gets the configured <code>Locale</code> implementation.
650      *
651      * @return The configured <code>Locale</code> implementation.
652      */
653     private Locale getLocale()
654     {
655         return (Locale) ContainerFactory.getContainer().
656             getDependency( this, "Locale" );
657 
658     }
659 
660 // </editor-fold>//GEN-END:jdtausDependencies
661 
662     //------------------------------------------------------------Dependencies--
663     //--Properties--------------------------------------------------------------
664 
665 // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausProperties
666     // This section is managed by jdtaus-container-mojo.
667 
668     /**
669      * Gets the value of property <code>defaultReloadIntervalMillis</code>.
670      *
671      * @return Default number of milliseconds to pass before providers are checked for modifications.
672      */
673     private java.lang.Long getDefaultReloadIntervalMillis()
674     {
675         return (java.lang.Long) ContainerFactory.getContainer().
676             getProperty( this, "defaultReloadIntervalMillis" );
677 
678     }
679 
680     /**
681      * Gets the value of property <code>defaultMonitoringThreshold</code>.
682      *
683      * @return Default number of bank codes for which progress monitoring gets enabled.
684      */
685     private java.lang.Long getDefaultMonitoringThreshold()
686     {
687         return (java.lang.Long) ContainerFactory.getContainer().
688             getProperty( this, "defaultMonitoringThreshold" );
689 
690     }
691 
692     /**
693      * Gets the value of property <code>dateOfExpirationText</code>.
694      *
695      * @return The date of expiration of the directory.
696      */
697     private java.lang.String getDateOfExpirationText()
698     {
699         return (java.lang.String) ContainerFactory.getContainer().
700             getProperty( this, "dateOfExpirationText" );
701 
702     }
703 
704     /**
705      * Gets the value of property <code>dateOfExpirationPattern</code>.
706      *
707      * @return Format pattern of the date of expiration property.
708      */
709     private java.lang.String getDateOfExpirationPattern()
710     {
711         return (java.lang.String) ContainerFactory.getContainer().
712             getProperty( this, "dateOfExpirationPattern" );
713 
714     }
715 
716 // </editor-fold>//GEN-END:jdtausProperties
717 
718     //--------------------------------------------------------------Properties--
719     //--Messages----------------------------------------------------------------
720 
721 // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausMessages
722     // This section is managed by jdtaus-container-mojo.
723 
724     /**
725      * Gets the text of message <code>outdatedInfo</code>.
726      * <blockquote><pre>Bankleitzahl {0} ist veraltet.</pre></blockquote>
727      * <blockquote><pre>Bankleitzahl {0} is outdated.</pre></blockquote>
728      *
729      * @param locale The locale of the message instance to return.
730      * @param bankleitzahl format parameter.
731      *
732      * @return the text of message <code>outdatedInfo</code>.
733      */
734     private String getOutdatedInfoMessage( final Locale locale,
735             final java.lang.String bankleitzahl )
736     {
737         return ContainerFactory.getContainer().
738             getMessage( this, "outdatedInfo", locale,
739                 new Object[]
740                 {
741                     bankleitzahl
742                 });
743 
744     }
745 
746     /**
747      * Gets the text of message <code>duplicateRecord</code>.
748      * <blockquote><pre>Mehrere Bankleitzahlendatei-Datensätze mit Seriennummer {0,number} während der Suche nach Bankleitzahl {1}.</pre></blockquote>
749      * <blockquote><pre>Multiple bankfile records with serial number {0,number} detected during searching the directory for bankcode {1}.</pre></blockquote>
750      *
751      * @param locale The locale of the message instance to return.
752      * @param serialNumber format parameter.
753      * @param bankleitzahl format parameter.
754      *
755      * @return the text of message <code>duplicateRecord</code>.
756      */
757     private String getDuplicateRecordMessage( final Locale locale,
758             final java.lang.Number serialNumber,
759             final java.lang.String bankleitzahl )
760     {
761         return ContainerFactory.getContainer().
762             getMessage( this, "duplicateRecord", locale,
763                 new Object[]
764                 {
765                     serialNumber,
766                     bankleitzahl
767                 });
768 
769     }
770 
771     /**
772      * Gets the text of message <code>bankfileInfo</code>.
773      * <blockquote><pre>{1,choice,0#Keine Bankleitzahlendatei|1#Eine Bankleitzahlendatei|1<{1} Bankleitzahlendateien} gelesen. {0,choice,0#Keine Datensätze|1#Einen Datensatz|1<{0} Datensätze} verarbeitet.</pre></blockquote>
774      * <blockquote><pre>Read {1,choice,0#no bankfile|1#one bankfile|1<{1} bankfiles}. Processed {0,choice,0#no entities|1#one entity|1<{0} entities}.</pre></blockquote>
775      *
776      * @param locale The locale of the message instance to return.
777      * @param entityCount format parameter.
778      * @param bankfileCount format parameter.
779      *
780      * @return the text of message <code>bankfileInfo</code>.
781      */
782     private String getBankfileInfoMessage( final Locale locale,
783             final java.lang.Number entityCount,
784             final java.lang.Number bankfileCount )
785     {
786         return ContainerFactory.getContainer().
787             getMessage( this, "bankfileInfo", locale,
788                 new Object[]
789                 {
790                     entityCount,
791                     bankfileCount
792                 });
793 
794     }
795 
796     /**
797      * Gets the text of message <code>reloadInfo</code>.
798      * <blockquote><pre>Änderungszeitstempel des Bankleitzahlen-Providers von ''{0,date} {0,time}'' zu ''{1,date} {1,time}''. Lädt neue Bankleitzahlen.</pre></blockquote>
799      * <blockquote><pre>Provider's last modification timestamp changed from ''{0,date} {0,time}'' to ''{1,date} {1,time}''. Loading new bankcodes.</pre></blockquote>
800      *
801      * @param locale The locale of the message instance to return.
802      * @param lastModification format parameter.
803      * @param lastProviderModification format parameter.
804      *
805      * @return the text of message <code>reloadInfo</code>.
806      */
807     private String getReloadInfoMessage( final Locale locale,
808             final java.util.Date lastModification,
809             final java.util.Date lastProviderModification )
810     {
811         return ContainerFactory.getContainer().
812             getMessage( this, "reloadInfo", locale,
813                 new Object[]
814                 {
815                     lastModification,
816                     lastProviderModification
817                 });
818 
819     }
820 
821     /**
822      * Gets the text of message <code>noBankfilesFound</code>.
823      * <blockquote><pre>Keine Bankleitzahlendateien gefunden.</pre></blockquote>
824      * <blockquote><pre>No bankcode files found.</pre></blockquote>
825      *
826      * @param locale The locale of the message instance to return.
827      *
828      * @return the text of message <code>noBankfilesFound</code>.
829      */
830     private String getNoBankfilesFoundMessage( final Locale locale )
831     {
832         return ContainerFactory.getContainer().
833             getMessage( this, "noBankfilesFound", locale, null );
834 
835     }
836 
837 // </editor-fold>//GEN-END:jdtausMessages
838 
839     //----------------------------------------------------------------Messages--
840 }