001/*
002 *  jDTAUS Banking RI DTAUS
003 *  Copyright (C) 2005 Christian Schulte
004 *  <cs@schulte.it>
005 *
006 *  This library is free software; you can redistribute it and/or
007 *  modify it under the terms of the GNU Lesser General Public
008 *  License as published by the Free Software Foundation; either
009 *  version 2.1 of the License, or any later version.
010 *
011 *  This library is distributed in the hope that it will be useful,
012 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 *  Lesser General Public License for more details.
015 *
016 *  You should have received a copy of the GNU Lesser General Public
017 *  License along with this library; if not, write to the Free Software
018 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
019 *
020 */
021package org.jdtaus.banking.dtaus.ri.zka;
022
023import java.io.IOException;
024import java.util.HashMap;
025import java.util.Iterator;
026import java.util.Map;
027import org.jdtaus.banking.Textschluessel;
028import org.jdtaus.banking.TextschluesselVerzeichnis;
029import org.jdtaus.banking.dtaus.LogicalFile;
030import org.jdtaus.banking.dtaus.LogicalFileType;
031import org.jdtaus.banking.dtaus.Transaction;
032import org.jdtaus.banking.dtaus.spi.IllegalTransactionException;
033import org.jdtaus.banking.dtaus.spi.TransactionValidator;
034import org.jdtaus.banking.messages.IllegalAmountMessage;
035import org.jdtaus.banking.messages.IllegalCurrencyMessage;
036import org.jdtaus.banking.messages.IllegalDescriptionCountMessage;
037import org.jdtaus.banking.messages.TextschluesselConstraintMessage;
038import org.jdtaus.banking.spi.CurrencyMapper;
039import org.jdtaus.banking.spi.UnsupportedCurrencyException;
040import org.jdtaus.core.container.ContainerFactory;
041import org.jdtaus.core.container.PropertyException;
042import org.jdtaus.core.logging.spi.Logger;
043import org.jdtaus.core.messages.MandatoryPropertyMessage;
044import org.jdtaus.core.text.Message;
045
046/**
047 * jDTAUS Banking SPI {@code TransactionValidator} implementation.
048 *
049 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
050 * @version $JDTAUS: DefaultTransactionValidator.java 8661 2012-09-27 11:29:58Z schulte $
051 */
052public final class DefaultTransactionValidator implements TransactionValidator
053{
054
055    public IllegalTransactionException assertValidTransaction(
056        final LogicalFile lFile, final Transaction transaction, IllegalTransactionException result )
057        throws IOException
058    {
059        if ( lFile == null )
060        {
061            throw new NullPointerException( "lFile" );
062        }
063        if ( transaction == null )
064        {
065            throw new NullPointerException( "transaction" );
066        }
067
068        this.assertValidProperties();
069        final Map properties = new HashMap( 20 );
070        final LogicalFileType lFileType = lFile.getHeader().getType();
071        final Textschluessel[] allowedTypes = this.getTextschluesselVerzeichnis().searchTextschluessel(
072            Boolean.valueOf( lFileType.isDebitAllowed() ), Boolean.valueOf( lFileType.isRemittanceAllowed() ),
073            lFile.getHeader().getCreateDate() );
074
075        if ( transaction.getExecutiveAccount() == null )
076        {
077            properties.put( Transaction.PROP_EXECUTIVEACCOUNT, new MandatoryPropertyMessage() );
078        }
079        if ( transaction.getExecutiveBank() == null )
080        {
081            properties.put( Transaction.PROP_EXECUTIVEBANK, new MandatoryPropertyMessage() );
082        }
083        if ( transaction.getExecutiveName() == null || transaction.getExecutiveName().isEmpty() )
084        {
085            properties.put( Transaction.PROP_EXECUTIVENAME, new MandatoryPropertyMessage() );
086        }
087        if ( transaction.getTargetAccount() == null )
088        {
089            properties.put( Transaction.PROP_TARGETACCOUNT, new MandatoryPropertyMessage() );
090        }
091        if ( transaction.getTargetBank() == null )
092        {
093            properties.put( Transaction.PROP_TARGETBANK, new MandatoryPropertyMessage() );
094        }
095        if ( transaction.getTargetName() == null || transaction.getTargetName().isEmpty() )
096        {
097            properties.put( Transaction.PROP_TARGETNAME, new MandatoryPropertyMessage() );
098        }
099        if ( transaction.getType() == null )
100        {
101            properties.put( Transaction.PROP_TYPE, new MandatoryPropertyMessage() );
102        }
103        if ( transaction.getCurrency() == null )
104        {
105            properties.put( Transaction.PROP_CURRENCY, new MandatoryPropertyMessage() );
106        }
107        if ( transaction.getAmount() == null )
108        {
109            properties.put( Transaction.PROP_AMOUNT, new MandatoryPropertyMessage() );
110        }
111        if ( allowedTypes != null && transaction.getType() != null )
112        {
113            int i;
114            for ( i = allowedTypes.length - 1; i >= 0; i-- )
115            {
116                if ( allowedTypes[i].equals( transaction.getType() ) )
117                {
118                    break;
119                }
120            }
121            if ( i < 0 )
122            {
123                properties.put( Transaction.PROP_TYPE, new TextschluesselConstraintMessage(
124                    lFileType, transaction.getType() ) );
125
126            }
127        }
128        else if ( transaction.getType() != null )
129        {
130            properties.put( Transaction.PROP_TYPE, new TextschluesselConstraintMessage(
131                lFileType, transaction.getType() ) );
132
133        }
134
135        if ( transaction.getAmount() != null &&
136             !( transaction.getAmount().longValue() >= this.getMinAmount() &&
137                transaction.getAmount().longValue() <= this.getMaxAmount() ) )
138        {
139            properties.put( Transaction.PROP_AMOUNT, new IllegalAmountMessage( transaction.getAmount() ) );
140        }
141        if ( !( transaction.getDescriptions().length >= this.getMinDescriptions() &&
142                transaction.getDescriptions().length <= this.getMaxDescriptions() ) )
143        {
144            properties.put( Transaction.PROP_DESCRIPTIONS, new IllegalDescriptionCountMessage(
145                this.getMaxDescriptions(), transaction.getDescriptions().length ) );
146
147        }
148
149        if ( transaction.getCurrency() != null )
150        {
151            try
152            {
153                this.getCurrencyMapper().getDtausCode( transaction.getCurrency(), lFile.getHeader().getCreateDate() );
154            }
155            catch ( UnsupportedCurrencyException ex )
156            {
157                if ( this.getLogger().isDebugEnabled() )
158                {
159                    this.getLogger().debug( ex.toString() );
160                }
161
162                properties.put( Transaction.PROP_CURRENCY, new IllegalCurrencyMessage(
163                    transaction.getCurrency().getCurrencyCode(), lFile.getHeader().getCreateDate() ) );
164
165            }
166        }
167
168        if ( properties.size() > 0 )
169        {
170            if ( result == null )
171            {
172                result = new IllegalTransactionException();
173            }
174
175            for ( Iterator it = properties.entrySet().iterator(); it.hasNext(); )
176            {
177                final Map.Entry entry = (Map.Entry) it.next();
178                result.addMessage( (String) entry.getKey(), (Message) entry.getValue() );
179            }
180        }
181
182        return result;
183    }
184
185    /**
186     * Checks configured properties.
187     *
188     * @throws PropertyException for illegal property values.
189     */
190    private void assertValidProperties()
191    {
192        if ( this.getMinAmount() < 0L )
193        {
194            throw new PropertyException( "minAmount", Long.toString( this.getMinAmount() ) );
195        }
196        if ( this.getMaxAmount() < 0L || this.getMinAmount() > this.getMaxAmount() )
197        {
198            throw new PropertyException( "maxAmount", Long.toString( this.getMaxAmount() ) );
199        }
200        if ( this.getMinDescriptions() < 0 )
201        {
202            throw new PropertyException( "minDescriptions", Integer.toString( this.getMinDescriptions() ) );
203        }
204        if ( this.getMaxDescriptions() < 0 || this.getMinDescriptions() > this.getMaxDescriptions() )
205        {
206            throw new PropertyException( "maxDescriptions", Integer.toString( this.getMaxDescriptions() ) );
207        }
208    }
209
210    //--Constructors------------------------------------------------------------
211
212// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausConstructors
213    // This section is managed by jdtaus-container-mojo.
214
215    /** Standard implementation constructor <code>org.jdtaus.banking.dtaus.ri.zka.DefaultTransactionValidator</code>. */
216    public DefaultTransactionValidator()
217    {
218        super();
219    }
220
221// </editor-fold>//GEN-END:jdtausConstructors
222
223    //------------------------------------------------------------Constructors--
224    //--Dependencies------------------------------------------------------------
225
226// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausDependencies
227    // This section is managed by jdtaus-container-mojo.
228
229    /**
230     * Gets the configured <code>TextschluesselVerzeichnis</code> implementation.
231     *
232     * @return The configured <code>TextschluesselVerzeichnis</code> implementation.
233     */
234    private TextschluesselVerzeichnis getTextschluesselVerzeichnis()
235    {
236        return (TextschluesselVerzeichnis) ContainerFactory.getContainer().
237            getDependency( this, "TextschluesselVerzeichnis" );
238
239    }
240
241    /**
242     * Gets the configured <code>CurrencyMapper</code> implementation.
243     *
244     * @return The configured <code>CurrencyMapper</code> implementation.
245     */
246    private CurrencyMapper getCurrencyMapper()
247    {
248        return (CurrencyMapper) ContainerFactory.getContainer().
249            getDependency( this, "CurrencyMapper" );
250
251    }
252
253    /**
254     * Gets the configured <code>Logger</code> implementation.
255     *
256     * @return The configured <code>Logger</code> implementation.
257     */
258    private Logger getLogger()
259    {
260        return (Logger) ContainerFactory.getContainer().
261            getDependency( this, "Logger" );
262
263    }
264
265// </editor-fold>//GEN-END:jdtausDependencies
266
267    //------------------------------------------------------------Dependencies--
268    //--Properties--------------------------------------------------------------
269
270// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausProperties
271    // This section is managed by jdtaus-container-mojo.
272
273    /**
274     * Gets the value of property <code>minDescriptions</code>.
275     *
276     * @return Minimum number of descriptions any transaction has to specify.
277     */
278    private int getMinDescriptions()
279    {
280        return ( (java.lang.Integer) ContainerFactory.getContainer().
281            getProperty( this, "minDescriptions" ) ).intValue();
282
283    }
284
285    /**
286     * Gets the value of property <code>minAmount</code>.
287     *
288     * @return Minimum amount any transaction has to specify.
289     */
290    private long getMinAmount()
291    {
292        return ( (java.lang.Long) ContainerFactory.getContainer().
293            getProperty( this, "minAmount" ) ).longValue();
294
295    }
296
297    /**
298     * Gets the value of property <code>maxDescriptions</code>.
299     *
300     * @return Maximum number of descriptions any transaction is allowed to specify.
301     */
302    private int getMaxDescriptions()
303    {
304        return ( (java.lang.Integer) ContainerFactory.getContainer().
305            getProperty( this, "maxDescriptions" ) ).intValue();
306
307    }
308
309    /**
310     * Gets the value of property <code>maxAmount</code>.
311     *
312     * @return Maximum amount any transaction is allowed to specify.
313     */
314    private long getMaxAmount()
315    {
316        return ( (java.lang.Long) ContainerFactory.getContainer().
317            getProperty( this, "maxAmount" ) ).longValue();
318
319    }
320
321// </editor-fold>//GEN-END:jdtausProperties
322
323    //--------------------------------------------------------------Properties--
324}