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.text;
024
025 import java.io.Serializable;
026 import java.rmi.server.UID;
027 import java.util.Comparator;
028 import java.util.Locale;
029
030 /**
031 * Application message.
032 * <p>Application messages consist of at least the two properties
033 * {@code timestamp} and {@code formatArguments}. The {@code timestamp} property
034 * will be initialized during instantiation to hold the timestamp of instance
035 * creation. Property {@code formatArguments} holds the arguments to use
036 * for formatting message text. It is recommended that subclasses of this class
037 * are declared {@code final} so that calling {@code getClass()} on a message
038 * instance always returns a type uniquely identifying a message type in the
039 * system.</p>
040 *
041 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a>
042 * @version $Id: Message.java 8044 2009-07-02 01:29:05Z schulte2005 $
043 *
044 * @see MessageEvent
045 */
046 public abstract class Message implements Cloneable, Serializable
047 {
048 //--Constants---------------------------------------------------------------
049
050 /**
051 * Comparator for sorting messages in ascending order of occurence.
052 * <p><b>Note:</b><br/>
053 * This comparator imposes orderings that are inconsistent with equals.</p>
054 */
055 public static final Comparator ASCENDING =
056 new AscendingMessageComparator();
057
058 /**
059 * Comparator for sorting messages in descending order of occurence.
060 * <p><b>Note:</b><br/>
061 * This comparator imposes orderings that are inconsistent with equals.</p>
062 */
063 public static final Comparator DESCENDING =
064 new DescendingMessageComparator();
065
066 /** Serial version UID for backwards compatibility with 1.0.x classes. */
067 private static final long serialVersionUID = -5747726994506247015L;
068
069 //---------------------------------------------------------------Constants--
070 //--Constructors------------------------------------------------------------
071
072 /** Creates a new {@code Message} instance. */
073 public Message()
074 {
075 super();
076 this.timestamp = System.currentTimeMillis();
077 this.uid = new UID();
078 }
079
080 //------------------------------------------------------------Constructors--
081 //--Message-----------------------------------------------------------------
082
083 /**
084 * Unique message identifier.
085 * @serial
086 */
087 private UID uid;
088
089 /**
090 * The timestamp this message got created.
091 * @serial
092 */
093 private long timestamp;
094
095 /**
096 * Getter for property {@code timestamp}.
097 *
098 * @return the timestamp this message got created.
099 */
100 public final long getTimestamp()
101 {
102 return this.timestamp;
103 }
104
105 /**
106 * Getter for property {@code formatArguments}.
107 *
108 * @param locale the locale to be used for the arguments to return.
109 *
110 * @return the arguments to use when formatting the message text.
111 */
112 public abstract Object[] getFormatArguments( Locale locale );
113
114 /**
115 * Gets the formatted message text.
116 *
117 * @param locale the locale to be used for the text to return.
118 *
119 * @return the text of the message for {@code locale}.
120 */
121 public abstract String getText( Locale locale );
122
123 /**
124 * Creates a string representing the properties of the instance.
125 *
126 * @return a string representing the properties of the instance.
127 */
128 private String internalString()
129 {
130 final StringBuffer buf = new StringBuffer( 500 );
131
132 buf.append( "\n\ttimestamp=" ).append( this.timestamp ).
133 append( "\n\tuid=" ).append( this.uid ).
134 append( "\n\ttext=" ).append( this.getText( Locale.getDefault() ) );
135
136 final Object[] args = this.getFormatArguments( Locale.getDefault() );
137 for ( int i = 0; i < args.length; i++ )
138 {
139 buf.append( "\n\tformatArguments[" ).append( i ).append( "]=" ).
140 append( args[i] );
141
142 }
143
144 return buf.toString();
145 }
146
147 //-----------------------------------------------------------------Message--
148 //--Object------------------------------------------------------------------
149
150 /**
151 * Returns a string representation of the object.
152 *
153 * @return a string representation of the object.
154 */
155 public String toString()
156 {
157 return super.toString() + this.internalString();
158 }
159
160 /**
161 * Returns a hash code value for this object.
162 *
163 * @return a hash code value for this object.
164 */
165 public final int hashCode()
166 {
167 return this.uid.hashCode();
168 }
169
170 /**
171 * Indicates whether some other object is equal to this one.
172 * <p>Messages internally cary a UID which is created during instantiation.
173 * This UID is used for comparing {@code o} with the instance.</p>
174 *
175 * @param o the reference object with which to compare.
176 *
177 * @return {@code true} if this object is the same as {@code o};
178 * {@code false} otherwise.
179 *
180 * @see UID
181 */
182 public final boolean equals( final Object o )
183 {
184 return o == this || ( o instanceof Message &&
185 ( ( Message ) o ).uid.equals( this.uid ) );
186
187 }
188
189 /**
190 * Creates and returns a copy of this object.
191 *
192 * @return a clone of this instance.
193 */
194 public Object clone()
195 {
196 try
197 {
198 return super.clone();
199 }
200 catch ( CloneNotSupportedException e )
201 {
202 throw new AssertionError( e );
203 }
204 }
205
206 //------------------------------------------------------------------Object--
207 }
208
209 /**
210 * Comparator for sorting messages in ascending order of occurence.
211 * <p><b>Note:</b><br/>
212 * This comparator imposes orderings that are inconsistent with equals.</p>
213 *
214 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a>
215 * @version $Id: Message.java 8044 2009-07-02 01:29:05Z schulte2005 $
216 */
217 class AscendingMessageComparator implements Comparator, Serializable
218 {
219 //--Comparator--------------------------------------------------------------
220
221 /**
222 * {@inheritDoc}
223 *
224 * @throws NullPointerException if either {@code o1} or {@code o2} is
225 * {@code null}.
226 * @throws ClassCastException if either {@code o1} or {@code o2} is
227 * not an instance of {@code Message}.
228 */
229 public int compare( final Object o1, final Object o2 )
230 {
231 if ( o1 == null )
232 {
233 throw new NullPointerException( "o1" );
234 }
235 if ( o2 == null )
236 {
237 throw new NullPointerException( "o2" );
238 }
239 if ( !( o1 instanceof Message ) )
240 {
241 throw new ClassCastException( o1.getClass().getName() );
242 }
243 if ( !( o2 instanceof Message ) )
244 {
245 throw new ClassCastException( o2.getClass().getName() );
246 }
247
248 // TODO JDK 1.5 Long.valueOf(long)
249 final Long l1 = new Long( ( ( Message ) o1 ).getTimestamp() );
250 final Long l2 = new Long( ( ( Message ) o2 ).getTimestamp() );
251 return l1.compareTo( l2 );
252 }
253
254 //--------------------------------------------------------------Comparator--
255 }
256
257 /**
258 * Comparator for sorting messages in descending order of occurence.
259 * <p><b>Note:</b><br/>
260 * This comparator imposes orderings that are inconsistent with equals.</p>
261 *
262 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a>
263 * @version $Id: Message.java 8044 2009-07-02 01:29:05Z schulte2005 $
264 */
265 class DescendingMessageComparator
266 extends AscendingMessageComparator
267 {
268 //--Comparator--------------------------------------------------------------
269
270 /**
271 * {@inheritDoc}
272 *
273 * @throws NullPointerException if either {@code o1} or {@code o2} is
274 * {@code null}.
275 * @throws ClassCastException if either {@code o1} or {@code o2} is
276 * not an instance of {@code Message}.
277 */
278 public int compare( final Object o1, final Object o2 )
279 {
280 return super.compare( o2, o1 );
281 }
282
283 //--------------------------------------------------------------Comparator--
284 }