[cal10n-dev] Congratulations on a useful project; here's my suggestion

Ceki Gulcu ceki at qos.ch
Mon Aug 31 21:56:23 CEST 2009


Thank you Rick. FYI, you could replace the comparison of this.args and 
other.args (about 10 lines) with just Arrays.equals(this.args, other.args).

Moreover, you could implement hashCode as follows, which correct and efficient 
at the same time. Having args contribute to the hashCode is a waste of time.

   @Override
   public int hashCode() {
     return e.hashCode();
   }


How about renaming ResourceMessage as MessageParameterObj. See also

   http://www.refactoring.com/catalog/introduceParameterObject.html

Cheers,

Rick Beton wrote:
> I have developed the idea a bit further.  I think ResourceMessage is a 
> better name (Message could mean too many other things). This is my 
> contribution for you to include in the API if you want to.
> 
> Regards,
> Rick
> 
> 
> 
> package ch.qos.cal10n;
> 
> import java.io.Serializable;
> import java.util.Locale;
> 
> /**
>  * Holds a resource message with the locale lookup deferred until it is 
> needed
>  * or until the locale is known. Instances are immutable so are safe to 
> use as
>  * Exception data or share between threads. Note that the immutability is
>  * actually dependent on the supplied args themselves being immutable. If
>  * ResourceMessage instances are created that contain parameters that are
>  * mutable, the results could be unpredictable.
>  *
>  * @author Rick Beton
>  */
> public final class ResourceMessage implements Serializable {
>     private static final long serialVersionUID = 6660897864328889682L;
> 
>     private final Enum<?> e;
>     private final Object[] args;
>     // cache the result of toString
>     private transient String string = null;
>     // cache the result of hashCode
>     private transient int hashcode = 0;
> 
>     /**
>      * Constructs an instance.
>      *
>      * @param e
>      *            the key for the corresponding resource.
>      * @param args
>      *            any message parameters, as required.
>      */
>     public ResourceMessage(Enum<?> e, Object... args) {
>         this.e = e;
>         if (args != null) {
>             // take defensive copy
>             this.args = new Object[args.length];
>             System.arraycopy(args, 0, this.args, 0, args.length);
>         } else {
>             this.args = null;
>         }
>     }
> 
>     /**
>      * Gets the localized message from the resource bundle, using the 
> specified
>      * locale.
>      *
>      * @return the message for the user
>      */
>     public String getLocalizedMessage(Locale locale) {
>         final IMessageConveyor mc = new MessageConveyor(locale);
>         return mc.getMessage(e, args);
>     }
> 
>     @Override
>     public String toString() {
>         if (string == null) {
>             final StringBuilder b = new StringBuilder("Message(");
>             b.append(e.name <http://e.name>());
>             b.append(", [");
>             if (args != null) {
>                 String comma = "";
>                 for (Object o : args) {
>                     b.append(comma).append(o);
>                     comma = ", ";
>                 }
>             }
>             b.append("])");
>             // there may be a thread race here but the outcome is never
>             // uncertain
>             string = b.toString();
>         }
>         return string;
>     }
> 
>     @Override
>     public boolean equals(Object obj) {
>         if (this == obj) {
>             return true;
>         }
>         if (obj.getClass() != ResourceMessage.class) {
>             return false;
>         }
> 
>         final ResourceMessage other = (ResourceMessage) obj;
>         if (!this.e.equals(other.e)) {
>             return false;
>         } else if (this.args == null && other.args == null) {
>             return true;
>         } else if (this.args == null || other.args == null) {
>             return false;
>         } else if (this.args.length != other.args.length) {
>             return false;
>         }
> 
>         for (int i = 0; i < args.length; i++) {
>             if (this.args[i] == null && other.args[i] == null) {
>                 // ok
>             } else if (this.args[i] == null && other.args[i] != null) {
>                 return false;
>             } else if (!this.args[i].equals(other.args[i])) {
>                 return false;
>             }
>         }
>         return true;
>     }
> 
>     @Override
>     public int hashCode() {
>         if (hashcode == 0) {
>             int newHashCode = 0;
>             newHashCode = e.hashCode();
>             if (args != null) {
>                 for (Object o : args) {
>                     if (o != null) {
>                         newHashCode ^= o.hashCode();
>                     }
>                 }
>             }
>             // there may be a thread race here but the outcome is never
>             // uncertain
>             hashcode = newHashCode;
>         }
>         return hashcode;
>     }
> }
> 

-- 
Ceki Gülcü
Logback: The reliable, generic, fast and flexible logging framework for Java.
http://logback.qos.ch


More information about the cal10n-dev mailing list