001/* 002 * jDTAUS Core API 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.core.container; 022 023import java.io.Serializable; 024import java.util.Arrays; 025import java.util.Collection; 026import java.util.HashMap; 027import java.util.Map; 028 029/** 030 * Collection of messages. 031 * 032 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 033 * @version $JDTAUS: Messages.java 8743 2012-10-07 03:06:20Z schulte $ 034 */ 035public class Messages extends ModelObject implements Cloneable, Serializable 036{ 037 //--Constants--------------------------------------------------------------- 038 039 /** Serial version UID for backwards compatibility with 1.5.x classes. */ 040 private static final long serialVersionUID = -4280995595863489214L; 041 042 //---------------------------------------------------------------Constants-- 043 //--Messages---------------------------------------------------------------- 044 045 /** 046 * The messages of the collection. 047 * @serial 048 */ 049 private Message[] messages; 050 051 /** 052 * Maps message names to messages. 053 * @serial 054 */ 055 private final Map names = new HashMap(); 056 057 /** 058 * Hash code. 059 * @serial 060 */ 061 private int hashCode; 062 063 /** Creates a new {@code Messages} instance. */ 064 public Messages() 065 { 066 super(); 067 } 068 069 /** 070 * Gets the messages of the collection. 071 * 072 * @return the messages of the collection. 073 */ 074 public Message[] getMessages() 075 { 076 if ( this.messages == null ) 077 { 078 this.messages = new Message[ 0 ]; 079 this.hashCode = 0; 080 } 081 082 return this.messages; 083 } 084 085 /** 086 * Setter for property {@code messages}. 087 * 088 * @param value the new messages for the instance. 089 * 090 * @throws DuplicateMessageException if {@code value} contains 091 * duplicate messages. 092 */ 093 public void setMessages( final Message[] value ) 094 { 095 this.names.clear(); 096 this.hashCode = 0; 097 this.messages = null; 098 099 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}