View Javadoc

1   /*
2    *  jDTAUS Core API
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.core.container;
22  
23  import java.io.Serializable;
24  import java.util.Arrays;
25  import java.util.Collection;
26  import java.util.HashMap;
27  import java.util.Map;
28  
29  /**
30   * Collection of messages.
31   *
32   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
33   * @version $JDTAUS: Messages.java 8743 2012-10-07 03:06:20Z schulte $
34   */
35  public class Messages extends ModelObject implements Cloneable, Serializable
36  {
37      //--Constants---------------------------------------------------------------
38  
39      /** Serial version UID for backwards compatibility with 1.5.x classes. */
40      private static final long serialVersionUID = -4280995595863489214L;
41  
42      //---------------------------------------------------------------Constants--
43      //--Messages----------------------------------------------------------------
44  
45      /**
46       * The messages of the collection.
47       * @serial
48       */
49      private Message[] messages;
50  
51      /**
52       * Maps message names to messages.
53       * @serial
54       */
55      private final Map names = new HashMap();
56  
57      /**
58       * Hash code.
59       * @serial
60       */
61      private int hashCode;
62  
63      /** Creates a new {@code Messages} instance. */
64      public Messages()
65      {
66          super();
67      }
68  
69      /**
70       * Gets the messages of the collection.
71       *
72       * @return the messages of the collection.
73       */
74      public Message[] getMessages()
75      {
76          if ( this.messages == null )
77          {
78              this.messages = new Message[ 0 ];
79              this.hashCode = 0;
80          }
81  
82          return this.messages;
83      }
84  
85      /**
86       * Setter for property {@code messages}.
87       *
88       * @param value the new messages for the instance.
89       *
90       * @throws DuplicateMessageException if {@code value} contains
91       * duplicate messages.
92       */
93      public void setMessages( final Message[] value )
94      {
95          this.names.clear();
96          this.hashCode = 0;
97          this.messages = null;
98  
99          if ( value != null )
100         {
101             for ( int i = value.length - 1; i >= 0; i-- )
102             {
103                 this.hashCode += value[i].hashCode();
104                 if ( this.names.put( value[i].getName(), value[i] ) != null )
105                 {
106                     this.names.clear();
107                     this.hashCode = 0;
108 
109                     throw new DuplicateMessageException( value[i].getName() );
110                 }
111             }
112 
113             this.messages = value;
114         }
115     }
116 
117     /**
118      * Gets a message for a name.
119      *
120      * @param name the name of the message to return.
121      *
122      * @return a reference to the message with name {@code name}.
123      *
124      * @throws NullPointerException if {@code name} is {@code null}.
125      * @throws MissingMessageException if no message matching
126      * {@code name} exists in the collection.
127      */
128     public Message getMessage( final String name )
129     {
130         if ( name == null )
131         {
132             throw new NullPointerException( "name" );
133         }
134 
135         final Message ret = (Message) this.names.get( name );
136 
137         if ( ret == null )
138         {
139             throw new MissingMessageException( name );
140         }
141 
142         return ret;
143     }
144 
145     /**
146      * Gets a message for an index.
147      *
148      * @param index the index of the message to return.
149      *
150      * @return a reference to the message at {@code index}.
151      *
152      * @throws IndexOutOfBoundsException if {@code index} is negativ,
153      * greater than or equal to {@code size()}.
154      */
155     public final Message getMessage( final int index )
156     {
157         if ( index < 0 || index >= this.size() )
158         {
159             throw new ArrayIndexOutOfBoundsException( index );
160         }
161 
162         return this.getMessages()[index];
163     }
164 
165     /**
166      * Gets the number of messages held by the instance.
167      *
168      * @return the number of messages held by the instance.
169      */
170     public final int size()
171     {
172         return this.getMessages().length;
173     }
174 
175     /**
176      * Creates a string representing the properties of the instance.
177      *
178      * @return a string representing the properties of the instance.
179      */
180     private String internalString()
181     {
182         final StringBuffer buf = new StringBuffer( 200 ).append( '{' );
183         buf.append( this.internalString( this ) );
184 
185         final Message[] msgs = this.getMessages();
186         for ( int i = msgs.length - 1; i >= 0; i-- )
187         {
188             buf.append( ", [" ).append( i ).append( "]=" ).append( msgs[i] );
189         }
190 
191         buf.append( '}' );
192         return buf.toString();
193     }
194 
195     //----------------------------------------------------------------Messages--
196     //--Object------------------------------------------------------------------
197 
198     /**
199      * Indicates whether some other object is equal to this one by comparing
200      * the values of all properties.
201      *
202      * @param o the reference object with which to compare.
203      *
204      * @return {@code true} if this object is the same as {@code o};
205      * {@code false} otherwise.
206      */
207     public boolean equals( final Object o )
208     {
209         boolean equal = this == o;
210 
211         if ( !equal && o instanceof Messages )
212         {
213             final Messages that = (Messages) o;
214             final Collection these = Arrays.asList( this.getMessages() );
215             final Collection those = Arrays.asList( that.getMessages() );
216 
217             equal = this.size() == that.size() && these.containsAll( those );
218         }
219 
220         return equal;
221     }
222 
223     /**
224      * Returns a hash code value for this object.
225      *
226      * @return a hash code value for this object.
227      */
228     public int hashCode()
229     {
230         return this.hashCode;
231     }
232 
233     /**
234      * Returns a string representation of the object.
235      *
236      * @return a string representation of the object.
237      */
238     public String toString()
239     {
240         return super.toString() + this.internalString();
241     }
242 
243     /**
244      * Creates and returns a deep copy of this object.
245      *
246      * @return a clone of this instance.
247      */
248     public Object clone()
249     {
250         try
251         {
252             final Messages ret = (Messages) super.clone();
253             final Message[] msgs = this.getMessages();
254             final Message[] cloned = new Message[ messages.length ];
255 
256             for ( int i = msgs.length - 1; i >= 0; i-- )
257             {
258                 cloned[i] = (Message) msgs[i].clone();
259             }
260 
261             ret.setMessages( cloned );
262             return ret;
263         }
264         catch ( final CloneNotSupportedException e )
265         {
266             throw new AssertionError( e );
267         }
268     }
269 
270     //------------------------------------------------------------------Object--
271 }