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 }