View Javadoc
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   */
21  package org.jdtaus.banking.dtaus.ri.zka;
22  
23  import java.io.IOException;
24  import java.util.Arrays;
25  import java.util.Currency;
26  import java.util.Date;
27  import java.util.HashMap;
28  import java.util.Iterator;
29  import java.util.LinkedList;
30  import java.util.List;
31  import java.util.Map;
32  import org.jdtaus.banking.dtaus.Header;
33  import org.jdtaus.banking.dtaus.LogicalFile;
34  import org.jdtaus.banking.dtaus.LogicalFileType;
35  import org.jdtaus.banking.dtaus.spi.CurrencyCounter;
36  import org.jdtaus.banking.dtaus.spi.HeaderValidator;
37  import org.jdtaus.banking.dtaus.spi.IllegalHeaderException;
38  import org.jdtaus.banking.messages.CurrencyConstraintMessage;
39  import org.jdtaus.banking.messages.IllegalCurrencyMessage;
40  import org.jdtaus.banking.messages.IllegalDateMessage;
41  import org.jdtaus.banking.messages.IllegalScheduleMessage;
42  import org.jdtaus.banking.messages.TextschluesselConstraintMessage;
43  import org.jdtaus.banking.spi.CurrencyMapper;
44  import org.jdtaus.banking.spi.UnsupportedCurrencyException;
45  import org.jdtaus.core.container.ContainerFactory;
46  import org.jdtaus.core.container.PropertyException;
47  import org.jdtaus.core.logging.spi.Logger;
48  import org.jdtaus.core.messages.MandatoryPropertyMessage;
49  import org.jdtaus.core.text.Message;
50  
51  /**
52   * jDTAUS Banking SPI {@code HeaderValidator} implementation.
53   *
54   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
55   * @version $JDTAUS: DefaultHeaderValidator.java 8661 2012-09-27 11:29:58Z schulte $
56   */
57  public final class DefaultHeaderValidator implements HeaderValidator
58  {
59  
60      /** Value of property {@code maxScheduleDays} in milliseconds. */
61      private long maxScheduleDaysMillis = Long.MIN_VALUE;
62  
63      public IllegalHeaderException assertValidHeader( final Header header, IllegalHeaderException result )
64      {
65          if ( header == null )
66          {
67              throw new NullPointerException( "header" );
68          }
69  
70          this.assertValidProperties();
71          final List messages = new LinkedList();
72          final Map properties = new HashMap( 20 );
73  
74          if ( header.getCreateDate() == null )
75          {
76              properties.put( Header.PROP_CREATEDATE, new MandatoryPropertyMessage() );
77          }
78          else if ( !this.checkDate( header.getCreateDate() ) )
79          {
80              properties.put( Header.PROP_CREATEDATE, new IllegalDateMessage(
81                  header.getCreateDate(), new Date( this.getMinDateMillis() ), new Date( this.getMaxDateMillis() ) ) );
82  
83          }
84  
85          if ( header.getExecutionDate() != null && !this.checkDate( header.getExecutionDate() ) )
86          {
87              properties.put( Header.PROP_EXECUTIONDATE, new IllegalDateMessage(
88                  header.getExecutionDate(), new Date( this.getMinDateMillis() ), new Date( this.getMaxDateMillis() ) ) );
89  
90          }
91          if ( header.getType() == null )
92          {
93              properties.put( Header.PROP_TYPE, new MandatoryPropertyMessage() );
94          }
95          else if ( header.getType().isSendByBank() && header.getBankData() == null )
96          {
97              properties.put( Header.PROP_BANKDATA, new MandatoryPropertyMessage() );
98          }
99  
100         if ( header.getCustomer() == null || header.getCustomer().isEmpty() )
101         {
102             properties.put( Header.PROP_CUSTOMER, new MandatoryPropertyMessage() );
103         }
104         if ( header.getBank() == null )
105         {
106             properties.put( Header.PROP_BANK, new MandatoryPropertyMessage() );
107         }
108         if ( header.getAccount() == null )
109         {
110             properties.put( Header.PROP_ACCOUNT, new MandatoryPropertyMessage() );
111         }
112         if ( header.getCurrency() == null )
113         {
114             properties.put( Header.PROP_CURRENCY, new MandatoryPropertyMessage() );
115         }
116 
117         if ( header.getCreateDate() != null )
118         {
119             if ( header.getCurrency() != null )
120             {
121                 try
122                 {
123                     this.getCurrencyMapper().getDtausCode( header.getCurrency(), header.getCreateDate() );
124                 }
125                 catch ( UnsupportedCurrencyException ex )
126                 {
127                     if ( this.getLogger().isDebugEnabled() )
128                     {
129                         this.getLogger().debug( ex.toString() );
130                     }
131 
132                     properties.put( Header.PROP_CURRENCY, new IllegalCurrencyMessage(
133                         header.getCurrency().getCurrencyCode(), header.getCreateDate() ) );
134 
135                 }
136             }
137 
138             if ( !this.checkSchedule( header.getCreateDate(), header.getExecutionDate() ) )
139             {
140                 messages.add( new IllegalScheduleMessage(
141                     header.getCreateDate(), header.getExecutionDate(), this.getMaxScheduleDays() ) );
142 
143             }
144         }
145 
146         if ( properties.size() > 0 || messages.size() > 0 )
147         {
148             if ( result == null )
149             {
150                 result = new IllegalHeaderException();
151             }
152 
153             for ( Iterator it = properties.entrySet().iterator(); it.hasNext(); )
154             {
155                 final Map.Entry entry = (Map.Entry) it.next();
156                 result.addMessage( (String) entry.getKey(), (Message) entry.getValue() );
157             }
158             for ( Iterator it = messages.iterator(); it.hasNext(); )
159             {
160                 result.addMessage( (Message) it.next() );
161             }
162         }
163 
164         return result;
165     }
166 
167     public IllegalHeaderException assertValidHeader(
168         final LogicalFile lFile, final Header header, final CurrencyCounter counter, IllegalHeaderException result )
169         throws IOException
170     {
171         if ( lFile == null )
172         {
173             throw new NullPointerException( "lFile" );
174         }
175         if ( header == null )
176         {
177             throw new NullPointerException( "header" );
178         }
179         if ( counter == null )
180         {
181             throw new NullPointerException( "counter" );
182         }
183 
184         this.assertValidProperties();
185 
186         IllegalHeaderException e = this.assertValidHeader( header, result );
187         final LogicalFileType oldLabel = lFile.getHeader().getType();
188         final LogicalFileType newLabel = header.getType();
189 
190         if ( newLabel != null )
191         {
192             if ( oldLabel != null && lFile.getChecksum().getTransactionCount() > 0
193                  && ( ( oldLabel.isDebitAllowed() && !newLabel.isDebitAllowed() )
194                       || ( oldLabel.isRemittanceAllowed() && !newLabel.isRemittanceAllowed() ) ) )
195             {
196                 if ( e == null )
197                 {
198                     e = new IllegalHeaderException();
199                 }
200 
201                 e.addMessage( Header.PROP_TYPE, new TextschluesselConstraintMessage(
202                     newLabel, lFile.getTransaction( 0 ).getType() ) );
203 
204             }
205         }
206 
207         if ( header.getCreateDate() != null )
208         {
209             final Currency[] oldCurrencies =
210                 this.getCurrencyMapper().getDtausCurrencies( lFile.getHeader().getCreateDate() );
211 
212             final Currency[] newCurrencies = this.getCurrencyMapper().getDtausCurrencies( header.getCreateDate() );
213 
214             if ( !Arrays.equals( oldCurrencies, newCurrencies ) )
215             {
216                 final Currency[] current = counter.getCurrencies();
217                 for ( int i = current.length - 1; i >= 0; i-- )
218                 {
219                     boolean currencyKept = false;
220 
221                     for ( int j = newCurrencies.length - 1; j >= 0; j-- )
222                     {
223                         if ( newCurrencies[j].getCurrencyCode().equals( current[i].getCurrencyCode() ) )
224                         {
225                             currencyKept = true;
226                             break;
227                         }
228                     }
229 
230                     if ( !currencyKept )
231                     {
232                         if ( e == null )
233                         {
234                             e = new IllegalHeaderException();
235                         }
236 
237                         e.addMessage( new CurrencyConstraintMessage(
238                             current[i].getCurrencyCode(), header.getCreateDate() ) );
239 
240                     }
241                 }
242             }
243         }
244 
245         return e;
246     }
247 
248     /**
249      * Gets the value of property {@code maxScheduleDays} in milliseconds.
250      *
251      * @return the value of property {@code maxScheduleDays} in milliseconds.
252      */
253     private long getMaxScheduleDaysMillis()
254     {
255         if ( this.maxScheduleDaysMillis < 0L )
256         {
257             this.maxScheduleDaysMillis = this.getMaxScheduleDays() * 86400000L;
258         }
259 
260         return this.maxScheduleDaysMillis;
261     }
262 
263     /**
264      * Checks configured properties.
265      *
266      * @throws PropertyException for illegal property values.
267      */
268     private void assertValidProperties()
269     {
270         if ( this.getMinDateMillis() < 0L )
271         {
272             throw new PropertyException( "minDateMillis", Long.toString( this.getMinDateMillis() ) );
273         }
274         if ( this.getMaxDateMillis() < 0L || this.getMinDateMillis() > this.getMaxDateMillis() )
275         {
276             throw new PropertyException( "maxDateMillis", Long.toString( this.getMaxDateMillis() ) );
277         }
278         if ( this.getMaxScheduleDays() < 0 )
279         {
280             throw new PropertyException( "maxScheduleDays", Integer.toString( this.getMaxScheduleDays() ) );
281         }
282     }
283 
284     /**
285      * Checks a given date.
286      *
287      * @param date instance to check.
288      *
289      * @return {@code true} if {@code date} is legal; {@code false} if not.
290      */
291     private boolean checkDate( final Date date )
292     {
293         boolean valid = false;
294 
295         if ( date != null )
296         {
297             final long millis = date.getTime();
298             valid = millis >= this.getMinDateMillis() && millis <= this.getMaxDateMillis();
299         }
300 
301         return valid;
302     }
303 
304     /**
305      * Checks a given schedule.
306      *
307      * @param createDate file creation date to check.
308      * @param executionDate file execution date to check.
309      *
310      * @return {@code true} if {@code createDate} and {@code executionDate} is a legal combination; {@code false} if
311      * not.
312      */
313     private boolean checkSchedule( final Date createDate, final Date executionDate )
314     {
315         boolean valid = createDate != null;
316 
317         if ( valid )
318         {
319             final long createMillis = createDate.getTime();
320             if ( executionDate != null )
321             {
322                 final long executionMillis = executionDate.getTime();
323                 valid = executionMillis >= createMillis
324                         && executionMillis <= createMillis + this.getMaxScheduleDaysMillis();
325 
326             }
327         }
328 
329         return valid;
330     }
331 
332     //--Constructors------------------------------------------------------------
333 
334 // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausConstructors
335     // This section is managed by jdtaus-container-mojo.
336 
337     /** Standard implementation constructor <code>org.jdtaus.banking.dtaus.ri.zka.DefaultHeaderValidator</code>. */
338     public DefaultHeaderValidator()
339     {
340         super();
341     }
342 
343 // </editor-fold>//GEN-END:jdtausConstructors
344 
345     //------------------------------------------------------------Constructors--
346     //--Dependencies------------------------------------------------------------
347 
348 // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausDependencies
349     // This section is managed by jdtaus-container-mojo.
350 
351     /**
352      * Gets the configured <code>CurrencyMapper</code> implementation.
353      *
354      * @return The configured <code>CurrencyMapper</code> implementation.
355      */
356     private CurrencyMapper getCurrencyMapper()
357     {
358         return (CurrencyMapper) ContainerFactory.getContainer().
359             getDependency( this, "CurrencyMapper" );
360 
361     }
362 
363     /**
364      * Gets the configured <code>Logger</code> implementation.
365      *
366      * @return The configured <code>Logger</code> implementation.
367      */
368     private Logger getLogger()
369     {
370         return (Logger) ContainerFactory.getContainer().
371             getDependency( this, "Logger" );
372 
373     }
374 
375 // </editor-fold>//GEN-END:jdtausDependencies
376 
377     //------------------------------------------------------------Dependencies--
378     //--Properties--------------------------------------------------------------
379 
380 // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausProperties
381     // This section is managed by jdtaus-container-mojo.
382 
383     /**
384      * Gets the value of property <code>minDateMillis</code>.
385      *
386      * @return Timestamp any date is not allowed to precede.
387      */
388     private long getMinDateMillis()
389     {
390         return ( (java.lang.Long) ContainerFactory.getContainer().
391             getProperty( this, "minDateMillis" ) ).longValue();
392 
393     }
394 
395     /**
396      * Gets the value of property <code>maxScheduleDays</code>.
397      *
398      * @return Maximum number of days allowed for a schedule.
399      */
400     private int getMaxScheduleDays()
401     {
402         return ( (java.lang.Integer) ContainerFactory.getContainer().
403             getProperty( this, "maxScheduleDays" ) ).intValue();
404 
405     }
406 
407     /**
408      * Gets the value of property <code>maxDateMillis</code>.
409      *
410      * @return Timestamp any date is not allowed to follow.
411      */
412     private long getMaxDateMillis()
413     {
414         return ( (java.lang.Long) ContainerFactory.getContainer().
415             getProperty( this, "maxDateMillis" ) ).longValue();
416 
417     }
418 
419 // </editor-fold>//GEN-END:jdtausProperties
420 
421     //--------------------------------------------------------------Properties--
422 }