001 /*
002 * jDTAUS Core API
003 * Copyright (c) 2005 Christian Schulte
004 *
005 * Christian Schulte, Haldener Strasse 72, 58095 Hagen, Germany
006 * <schulte2005@users.sourceforge.net> (+49 2331 3543887)
007 *
008 * This library is free software; you can redistribute it and/or
009 * modify it under the terms of the GNU Lesser General Public
010 * License as published by the Free Software Foundation; either
011 * version 2.1 of the License, or any later version.
012 *
013 * This library is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016 * Lesser General Public License for more details.
017 *
018 * You should have received a copy of the GNU Lesser General Public
019 * License along with this library; if not, write to the Free Software
020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
021 *
022 */
023 package org.jdtaus.core.container;
024
025 import java.io.Serializable;
026 import java.util.Arrays;
027 import java.util.Collection;
028 import java.util.HashMap;
029 import java.util.Map;
030
031 /**
032 * Collection of messages.
033 *
034 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a>
035 * @version $Id: Messages.java 8044 2009-07-02 01:29:05Z schulte2005 $
036 */
037 public class Messages extends ModelObject implements Cloneable, Serializable
038 {
039 //--Constants---------------------------------------------------------------
040
041 /** Serial version UID for backwards compatibility with 1.5.x classes. */
042 private static final long serialVersionUID = -4280995595863489214L;
043
044 //---------------------------------------------------------------Constants--
045 //--Messages----------------------------------------------------------------
046
047 /**
048 * The messages of the collection.
049 * @serial
050 */
051 private Message[] messages;
052
053 /**
054 * Maps message names to messages.
055 * @serial
056 */
057 private final Map names = new HashMap();
058
059 /**
060 * Hash code.
061 * @serial
062 */
063 private int hashCode;
064
065 /**
066 * Gets the messages of the collection.
067 *
068 * @return the messages of the collection.
069 */
070 public Message[] getMessages()
071 {
072 if ( this.messages == null )
073 {
074 this.messages = new Message[ 0 ];
075 this.hashCode = 0;
076 }
077
078 return this.messages;
079 }
080
081 /**
082 * Setter for property {@code messages}.
083 *
084 * @param value the new messages for the instance.
085 *
086 * @throws DuplicateMessageException if {@code value} contains
087 * duplicate messages.
088 */
089 public void setMessages( final Message[] value )
090 {
091 this.names.clear();
092 this.hashCode = 0;
093 this.messages = null;
094
095 if ( value != null )
096 {
097 for ( int i = value.length - 1; i >= 0; i-- )
098 {
099 this.hashCode += value[i].hashCode();
100 if ( this.names.put( value[i].getName(), value[i] ) != null )
101 {
102 this.names.clear();
103 this.hashCode = 0;
104
105 throw new DuplicateMessageException( value[i].getName() );
106 }
107 }
108
109 this.messages = value;
110 }
111 }
112
113 /**
114 * Gets a message for a name.
115 *
116 * @param name the name of the message to return.
117 *
118 * @return a reference to the message with name {@code name}.
119 *
120 * @throws NullPointerException if {@code name} is {@code null}.
121 * @throws MissingMessageException if no message matching
122 * {@code name} exists in the collection.
123 */
124 public Message getMessage( final String name )
125 {
126 if ( name == null )
127 {
128 throw new NullPointerException( "name" );
129 }
130
131 final Message ret = (Message) this.names.get( name );
132
133 if ( ret == null )
134 {
135 throw new MissingMessageException( name );
136 }
137
138 return ret;
139 }
140
141 /**
142 * Gets a message for an index.
143 *
144 * @param index the index of the message to return.
145 *
146 * @return a reference to the message at {@code index}.
147 *
148 * @throws IndexOutOfBoundsException if {@code index} is negativ,
149 * greater than or equal to {@code size()}.
150 */
151 public final Message getMessage( final int index )
152 {
153 if ( index < 0 || index >= this.size() )
154 {
155 throw new ArrayIndexOutOfBoundsException( index );
156 }
157
158 return this.getMessages()[index];
159 }
160
161 /**
162 * Gets the number of messages held by the instance.
163 *
164 * @return the number of messages held by the instance.
165 */
166 public final int size()
167 {
168 return this.getMessages().length;
169 }
170
171 /**
172 * Creates a string representing the properties of the instance.
173 *
174 * @return a string representing the properties of the instance.
175 */
176 private String internalString()
177 {
178 final StringBuffer buf = new StringBuffer( 200 ).append( '{' );
179 buf.append( this.internalString( this ) );
180
181 final Message[] msgs = this.getMessages();
182 for ( int i = msgs.length - 1; i >= 0; i-- )
183 {
184 buf.append( ", [" ).append( i ).append( "]=" ).append( msgs[i] );
185 }
186
187 buf.append( '}' );
188 return buf.toString();
189 }
190
191 //----------------------------------------------------------------Messages--
192 //--Object------------------------------------------------------------------
193
194 /**
195 * Indicates whether some other object is equal to this one by comparing
196 * the values of all properties.
197 *
198 * @param o the reference object with which to compare.
199 *
200 * @return {@code true} if this object is the same as {@code o};
201 * {@code false} otherwise.
202 */
203 public boolean equals( final Object o )
204 {
205 boolean equal = this == o;
206
207 if ( !equal && o instanceof Messages )
208 {
209 final Messages that = (Messages) o;
210 final Collection these = Arrays.asList( this.getMessages() );
211 final Collection those = Arrays.asList( that.getMessages() );
212
213 equal = this.size() == that.size() && these.containsAll( those );
214 }
215
216 return equal;
217 }
218
219 /**
220 * Returns a hash code value for this object.
221 *
222 * @return a hash code value for this object.
223 */
224 public int hashCode()
225 {
226 return this.hashCode;
227 }
228
229 /**
230 * Returns a string representation of the object.
231 *
232 * @return a string representation of the object.
233 */
234 public String toString()
235 {
236 return super.toString() + this.internalString();
237 }
238
239 /**
240 * Creates and returns a deep copy of this object.
241 *
242 * @return a clone of this instance.
243 */
244 public Object clone()
245 {
246 try
247 {
248 final Messages ret = (Messages) super.clone();
249 final Message[] msgs = this.getMessages();
250 final Message[] cloned = new Message[ messages.length ];
251
252 for ( int i = msgs.length - 1; i >= 0; i-- )
253 {
254 cloned[i] = (Message) msgs[i].clone();
255 }
256
257 ret.setMessages( cloned );
258 return ret;
259 }
260 catch ( CloneNotSupportedException e )
261 {
262 throw new AssertionError( e );
263 }
264 }
265
266 //------------------------------------------------------------------Object--
267 }