JCLOUDS-597: HashCode methods for Content-MD5

This works more naturally with Guava Hashing methods and immutability
provides better safety guarantees.  Also deprecate existing byte[]
methods.
This commit is contained in:
Andrew Gaul 2014-05-27 23:02:42 -07:00
parent ad79081f43
commit cb53eee8aa
9 changed files with 92 additions and 42 deletions

View File

@ -23,6 +23,8 @@ import org.jclouds.atmos.domain.MutableContentMetadata;
import org.jclouds.io.ContentMetadataBuilder; import org.jclouds.io.ContentMetadataBuilder;
import org.jclouds.io.payloads.BaseMutableContentMetadata; import org.jclouds.io.payloads.BaseMutableContentMetadata;
import com.google.common.hash.HashCode;
/** /**
* *
* @author Adrian Cole * @author Adrian Cole
@ -50,11 +52,18 @@ public class DelegatingMutableContentMetadata implements MutableContentMetadata
return delegate.getContentLength(); return delegate.getContentLength();
} }
/** @deprecated use {@link #getContentMD5AsHashCode()} instead. */
@Deprecated
@Override @Override
public byte[] getContentMD5() { public byte[] getContentMD5() {
return delegate.getContentMD5(); return delegate.getContentMD5();
} }
@Override
public HashCode getContentMD5AsHashCode() {
return delegate.getContentMD5AsHashCode();
}
@Override @Override
public String getContentType() { public String getContentType() {
return delegate.getContentType(); return delegate.getContentType();
@ -70,11 +79,18 @@ public class DelegatingMutableContentMetadata implements MutableContentMetadata
delegate.setContentLength(contentLength); delegate.setContentLength(contentLength);
} }
/** @deprecated use {@link #setContentMD5(HashCode)} instead. */
@Deprecated
@Override @Override
public void setContentMD5(byte[] contentMD5) { public void setContentMD5(byte[] contentMD5) {
delegate.setContentMD5(contentMD5); delegate.setContentMD5(contentMD5);
} }
@Override
public void setContentMD5(HashCode contentMD5) {
delegate.setContentMD5(contentMD5);
}
@Override @Override
public void setContentType(String contentType) { public void setContentType(String contentType) {
delegate.setContentType(contentType); delegate.setContentType(contentType);

View File

@ -25,6 +25,7 @@ import java.util.Map;
import org.jclouds.blobstore.domain.internal.BlobBuilderImpl; import org.jclouds.blobstore.domain.internal.BlobBuilderImpl;
import org.jclouds.io.Payload; import org.jclouds.io.Payload;
import com.google.common.hash.HashCode;
import com.google.common.io.ByteSource; import com.google.common.io.ByteSource;
import com.google.inject.ImplementedBy; import com.google.inject.ImplementedBy;
@ -117,8 +118,12 @@ public interface BlobBuilder {
PayloadBlobBuilder contentLength(long contentLength); PayloadBlobBuilder contentLength(long contentLength);
/** @deprecated use {@link #contentMD5(HashCode)} instead. */
@Deprecated
PayloadBlobBuilder contentMD5(byte[] md5); PayloadBlobBuilder contentMD5(byte[] md5);
PayloadBlobBuilder contentMD5(HashCode md5);
PayloadBlobBuilder contentType(String contentType); PayloadBlobBuilder contentType(String contentType);
PayloadBlobBuilder contentDisposition(String contentDisposition); PayloadBlobBuilder contentDisposition(String contentDisposition);

View File

@ -35,6 +35,7 @@ import org.jclouds.io.Payloads;
import org.jclouds.io.payloads.PhantomPayload; import org.jclouds.io.payloads.PhantomPayload;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.hash.HashCode;
import com.google.common.io.ByteSource; import com.google.common.io.ByteSource;
/** /**
@ -199,8 +200,15 @@ public class BlobBuilderImpl implements BlobBuilder {
return this; return this;
} }
/** @deprecated use {@link #contentMD5(HashCode)} instead. */
@Deprecated
@Override @Override
public PayloadBlobBuilder contentMD5(byte[] md5) { public PayloadBlobBuilder contentMD5(byte[] md5) {
return contentMD5(md5 == null ? null : HashCode.fromBytes(md5));
}
@Override
public PayloadBlobBuilder contentMD5(HashCode md5) {
payload.getContentMetadata().setContentMD5(md5); payload.getContentMetadata().setContentMD5(md5);
return this; return this;
} }

View File

@ -28,6 +28,7 @@ import java.util.Set;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import com.google.common.hash.HashCode;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
/** /**
@ -82,9 +83,14 @@ public interface ContentMetadata {
@Nullable @Nullable
String getContentType(); String getContentType();
/** @deprecated use {@link #getContentMD5AsHashCode()} instead. */
@Deprecated
@Nullable @Nullable
byte[] getContentMD5(); byte[] getContentMD5();
@Nullable
HashCode getContentMD5AsHashCode();
/** /**
* Get Content Language of the payload * Get Content Language of the payload
* <p/> * <p/>

View File

@ -16,13 +16,13 @@
*/ */
package org.jclouds.io; package org.jclouds.io;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import org.jclouds.io.payloads.BaseImmutableContentMetadata; import org.jclouds.io.payloads.BaseImmutableContentMetadata;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.hash.HashCode;
/** /**
* @author Adrian Cole * @author Adrian Cole
@ -35,7 +35,7 @@ public class ContentMetadataBuilder {
protected String contentType = "application/unknown"; protected String contentType = "application/unknown";
protected Long contentLength; protected Long contentLength;
protected byte[] contentMD5; protected HashCode contentMD5;
protected String contentDisposition; protected String contentDisposition;
protected String contentLanguage; protected String contentLanguage;
protected String contentEncoding; protected String contentEncoding;
@ -46,14 +46,17 @@ public class ContentMetadataBuilder {
return this; return this;
} }
public ContentMetadataBuilder contentMD5(byte[] md5) { /** @deprecated use {@link #contentMD5(HashCode)} instead. */
if (md5 != null) { @Deprecated
byte[] retval = new byte[md5.length]; public ContentMetadataBuilder contentMD5(@Nullable byte[] contentMD5) {
System.arraycopy(md5, 0, retval, 0, md5.length); return contentMD5(contentMD5 == null ? null : HashCode.fromBytes(contentMD5));
this.contentMD5 = md5; }
public ContentMetadataBuilder contentMD5(@Nullable HashCode contentMD5) {
if (contentMD5 != null) {
this.contentMD5 = contentMD5;
} }
return this; return this;
} }
public ContentMetadataBuilder contentType(@Nullable String contentType) { public ContentMetadataBuilder contentType(@Nullable String contentType) {
@ -83,7 +86,8 @@ public class ContentMetadataBuilder {
} }
public ContentMetadata build() { public ContentMetadata build() {
return new BaseImmutableContentMetadata(contentType, contentLength, contentMD5, contentDisposition, return new BaseImmutableContentMetadata(contentType, contentLength,
contentMD5 == null ? null : contentMD5.asBytes(), contentDisposition,
contentLanguage, contentEncoding, expires); contentLanguage, contentEncoding, expires);
} }
@ -112,7 +116,7 @@ public class ContentMetadataBuilder {
Objects.equal(contentEncoding, other.contentEncoding) && Objects.equal(contentEncoding, other.contentEncoding) &&
Objects.equal(contentLanguage, other.contentLanguage) && Objects.equal(contentLanguage, other.contentLanguage) &&
Objects.equal(contentLength, other.contentLength) && Objects.equal(contentLength, other.contentLength) &&
Arrays.equals(contentMD5, other.contentMD5) && Objects.equal(contentMD5, other.contentMD5) &&
Objects.equal(contentType, other.contentType) && Objects.equal(contentType, other.contentType) &&
Objects.equal(expires, other.expires); Objects.equal(expires, other.expires);
} }
@ -121,6 +125,6 @@ public class ContentMetadataBuilder {
public String toString() { public String toString() {
return "[contentDisposition=" + contentDisposition + ", contentEncoding=" + contentEncoding return "[contentDisposition=" + contentDisposition + ", contentEncoding=" + contentEncoding
+ ", contentLanguage=" + contentLanguage + ", contentLength=" + contentLength + ", contentMD5=" + ", contentLanguage=" + contentLanguage + ", contentLength=" + contentLength + ", contentMD5="
+ Arrays.toString(contentMD5) + ", contentType=" + contentType + ", expires=" + expires + "]"; + contentMD5 + ", contentType=" + contentType + ", expires=" + expires + "]";
} }
} }

View File

@ -20,6 +20,8 @@ import java.util.Date;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import com.google.common.hash.HashCode;
/** /**
* @author Adrian Cole * @author Adrian Cole
*/ */
@ -27,8 +29,12 @@ public interface MutableContentMetadata extends ContentMetadata {
void setContentLength(@Nullable Long contentLength); void setContentLength(@Nullable Long contentLength);
/** @deprecated use {@link #setContentMD5(HashCode)} instead. */
@Deprecated
void setContentMD5(@Nullable byte[] md5); void setContentMD5(@Nullable byte[] md5);
void setContentMD5(@Nullable HashCode md5);
void setContentType(@Nullable String contentType); void setContentType(@Nullable String contentType);
/** /**

View File

@ -41,6 +41,7 @@ import org.jclouds.io.payloads.InputStreamPayload;
import org.jclouds.io.payloads.InputStreamSupplierPayload; import org.jclouds.io.payloads.InputStreamSupplierPayload;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import com.google.common.hash.HashCode;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
import com.google.common.io.Files; import com.google.common.io.Files;
import com.google.common.io.InputSupplier; import com.google.common.io.InputSupplier;
@ -115,7 +116,7 @@ public class BasePayloadSlicer implements PayloadSlicer {
if (content.length > 0) { if (content.length > 0) {
payload = new ByteArrayPayload(content); payload = new ByteArrayPayload(content);
ContentMetadata cm = metaData.toBuilder().contentLength((long)content.length).contentMD5(null).build(); ContentMetadata cm = metaData.toBuilder().contentLength((long)content.length).contentMD5((HashCode) null).build();
payload.setContentMetadata(BaseMutableContentMetadata.fromContentMetadata(cm)); payload.setContentMetadata(BaseMutableContentMetadata.fromContentMetadata(cm));
} }
@ -183,7 +184,7 @@ public class BasePayloadSlicer implements PayloadSlicer {
protected Payload copyMetadataAndSetLength(Payload input, Payload returnVal, long length) { protected Payload copyMetadataAndSetLength(Payload input, Payload returnVal, long length) {
returnVal.setContentMetadata(BaseMutableContentMetadata.fromContentMetadata(input.getContentMetadata() returnVal.setContentMetadata(BaseMutableContentMetadata.fromContentMetadata(input.getContentMetadata()
.toBuilder().contentLength(length).contentMD5(null).build())); .toBuilder().contentLength(length).contentMD5((HashCode) null).build()));
return returnVal; return returnVal;
} }
@ -195,7 +196,7 @@ public class BasePayloadSlicer implements PayloadSlicer {
ContentMetadata meta = BaseMutableContentMetadata.fromContentMetadata(input.getContentMetadata()) ContentMetadata meta = BaseMutableContentMetadata.fromContentMetadata(input.getContentMetadata())
.toBuilder() .toBuilder()
.contentLength(size) .contentLength(size)
.contentMD5(null) .contentMD5((HashCode) null)
.build(); .build();
Object rawContent = input.getRawContent(); Object rawContent = input.getRawContent();
if (rawContent instanceof File) { if (rawContent instanceof File) {

View File

@ -16,13 +16,13 @@
*/ */
package org.jclouds.io.payloads; package org.jclouds.io.payloads;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import org.jclouds.io.ContentMetadata; import org.jclouds.io.ContentMetadata;
import org.jclouds.io.ContentMetadataBuilder; import org.jclouds.io.ContentMetadataBuilder;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.hash.HashCode;
/** /**
* @author Adrian Cole * @author Adrian Cole
@ -31,7 +31,7 @@ public class BaseImmutableContentMetadata implements ContentMetadata {
protected String contentType; protected String contentType;
protected Long contentLength; protected Long contentLength;
protected byte[] contentMD5; protected HashCode contentMD5;
protected String contentDisposition; protected String contentDisposition;
protected String contentLanguage; protected String contentLanguage;
protected String contentEncoding; protected String contentEncoding;
@ -41,7 +41,7 @@ public class BaseImmutableContentMetadata implements ContentMetadata {
String contentDisposition, String contentLanguage, String contentEncoding, Date expires) { String contentDisposition, String contentLanguage, String contentEncoding, Date expires) {
this.contentType = contentType; this.contentType = contentType;
this.contentLength = contentLength; this.contentLength = contentLength;
this.contentMD5 = contentMD5; this.contentMD5 = contentMD5 == null ? null : HashCode.fromBytes(contentMD5);
this.contentDisposition = contentDisposition; this.contentDisposition = contentDisposition;
this.contentLanguage = contentLanguage; this.contentLanguage = contentLanguage;
this.contentEncoding = contentEncoding; this.contentEncoding = contentEncoding;
@ -56,18 +56,17 @@ public class BaseImmutableContentMetadata implements ContentMetadata {
return contentLength; return contentLength;
} }
/** /** @deprecated use {@link #getContentMD5AsHashCode()} instead. */
* {@inheritDoc} @Deprecated
*/
@Override @Override
public byte[] getContentMD5() { public byte[] getContentMD5() {
if (contentMD5 != null) { HashCode hashCode = getContentMD5AsHashCode();
byte[] retval = new byte[contentMD5.length]; return hashCode == null ? null : hashCode.asBytes();
System.arraycopy(this.contentMD5, 0, retval, 0, contentMD5.length);
return retval;
} else {
return null;
} }
@Override
public HashCode getContentMD5AsHashCode() {
return contentMD5;
} }
/** /**
@ -114,7 +113,7 @@ public class BaseImmutableContentMetadata implements ContentMetadata {
public String toString() { public String toString() {
return "[contentType=" + contentType + ", contentLength=" + contentLength + ", contentDisposition=" return "[contentType=" + contentType + ", contentLength=" + contentLength + ", contentDisposition="
+ contentDisposition + ", contentEncoding=" + contentEncoding + ", contentLanguage=" + contentLanguage + contentDisposition + ", contentEncoding=" + contentEncoding + ", contentLanguage=" + contentLanguage
+ ", contentMD5=" + Arrays.toString(contentMD5) + ", expires = " + expires + "]"; + ", contentMD5=" + contentMD5 + ", expires = " + expires + "]";
} }
@Override @Override
@ -152,7 +151,7 @@ public class BaseImmutableContentMetadata implements ContentMetadata {
return false; return false;
} else if (!contentLength.equals(other.contentLength)) } else if (!contentLength.equals(other.contentLength))
return false; return false;
if (!Arrays.equals(contentMD5, other.contentMD5)) if (!Objects.equal(contentMD5, other.contentMD5))
return false; return false;
if (contentType == null) { if (contentType == null) {
if (other.contentType != null) if (other.contentType != null)

View File

@ -23,6 +23,8 @@ import org.jclouds.io.ContentMetadataBuilder;
import org.jclouds.io.MutableContentMetadata; import org.jclouds.io.MutableContentMetadata;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import com.google.common.hash.HashCode;
/** /**
* @author Adrian Cole * @author Adrian Cole
*/ */
@ -44,25 +46,28 @@ public class BaseMutableContentMetadata extends ContentMetadataBuilder implement
contentLength(contentLength); contentLength(contentLength);
} }
/** /** @deprecated use {@link #getContentMD5AsHashCode()} instead. */
* {@inheritDoc} @Deprecated
*/
@Override @Override
public byte[] getContentMD5() { public byte[] getContentMD5() {
if (contentMD5 != null) { HashCode hashCode = getContentMD5AsHashCode();
byte[] retval = new byte[contentMD5.length]; return hashCode == null ? null : hashCode.asBytes();
System.arraycopy(this.contentMD5, 0, retval, 0, contentMD5.length);
return retval;
} else {
return null;
}
} }
/** @Override
* {@inheritDoc} public HashCode getContentMD5AsHashCode() {
*/ return contentMD5;
}
/** @deprecated use {@link #setContentMD5(HashCode)} instead. */
@Deprecated
@Override @Override
public void setContentMD5(byte[] md5) { public void setContentMD5(byte[] md5) {
setContentMD5(md5 == null ? null : HashCode.fromBytes(md5));
}
@Override
public void setContentMD5(HashCode md5) {
contentMD5(md5); contentMD5(md5);
} }