blob: ed74a4b3c9fe54d9df9fbeee3e9d21768846078e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.blobstore.options;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Date;
import java.util.List;
import com.google.common.collect.Lists;
/**
* Contains options supported for HTTP GET operations. <h2>
* Usage</h2> The recommended way to instantiate a {@link GetOptions} object is to statically import
* GetOptions.Builder.* and invoke a static creation method followed by an instance mutator (if
* needed):
* <p/>
* <code>
* import static org.jclouds.blobstore.options.GetOptions.Builder.*
*
*
* // this will get the first megabyte of an blob, provided it wasn't modified since yesterday
* blob = blobStore.getBlob("container, "blobName",range(0,1024).ifUnmodifiedSince(new Date().minusDays(1)));
* <code>
*/
public class GetOptions {
public static final GetOptions NONE = new GetOptions();
private final List<String> ranges = Lists.newArrayList();
private Date ifModifiedSince;
private Date ifUnmodifiedSince;
private String ifMatch;
private String ifNoneMatch;
/**
* download the specified range of the object.
* @param start first offset included in the response
* @param end last offset included in the response (inclusive).
* @return itself to enable daisy-chaining of expressions
*/
public GetOptions range(long start, long end) {
checkArgument(start >= 0, "start must be >= 0");
checkArgument(end >= 0, "end must be >= 0");
getRanges().add(String.format("%d-%d", start, end));
return this;
}
/**
* download the specified range of the object.
*/
public GetOptions startAt(long start) {
checkArgument(start >= 0, "start must be >= 0");
getRanges().add(String.format("%d-", start));
return this;
}
/**
* download the specified range of the object starting from the end of the object.
*/
public GetOptions tail(long length) {
checkArgument(length >= 0, "length must be >= 0");
getRanges().add(String.format("-%d", length));
return this;
}
/**
* Only return the object if it has changed since this time.
* <p />
* Not compatible with {@link #ifETagMatches(String)} or {@link #ifUnmodifiedSince(Date)}
*/
public GetOptions ifModifiedSince(Date ifModifiedSince) {
checkArgument(getIfMatch() == null, "ifETagMatches() is not compatible with ifModifiedSince()");
checkArgument(getIfUnmodifiedSince() == null, "ifUnmodifiedSince() is not compatible with ifModifiedSince()");
this.ifModifiedSince = checkNotNull(ifModifiedSince, "ifModifiedSince");
return this;
}
/**
* For use in the header If-Modified-Since
* <p />
* Return the object only if it has been modified since the specified time, otherwise return a
* 304 (not modified).
*
* @see GetOptions#ifModifiedSince(Date)
*/
public Date getIfModifiedSince() {
return this.ifModifiedSince;
}
/**
* Only return the object if it hasn't changed since this time.
* <p />
* Not compatible with {@link #ifETagDoesntMatch(String)} or {@link #ifModifiedSince(Date)}
*/
public GetOptions ifUnmodifiedSince(Date ifUnmodifiedSince) {
checkArgument(getIfNoneMatch() == null, "ifETagDoesntMatch() is not compatible with ifUnmodifiedSince()");
checkArgument(getIfModifiedSince() == null, "ifModifiedSince() is not compatible with ifUnmodifiedSince()");
this.ifUnmodifiedSince = checkNotNull(ifUnmodifiedSince, "ifUnmodifiedSince");
return this;
}
/**
* For use in the header If-Unmodified-Since
* <p />
* Return the object only if it has not been modified since the specified time, otherwise return
* a 412 (precondition failed).
*
* @see GetOptions#ifUnmodifiedSince(Date)
*/
public Date getIfUnmodifiedSince() {
return this.ifUnmodifiedSince;
}
/**
* The object's eTag hash should match the parameter <code>eTag</code>.
*
* <p />
* Not compatible with {@link #ifETagDoesntMatch(String)} or {@link #ifModifiedSince(Date)}
*
* @param eTag
* hash representing the payload
*/
public GetOptions ifETagMatches(String eTag) {
checkArgument(getIfNoneMatch() == null, "ifETagDoesntMatch() is not compatible with ifETagMatches()");
checkArgument(getIfModifiedSince() == null, "ifModifiedSince() is not compatible with ifETagMatches()");
this.ifMatch = checkNotNull(eTag, "eTag");
return this;
}
/**
* For use in the request header: If-Match
* <p />
* Return the object only if its payload tag (ETag) is the same as the eTag specified, otherwise
* return a 412 (precondition failed).
*
* @see GetOptions#ifETagMatches(String)
*/
public String getIfMatch() {
return this.ifMatch;
}
/**
* The object should not have a eTag hash corresponding with the parameter <code>eTag</code>.
* <p />
* Not compatible with {@link #ifETagMatches(String)} or {@link #ifUnmodifiedSince(Date)}
*
* @param eTag
* hash representing the payload
*/
public GetOptions ifETagDoesntMatch(String eTag) {
checkArgument(getIfMatch() == null, "ifETagMatches() is not compatible with ifETagDoesntMatch()");
checkArgument(getIfUnmodifiedSince() == null, "ifUnmodifiedSince() is not compatible with ifETagDoesntMatch()");
this.ifNoneMatch = checkNotNull(eTag, "eTag");
return this;
}
/**
* For use in the request header: If-None-Match
* <p />
* Return the object only if its payload tag (ETag) is different from the one specified,
* otherwise return a 304 (not modified).
*
* @see GetOptions#ifETagDoesntMatch(String)
*/
public String getIfNoneMatch() {
return this.ifNoneMatch;
}
public List<String> getRanges() {
return ranges;
}
public static class Builder {
/**
* @see GetOptions#range(long, long)
*/
public static GetOptions range(long start, long end) {
GetOptions options = new GetOptions();
return options.range(start, end);
}
/**
* @see GetOptions#getIfModifiedSince()
*/
public static GetOptions ifModifiedSince(Date ifModifiedSince) {
GetOptions options = new GetOptions();
return options.ifModifiedSince(ifModifiedSince);
}
/**
* @see GetOptions#ifUnmodifiedSince(Date)
*/
public static GetOptions ifUnmodifiedSince(Date ifUnmodifiedSince) {
GetOptions options = new GetOptions();
return options.ifUnmodifiedSince(ifUnmodifiedSince);
}
/**
* @see GetOptions#ifETagMatches(String)
*/
public static GetOptions ifETagMatches(String eTag) {
GetOptions options = new GetOptions();
return options.ifETagMatches(eTag);
}
/**
* @see GetOptions#ifETagDoesntMatch(String)
*/
public static GetOptions ifETagDoesntMatch(String eTag) {
GetOptions options = new GetOptions();
return options.ifETagDoesntMatch(eTag);
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((ifMatch == null) ? 0 : ifMatch.hashCode());
result = prime * result + ((ifModifiedSince == null) ? 0 : ifModifiedSince.hashCode());
result = prime * result + ((ifNoneMatch == null) ? 0 : ifNoneMatch.hashCode());
result = prime * result + ((ifUnmodifiedSince == null) ? 0 : ifUnmodifiedSince.hashCode());
result = prime * result + ((ranges == null) ? 0 : ranges.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
GetOptions other = (GetOptions) obj;
if (ifMatch == null) {
if (other.ifMatch != null)
return false;
} else if (!ifMatch.equals(other.ifMatch))
return false;
if (ifModifiedSince == null) {
if (other.ifModifiedSince != null)
return false;
} else if (!ifModifiedSince.equals(other.ifModifiedSince))
return false;
if (ifNoneMatch == null) {
if (other.ifNoneMatch != null)
return false;
} else if (!ifNoneMatch.equals(other.ifNoneMatch))
return false;
if (ifUnmodifiedSince == null) {
if (other.ifUnmodifiedSince != null)
return false;
} else if (!ifUnmodifiedSince.equals(other.ifUnmodifiedSince))
return false;
if (ranges == null) {
if (other.ranges != null)
return false;
} else if (!ranges.equals(other.ranges))
return false;
return true;
}
@Override
public String toString() {
return "[ranges=" + ranges + ", ifModifiedSince=" + ifModifiedSince + ", ifUnmodifiedSince=" + ifUnmodifiedSince
+ ", ifMatch=" + ifMatch + ", ifNoneMatch=" + ifNoneMatch + "]";
}
}