On Apr 28, 2008, at 8:40 AM, Stephan Koops wrote:
>
> for some of the classes in javax.ws.rs.core I've created the methods
> equals() and hashCode() and made other little changes. Here are some
> notes:
> • Because a NewCookie has the same attributes as a Cookie, but is
> (IMO) different from it (because of additional attributes), a
> NewCookie is never equals to a Cookie now. If the equality should be
> possible, two, we could add a new equal method for this.
I've added an issue about whether NewCookie should subclass Cookie
(the status quo) or whether NewCookie should contain a Cookie instead.
We'll discuss after JavaOne.
> • CacheControl:
> • CacheControl is intended to be changed, so it returned for every
> internal state the same hashCode. Otherwise it is not possible to
> find again an object that is already inserted and afterwoods changed
> from whereever.
I can't think of a good reason to use an instance of a mutable
CacheControl as a key in a hash map but, ignoring whether or not its a
good use case, using a constant value for hashCode would kill hashMap
performance anyway.
> • Because a representation could not be private and public, I've
> changed the setters, to set the other to false, if it sets to true.
Perhaps we should just drop the public property instead. IIRC, public
is the default if not explicitly specified so just having a private
property would suffice.
> • The EntityTag constructors will rejecting null values.
OK.
> Is it useful also for some NewCookie.name and NewCookie.value?
For NewCookie.name yes, for value I think null is OK (equivalent to
empty string).
>
> • If a MediaType constructor gets nulls as type or subtype, it uses
> the wildcard for it.
OK.
Marc.
>
> Property changes on: .
> ___________________________________________________________________
> Name: svn:ignore
> - build
> dist
>
> + build
> dist
> .classpath
> .project
> javax.ws.rs.jar
> bin
>
>
> Index: src/javax/ws/rs/core/CacheControl.java
> ===================================================================
> --- src/javax/ws/rs/core/CacheControl.java (revision 329)
> +++ src/javax/ws/rs/core/CacheControl.java (working copy)
> @@ -15,13 +15,14 @@
> *
> * Created on March 5, 2007, 3:36 PM
> */
> -
> package javax.ws.rs.core;
>
> import java.util.ArrayList;
> import java.util.HashMap;
> import java.util.List;
> import java.util.Map;
> +import java.util.Set;
> +
> import javax.ws.rs.ext.RuntimeDelegate;
> import javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate;
>
> @@ -46,7 +47,6 @@
> private static final HeaderDelegate<CacheControl> delegate =
>
> RuntimeDelegate
> .getInstance().createHeaderDelegate(CacheControl.class);
>
> -
> /**
> * Create a new instance of CacheControl. The new instance will
> have the
> * following default settings:
> @@ -214,6 +214,8 @@
> */
> public void setPublic(boolean _public) {
> this._public = _public;
> + if (_public)
> + this._private = false;
> }
>
> /**
> @@ -250,6 +252,8 @@
> */
> public void setPrivate(boolean _private) {
> this._private = _private;
> + if (_private)
> + this._public = false;
> }
>
> /**
> @@ -316,4 +320,50 @@
> public String toString() {
> return delegate.toString(this);
> }
> -}
> +
> + @Override
> + public boolean equals(Object o) {
> + if (o == this)
> + return true;
> + if (!(o instanceof CacheControl))
> + return false;
> + CacheControl other = (CacheControl) o;
> + if (other.isPrivate() != this.isPrivate())
> + return false;
> + if (other.isPublic() != this.isPublic())
> + return false;
> + if (!
> other.getCacheExtension().equals(this.getCacheExtension()))
> + return false;
> + if (other.getMaxAge() != this.getMaxAge())
> + return false;
> + if (other.isMustRevalidate() != this.isMustRevalidate())
> + return false;
> + if (other.isNoCache() != this.isNoCache())
> + return false;
> + if (!
> other.getNoCacheFields().equals(this.getNoCacheFields()))
> + return false;
> + if (other.isNoStore() != this.isNoStore())
> + return false;
> + if (other.isNoTransform() != this.isNoTransform())
> + return false;
> + if (!
> other.getPrivateFields().equals(this.getPrivateFields()))
> + return false;
> + if (other.isProxyRevalidate() != this.isProxyRevalidate())
> + return false;
> + if (other.getSMaxAge() != this.getSMaxAge())
> + return false;
> + return true;
> + }
> +
> + /**
> + * The {_at_link #hashCode()} of this class is ever the same,
> because it may be
> + * changed while it is stored in a {_at_link Set} (or whereever
> the hashCode is
> + * needed).
> + *
> + * @see java.lang.Object#hashCode()
> + */
> + @Override
> + public int hashCode() {
> + return 986879;
> + }
> +}
> \ No newline at end of file
> Index: src/javax/ws/rs/core/Cookie.java
> ===================================================================
> --- src/javax/ws/rs/core/Cookie.java (revision 329)
> +++ src/javax/ws/rs/core/Cookie.java (working copy)
> @@ -14,9 +14,7 @@
> * Cookie.java
> *
> * Created on March 12, 2007, 5:01 PM
> - *
> */
> -
> package javax.ws.rs.core;
>
> import javax.ws.rs.ext.RuntimeDelegate;
> @@ -143,4 +141,70 @@
> public String toString() {
> return delegate.toString(this);
> }
> -}
> +
> + @Override
> + public int hashCode() {
> + int hashCode = this.version;
> + if (this.domain != null)
> + hashCode ^= this.domain.hashCode();
> + if (this.name != null)
> + hashCode ^= this.name.hashCode();
> + if (this.path != null)
> + hashCode ^= this.path.hashCode();
> + if (this.value != null)
> + hashCode ^= this.value.hashCode();
> + return hashCode;
> + }
> +
> + /**
> + * Compares this Cookie with another object. A cookie is never
> equal to a
> + * {_at_link NewCookie}.
> + *
> + * @see java.lang.Object#equals(java.lang.Object)
> + */
> + @Override
> + public boolean equals(Object o) {
> + if (o == this)
> + return true;
> + if (!(o instanceof Cookie))
> + return false;
> + if (o instanceof NewCookie)
> + return false;
> + return internalEquals((Cookie) o);
> + }
> +
> + /**
> + * @return
> + */
> + boolean internalEquals(Cookie other) {
> + if (this.domain != null) {
> + if (!this.domain.equals(other.domain))
> + return false;
> + } else {
> + if (other.domain != null)
> + return false;
> + }
> + if (this.name != null) {
> + if (!this.name.equals(other.name))
> + return false;
> + } else {
> + if (other.name != null)
> + return false;
> + }
> + if (this.path != null) {
> + if (!this.path.equals(other.path))
> + return false;
> + } else {
> + if (other.path != null)
> + return false;
> + }
> + if (this.value != null) {
> + if (!this.value.equals(other.value))
> + return false;
> + } else {
> + if (other.value != null)
> + return false;
> + }
> + return this.version == other.version;
> + }
> +}
> \ No newline at end of file
> Index: src/javax/ws/rs/core/EntityTag.java
> ===================================================================
> --- src/javax/ws/rs/core/EntityTag.java (revision 329)
> +++ src/javax/ws/rs/core/EntityTag.java (working copy)
> @@ -14,9 +14,7 @@
> * EntityTag.java
> *
> * Created on March 21, 2007, 3:14 PM
> - *
> */
> -
> package javax.ws.rs.core;
>
> import javax.ws.rs.ext.RuntimeDelegate;
> @@ -39,6 +37,8 @@
> * @param value the value of the tag, quotes not included.
> */
> public EntityTag(String value) {
> + if(value == null)
> + throw new IllegalArgumentException("THe value of the
> EntityTag must not be null");
> this.value = value;
> this.weak = false;
> }
> @@ -49,6 +49,8 @@
> * @param weak true if this represents a weak tag, false otherwise
> */
> public EntityTag(String value, boolean weak) {
> + if(value == null)
> + throw new IllegalArgumentException("THe value of the
> EntityTag must not be null");
> this.value = value;
> this.weak = weak;
> }
> @@ -91,12 +93,15 @@
> return false;
> if (!(obj instanceof EntityTag))
> return super.equals(obj);
> - EntityTag other = (EntityTag)obj;
> - if (value.equals(other.getValue()) && weak==other.isWeak())
> - return true;
> - return false;
> + EntityTag other = (EntityTag) obj;
> + return value.equals(other.getValue()) && weak ==
> other.isWeak();
> }
>
> + @Override
> + public int hashCode() {
> + return (weak ? 1 : 0) ^ this.value.hashCode();
> + }
> +
> /**
> * Convert the entity tag to a string suitable for use as the
> value of the
> * corresponding HTTP header.
> @@ -106,4 +111,4 @@
> public String toString() {
> return delegate.toString(this);
> }
> -}
> +}
> \ No newline at end of file
> Index: src/javax/ws/rs/core/MediaType.java
> ===================================================================
> --- src/javax/ws/rs/core/MediaType.java (revision 329)
> +++ src/javax/ws/rs/core/MediaType.java (working copy)
> @@ -14,9 +14,7 @@
> * MediaType.java
> *
> * Created on March 22, 2007, 2:35 PM
> - *
> */
> -
> package javax.ws.rs.core;
>
> import java.util.Collections;
> @@ -116,9 +114,15 @@
> * @param parameters a map of media type parameters
> */
> public MediaType(String type, String subtype, Map<String,
> String> parameters) {
> - this.type = type;
> - this.subtype = subtype;
> - if (parameters==null) {
> + if (type != null)
> + this.type = type;
> + else
> + type = MEDIA_TYPE_WILDCARD;
> + if (subtype != null)
> + this.subtype = subtype;
> + else
> + this.subtype = MEDIA_TYPE_WILDCARD;
> + if (parameters == null) {
> this.parameters = emptyMap;
> } else {
> Map<String, String> map = new TreeMap<String,
> String>(new Comparator<String>() {
> Index: src/javax/ws/rs/core/MultivaluedMap.java
> ===================================================================
> --- src/javax/ws/rs/core/MultivaluedMap.java (revision 329)
> +++ src/javax/ws/rs/core/MultivaluedMap.java (working copy)
> @@ -19,14 +19,11 @@
>
> package javax.ws.rs.core;
>
> -import java.util.ArrayList;
> -import java.util.HashMap;
> import java.util.List;
> import java.util.Map;
>
> /**
> * A map of key-values pairs. Each key can have zero or more values.
> - *
> */
> public interface MultivaluedMap<K, V> extends Map<K, List<V>> {
>
> @@ -52,7 +49,5 @@
> * @return the first value for the specified key or null if the
> key is
> * not in the map.
> */
> - V getFirst(K key);
> -
> -}
> -
> + V getFirst(K key);
> +}
> \ No newline at end of file
> Index: src/javax/ws/rs/core/NewCookie.java
> ===================================================================
> --- src/javax/ws/rs/core/NewCookie.java (revision 329)
> +++ src/javax/ws/rs/core/NewCookie.java (working copy)
> @@ -14,12 +14,9 @@
> * NewCookie.java
> *
> * Created on March 12, 2007, 5:08 PM
> - *
> */
> -
> package javax.ws.rs.core;
>
> -import java.text.ParseException;
> import javax.ws.rs.ext.RuntimeDelegate;
> import javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate;
>
> @@ -153,4 +150,41 @@
> public String toString() {
> return delegate.toString(this);
> }
> -}
> +
> + @Override
> + public int hashCode() {
> + int hashCode = super.hashCode() ^ maxAge;
> + if (this.secure)
> + hashCode += 1;
> + if (this.comment != null)
> + hashCode ^= this.comment.hashCode();
> + return hashCode;
> + }
> +
> + /**
> + * Compares this NewCookie with another object. A NewCookie is
> never equal
> + * to a {_at_link Cookie}.
> + *
> + * @see javax.ws.rs.core.Cookie#equals(java.lang.Object)
> + */
> + @Override
> + public boolean equals(Object o) {
> + if (o == this)
> + return true;
> + if (!(o instanceof NewCookie))
> + return false;
> + NewCookie other = (NewCookie) o;
> + if (!super.internalEquals(other))
> + return false;
> + if (this.comment != null) {
> + if (!this.comment.equals(other.comment))
> + return false;
> + } else {
> + if (other.comment != null)
> + return false;
> + }
> + if (this.secure != other.secure)
> + return false;
> + return this.maxAge == other.maxAge;
> + }
> +}
> \ No newline at end of file
> Index: src/javax/ws/rs/core/Response.java
> ===================================================================
> --- src/javax/ws/rs/core/Response.java (revision 329)
> +++ src/javax/ws/rs/core/Response.java (working copy)
> @@ -477,6 +477,9 @@
> public abstract ResponseBuilder cookie(NewCookie... cookies);
> }
>
> + /**
> + * Contains some of the status defined by HTTP, see {_at_link <a
> href="http://www.w3.org/Protocols/rfc2616/rfc2616-
> sec10.html#sec10">HTTP/1.1 documentation</a>}.
> + */
> public enum Status {
> /**
> * 200 OK, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1
> ">HTTP/1.1 documentation</a>}.
> Index: src/javax/ws/rs/core/UriBuilderException.java
> ===================================================================
> --- src/javax/ws/rs/core/UriBuilderException.java (revision 329)
> +++ src/javax/ws/rs/core/UriBuilderException.java (working copy)
> @@ -26,6 +26,8 @@
> */
> public class UriBuilderException extends java.lang.RuntimeException {
>
> + private static final long serialVersionUID = 956255903370721193L;
> +
> /**
> * Creates a new instance of <code>UriBuilderException</code>
> without detail message.
> */
> Index: src/javax/ws/rs/core/Variant.java
> ===================================================================
> --- src/javax/ws/rs/core/Variant.java (revision 329)
> +++ src/javax/ws/rs/core/Variant.java (working copy)
> @@ -14,9 +14,7 @@
> * Variant.java
> *
> * Created on September 27, 2007, 3:12 PM
> - *
> */
> -
> package javax.ws.rs.core;
>
> import java.util.List;
> @@ -66,6 +64,70 @@
> public String getEncoding() {
> return encoding;
> }
> +
> + @Override
> + public boolean equals(Object o) {
> + if (o == this)
> + return true;
> + if (!(o instanceof Variant))
> + return false;
> + Variant other = (Variant) o;
> + if (this.language != null) {
> + if (!this.language.equals(other.language))
> + return false;
> + } else {
> + if (other.language != null)
> + return false;
> + }
> + if (this.mediaType != null) {
> + if (!this.mediaType.equals(other.mediaType))
> + return false;
> + } else {
> + if (other.mediaType != null)
> + return false;
> + }
> + if (this.encoding != null) {
> + if (!this.encoding.equals(other.encoding))
> + return false;
> + } else {
> + if (other.encoding != null)
> + return false;
> + }
> + return true;
> + }
> +
> + @Override
> + public int hashCode() {
> + int hashCode = 0;
> + if (this.language != null)
> + hashCode ^= this.language.hashCode();
> + if (this.mediaType != null)
> + hashCode ^= this.mediaType.hashCode();
> + if (this.encoding != null)
> + hashCode ^= this.encoding.hashCode();
> + return hashCode;
> + }
> +
> + @Override
> + public String toString() {
> + StringBuilder stb = new StringBuilder();
> + stb.append("Variant[");
> + if (this.mediaType != null) {
> + stb.append(mediaType);
> + stb.append(",");
> + }
> + if (this.language != null) {
> + stb.append(language);
> + stb.append(",");
> + }
> + if (this.encoding != null) {
> + stb.append(encoding);
> + stb.append("]");
> + } else {
> + stb.replace(stb.length() - 1, stb.length(), "]");
> + }
> + return stb.toString();
> + }
>
> /**
> * A builder for a list of representation variants.
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jsr311.dev.java.net
> For additional commands, e-mail: users-help_at_jsr311.dev.java.net
---
Marc Hadley <marc.hadley at sun.com>
CTO Office, Sun Microsystems.