View Javadoc
1   /*
2    *  jDTAUS Banking SPI
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.spi;
22  
23  import java.util.ArrayList;
24  import java.util.HashMap;
25  import java.util.Iterator;
26  import java.util.LinkedList;
27  import java.util.List;
28  import java.util.Locale;
29  import java.util.Map;
30  import org.jdtaus.banking.dtaus.Transaction;
31  import org.jdtaus.core.text.Message;
32  import org.jdtaus.core.text.Messages;
33  
34  /**
35   * Gets thrown whenever an illegal transaction is passed to a method expecting a legal transaction.
36   * <p>Example: Throwing an {@code IllegalTransactionException}<br/><blockquote>
37   * <pre>
38   * IllegalTransactionException e = new IllegalTransactionException();
39   * e.addMessage(message);
40   * e.addMessage(Transaction.PROP_<i>XYZ</i>, message);
41   * throw e;</pre></blockquote></p>
42   *
43   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
44   * @version $JDTAUS: IllegalTransactionException.java 8661 2012-09-27 11:29:58Z schulte $
45   */
46  public class IllegalTransactionException
47      extends org.jdtaus.banking.dtaus.IllegalTransactionException
48  {
49  
50      /** Serial version UID for backwards compatibility with 1.0.x classes. */
51      private static final long serialVersionUID = -81649021330912822L;
52  
53      /** Creates a new {@code IllegalTransactionException} instance. */
54      public IllegalTransactionException()
55      {
56          super();
57      }
58  
59      /** Key to the list of messages not bound to any particular property. */
60      private static final String PROP_UNSPECIFIED = "org.jdtaus.banking.dtaus.Transaction";
61  
62      /**
63       * The messages describing the exception.
64       * @serial
65       */
66      private Map messages = new HashMap();
67  
68      /**
69       * Adds a message to the instance.
70       *
71       * @param message The message to add to the instance.
72       *
73       * @throws NullPointerException if {@code message} is {@code null}.
74       */
75      public void addMessage( final Message message )
76      {
77          this.addMessage( PROP_UNSPECIFIED, message );
78      }
79  
80      /**
81       * Adds messages to the instance.
82       *
83       * @param messages The messages to add to the instance.
84       *
85       * @throws NullPointerException if {@code messages} is {@code null}.
86       */
87      public final void addMessages( final Messages messages )
88      {
89          if ( messages == null )
90          {
91              throw new NullPointerException( "messages" );
92          }
93  
94          for ( int i = messages.size() - 1; i >= 0; i-- )
95          {
96              this.addMessage( messages.getMessage( i ) );
97          }
98      }
99  
100     /**
101      * Adds a message for a property to the instance.
102      *
103      * @param propertyName The name of a property {@code message} is bound to.
104      * @param message The message to add to the instance.
105      *
106      * @throws NullPointerException if either {@code message} or {@code propertyName} is {@code null}.
107      */
108     public void addMessage( final String propertyName, final Message message )
109     {
110         if ( propertyName == null )
111         {
112             throw new NullPointerException( "propertyName" );
113         }
114         if ( message == null )
115         {
116             throw new NullPointerException( "message" );
117         }
118 
119         List msgs = (List) this.messages.get( propertyName );
120         if ( msgs == null )
121         {
122             msgs = new LinkedList();
123             this.messages.put( propertyName, msgs );
124         }
125 
126         msgs.add( message );
127     }
128 
129     /**
130      * Adds messages bound to a property to the instance.
131      *
132      * @param propertyName The name of a property {@code messages} are bound to.
133      * @param messages The messages to add to the instance.
134      *
135      * @throws NullPointerException if either {@code messages} or {@code propertyName} is {@code null}.
136      */
137     public final void addMessages( final String propertyName, final Messages messages )
138     {
139         if ( propertyName == null )
140         {
141             throw new NullPointerException( "propertyName" );
142         }
143         if ( messages == null )
144         {
145             throw new NullPointerException( "messages" );
146         }
147 
148         for ( int i = messages.size() - 1; i >= 0; i-- )
149         {
150             this.addMessage( propertyName, messages.getMessage( i ) );
151         }
152     }
153 
154     /**
155      * Gets all messages describing the exception.
156      *
157      * @return An array of messages describing the exception or an empty array if the instance does not hold any
158      * messages.
159      */
160     public Message[] getMessages()
161     {
162         final List col = new LinkedList();
163         for ( Iterator it = this.messages.keySet().iterator(); it.hasNext(); )
164         {
165             final String propertyName = (String) it.next();
166             col.addAll( (List) this.messages.get( propertyName ) );
167         }
168 
169         return (Message[]) col.toArray( new Message[ col.size() ] );
170     }
171 
172     /**
173      * Gets messages bound to a property removing these messages from the instance.
174      *
175      * @param propertyName the name of a property to return any messages for.
176      *
177      * @return All messages bound to a property with name {@code propertyName} or an empty array if the instance does
178      * not hold messages for a property with name {@code propertyName}.
179      *
180      * @throws NullPointerException if {@code propertyName} is {@code null}.
181      */
182     public Message[] getMessages( final String propertyName )
183     {
184         if ( propertyName == null )
185         {
186             throw new NullPointerException( "propertyName" );
187         }
188 
189         final List msgs = (List) this.messages.remove( propertyName );
190         return msgs == null ? new Message[ 0 ] : (Message[]) msgs.toArray( new Message[ msgs.size() ] );
191     }
192 
193     /**
194      * Gets the names of all properties for which the exception holds messages.
195      *
196      * @return An array of the names of all properties for which the exception holds messages or an empty array if the
197      * exception does not hold any message bound to a property.
198      */
199     public String[] getPropertyNames()
200     {
201         final List names = new ArrayList( this.messages.size() );
202         for ( Iterator it = this.messages.keySet().iterator(); it.hasNext(); )
203         {
204             final String name = (String) it.next();
205             if ( !PROP_UNSPECIFIED.equals( name ) )
206             {
207                 names.add( name );
208             }
209         }
210 
211         return (String[]) names.toArray( new String[ names.size() ] );
212     }
213 
214     /**
215      * Creates a string representing the messages of the instance.
216      *
217      * @return A string representing the messages of the instance.
218      */
219     private String internalString()
220     {
221         final StringBuffer buf = new StringBuffer( 200 ).append( '{' );
222         final String[] propertyNames = this.getPropertyNames();
223         final List unspecifiedMsgs = (List) this.messages.get( PROP_UNSPECIFIED );
224 
225         for ( int i = 0; i < propertyNames.length; i++ )
226         {
227             buf.append( propertyNames[i] ).append( "={" );
228 
229             int j = 0;
230             final List msgs = (List) this.messages.get( propertyNames[i] );
231             for ( Iterator it = msgs.iterator(); it.hasNext(); j++ )
232             {
233                 final Message msg = (Message) it.next();
234                 buf.append( "[" ).append( j ).append( "]=" ).append( msg.getText( Locale.getDefault() ) );
235                 if ( it.hasNext() )
236                 {
237                     buf.append( ", " );
238                 }
239             }
240 
241             buf.append( '}' );
242 
243             if ( i + i < propertyNames.length )
244             {
245                 buf.append( ", " );
246             }
247         }
248 
249         if ( unspecifiedMsgs != null && !unspecifiedMsgs.isEmpty() )
250         {
251             if ( propertyNames.length > 0 )
252             {
253                 buf.append( ", " );
254             }
255 
256             buf.append( PROP_UNSPECIFIED ).append( "={" );
257 
258             int i = 0;
259             for ( Iterator it = unspecifiedMsgs.iterator(); it.hasNext(); i++ )
260             {
261                 final Message msg = (Message) it.next();
262                 buf.append( "[" ).append( i ).append( "]=" ).append( msg.getText( Locale.getDefault() ) );
263                 if ( it.hasNext() )
264                 {
265                     buf.append( ", " );
266                 }
267             }
268 
269             buf.append( '}' );
270         }
271 
272         buf.append( '}' );
273         return buf.toString();
274     }
275 
276     /**
277      * Returns a string representation of the object.
278      *
279      * @return A string representation of the object.
280      */
281     public String toString()
282     {
283         return super.toString() + '\n' + this.internalString();
284     }
285 
286 }