All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jclouds.s3.options.CopyObjectOptions Maven / Gradle / Ivy

The newest version!
/*
 * 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.s3.options;

import static shaded.com.google.common.base.Preconditions.checkNotNull;
import static shaded.com.google.common.base.Preconditions.checkState;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
import static org.jclouds.s3.reference.S3Headers.CANNED_ACL;
import static org.jclouds.s3.reference.S3Headers.COPY_SOURCE_IF_MATCH;
import static org.jclouds.s3.reference.S3Headers.COPY_SOURCE_IF_MODIFIED_SINCE;
import static org.jclouds.s3.reference.S3Headers.COPY_SOURCE_IF_NO_MATCH;
import static org.jclouds.s3.reference.S3Headers.COPY_SOURCE_IF_UNMODIFIED_SINCE;
import static org.jclouds.s3.reference.S3Headers.DEFAULT_AMAZON_HEADERTAG;
import static org.jclouds.s3.reference.S3Headers.METADATA_DIRECTIVE;

import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;

import javax.inject.Inject;
import javax.inject.Named;

import org.jclouds.date.DateService;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.options.BaseHttpRequestOptions;
import org.jclouds.s3.domain.CannedAccessPolicy;

import shaded.com.google.common.base.Preconditions;
import shaded.com.google.common.collect.ImmutableMultimap;
import shaded.com.google.common.collect.Multimap;
import shaded.com.google.common.net.HttpHeaders;

/**
 * Contains options supported in the REST API for the COPY object operation.
 * 

*

Usage

The recommended way to instantiate a CopyObjectOptions object is to statically * import CopyObjectOptions.Builder.* and invoke a static creation method followed by an instance * mutator (if needed): *

* * import static org.jclouds.s3.commands.options.CopyObjectOptions.Builder.* *

* S3Client connection = // get connection *

* Multimap metadata = LinkedHashMultimap.create(); * metadata.put("x-amz-meta-adrian", "foo"); *

* // this will copy the object, provided it wasn't modified since yesterday. * // it will not use metadata from the source, and instead use what we pass in. * Future object = connection.copyObject("sourceBucket", "objectName", * "destinationBucket", "destinationName", * overrideMetadataWith(meta). * ifSourceModifiedSince(new Date().minusDays(1)) * ); * */ public class CopyObjectOptions extends BaseHttpRequestOptions { private static final DateService dateService = new SimpleDateFormatDateService(); public static final CopyObjectOptions NONE = new CopyObjectOptions(); private String cacheControl; private String contentDisposition; private String contentEncoding; private String contentLanguage; private String contentType; private Map metadata; private CannedAccessPolicy acl = CannedAccessPolicy.PRIVATE; private String metadataPrefix; @Inject public void setMetadataPrefix(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) { this.metadataPrefix = metadataPrefix; } private String headerTag; @Inject public void setHeaderTag(@Named(PROPERTY_HEADER_TAG) String headerTag) { this.headerTag = headerTag; } /** * Override the default ACL (private) with the specified one. * * @see CannedAccessPolicy */ public CopyObjectOptions overrideAcl(CannedAccessPolicy acl) { this.acl = checkNotNull(acl, "acl"); if (!acl.equals(CannedAccessPolicy.PRIVATE)) this.replaceHeader(CANNED_ACL, acl.toString()); return this; } /** * @see CopyObjectOptions#overrideAcl(CannedAccessPolicy) */ public CannedAccessPolicy getAcl() { return acl; } /** * For use in the header x-amz-copy-source-if-unmodified-since *

* Copies the object if it hasn't been modified since the specified time; otherwise returns a 412 * (precondition failed). *

* This header can be used with x-amz-copy-source-if-match, but cannot be used with other * conditional copy headers. * * @return valid HTTP date * @see CopyObjectOptions#ifSourceModifiedSince(Date) */ public String getIfModifiedSince() { return getFirstHeaderOrNull(COPY_SOURCE_IF_MODIFIED_SINCE); } /** * For use in the header x-amz-copy-source-if-modified-since *

* Copies the object if it has been modified since the specified time; otherwise returns a 412 * (failed condition). *

* This header can be used with x-amz-copy-source-if-none-match, but cannot be used with other * conditional copy headers. * * @return valid HTTP date * @see CopyObjectOptions#ifSourceUnmodifiedSince(Date) */ public String getIfUnmodifiedSince() { return getFirstHeaderOrNull(COPY_SOURCE_IF_UNMODIFIED_SINCE); } /** * For use in the request header: x-amz-copy-source-if-match *

* Copies the object if its payload tag (ETag) matches the specified tag; otherwise return a 412 * (precondition failed). *

* This header can be used with x-amz-copy-source-if-unmodified-since, but cannot be used with * other conditional copy headers. * * @see CopyObjectOptions#ifSourceETagMatches(String) */ public String getIfMatch() { return getFirstHeaderOrNull(COPY_SOURCE_IF_MATCH); } /** * For use in the request header: x-amz-copy-source-if-none-match *

* Copies the object if its payload tag (ETag) is different than the specified Etag; otherwise * returns a 412 (failed condition). *

* This header can be used with x-amz-copy-source-if-modified-since, but cannot be used with * other conditional copy headers. * * @see CopyObjectOptions#ifSourceETagDoesntMatch(String) */ public String getIfNoneMatch() { return getFirstHeaderOrNull(COPY_SOURCE_IF_NO_MATCH); } /** * When not null, contains the header [x-amz-copy-source-if-unmodified-since] -> [REPLACE] and * metadata headers passed in from the users. * * @see #overrideMetadataWith(Multimap) */ public Map getMetadata() { return metadata; } /** * Only return the object if it has changed since this time. *

* Not compatible with {@link #ifSourceETagMatches(String)} or * {@link #ifSourceUnmodifiedSince(Date)} */ public CopyObjectOptions ifSourceModifiedSince(Date ifModifiedSince) { checkState(getIfMatch() == null, "ifETagMatches() is not compatible with ifModifiedSince()"); checkState(getIfUnmodifiedSince() == null, "ifUnmodifiedSince() is not compatible with ifModifiedSince()"); replaceHeader(COPY_SOURCE_IF_MODIFIED_SINCE, dateService.rfc822DateFormat(checkNotNull(ifModifiedSince, "ifModifiedSince"))); return this; } /** * Only return the object if it hasn't changed since this time. *

* Not compatible with {@link #ifSourceETagDoesntMatch(String)} or * {@link #ifSourceModifiedSince(Date)} */ public CopyObjectOptions ifSourceUnmodifiedSince(Date ifUnmodifiedSince) { checkState(getIfNoneMatch() == null, "ifETagDoesntMatch() is not compatible with ifUnmodifiedSince()"); checkState(getIfModifiedSince() == null, "ifModifiedSince() is not compatible with ifUnmodifiedSince()"); replaceHeader(COPY_SOURCE_IF_UNMODIFIED_SINCE, dateService.rfc822DateFormat(checkNotNull(ifUnmodifiedSince, "ifUnmodifiedSince"))); return this; } /** * The object's eTag hash should match the parameter eTag. *

*

* Not compatible with {@link #ifSourceETagDoesntMatch(String)} or * {@link #ifSourceModifiedSince(Date)} * * @param eTag * hash representing the payload */ public CopyObjectOptions ifSourceETagMatches(String eTag) { checkState(getIfNoneMatch() == null, "ifETagDoesntMatch() is not compatible with ifETagMatches()"); checkState(getIfModifiedSince() == null, "ifModifiedSince() is not compatible with ifETagMatches()"); replaceHeader(COPY_SOURCE_IF_MATCH, maybeQuoteETag(checkNotNull(eTag, "eTag"))); return this; } /** * The object should not have a eTag hash corresponding with the parameter eTag. *

* Not compatible with {@link #ifSourceETagMatches(String)} or * {@link #ifSourceUnmodifiedSince(Date)} * * @param eTag * hash representing the payload */ public CopyObjectOptions ifSourceETagDoesntMatch(String eTag) { checkState(getIfMatch() == null, "ifETagMatches() is not compatible with ifETagDoesntMatch()"); Preconditions.checkState(getIfUnmodifiedSince() == null, "ifUnmodifiedSince() is not compatible with ifETagDoesntMatch()"); replaceHeader(COPY_SOURCE_IF_NO_MATCH, maybeQuoteETag(checkNotNull(eTag, "ifETagDoesntMatch"))); return this; } @Override public Multimap buildRequestHeaders() { checkState(headerTag != null, "headerTag should have been injected!"); checkState(metadataPrefix != null, "metadataPrefix should have been injected!"); ImmutableMultimap.Builder returnVal = ImmutableMultimap.builder(); for (Entry entry : headers.entries()) { returnVal.put(entry.getKey().replace(DEFAULT_AMAZON_HEADERTAG, headerTag), entry.getValue()); } boolean replace = false; if (cacheControl != null) { returnVal.put(HttpHeaders.CACHE_CONTROL, cacheControl); replace = true; } if (contentDisposition != null) { returnVal.put(HttpHeaders.CONTENT_DISPOSITION, contentDisposition); replace = true; } if (contentEncoding != null) { returnVal.put(HttpHeaders.CONTENT_ENCODING, contentEncoding); replace = true; } if (contentLanguage != null) { returnVal.put(HttpHeaders.CONTENT_LANGUAGE, contentLanguage); replace = true; } if (contentType != null) { returnVal.put(HttpHeaders.CONTENT_TYPE, contentType); replace = true; } if (metadata != null) { for (Map.Entry entry : metadata.entrySet()) { String key = entry.getKey(); returnVal.put(key.startsWith(metadataPrefix) ? key : metadataPrefix + key, entry.getValue()); } replace = true; } if (replace) { returnVal.put(METADATA_DIRECTIVE.replace(DEFAULT_AMAZON_HEADERTAG, headerTag), "REPLACE"); } return returnVal.build(); } public CopyObjectOptions cacheControl(String cacheControl) { this.cacheControl = checkNotNull(cacheControl, "cacheControl"); return this; } public CopyObjectOptions contentDisposition(String contentDisposition) { this.contentDisposition = checkNotNull(contentDisposition, "contentDisposition"); return this; } public CopyObjectOptions contentEncoding(String contentEncoding) { this.contentEncoding = checkNotNull(contentEncoding, "contentEncoding"); return this; } public CopyObjectOptions contentLanguage(String contentLanguage) { this.contentLanguage = checkNotNull(contentLanguage, "contentLanguage"); return this; } public CopyObjectOptions contentType(String contentType) { this.contentType = checkNotNull(contentType, "contentType"); return this; } /** * Use the provided metadata instead of what is on the source object. */ public CopyObjectOptions overrideMetadataWith(Map metadata) { checkNotNull(metadata, "metadata"); this.metadata = metadata; return this; } public static class Builder { /** * @see CopyObjectOptions#overrideAcl(CannedAccessPolicy) */ public static CopyObjectOptions overrideAcl(CannedAccessPolicy acl) { CopyObjectOptions options = new CopyObjectOptions(); return options.overrideAcl(acl); } /** * @see CopyObjectOptions#getIfModifiedSince() */ public static CopyObjectOptions ifSourceModifiedSince(Date ifModifiedSince) { CopyObjectOptions options = new CopyObjectOptions(); return options.ifSourceModifiedSince(ifModifiedSince); } /** * @see CopyObjectOptions#ifSourceUnmodifiedSince(Date) */ public static CopyObjectOptions ifSourceUnmodifiedSince(Date ifUnmodifiedSince) { CopyObjectOptions options = new CopyObjectOptions(); return options.ifSourceUnmodifiedSince(ifUnmodifiedSince); } /** * @see CopyObjectOptions#ifSourceETagMatches(String) */ public static CopyObjectOptions ifSourceETagMatches(String eTag) { CopyObjectOptions options = new CopyObjectOptions(); return options.ifSourceETagMatches(eTag); } /** * @see CopyObjectOptions#ifSourceETagDoesntMatch(String) */ public static CopyObjectOptions ifSourceETagDoesntMatch(String eTag) { CopyObjectOptions options = new CopyObjectOptions(); return options.ifSourceETagDoesntMatch(eTag); } public static CopyObjectOptions cacheControl(String cacheControl) { CopyObjectOptions options = new CopyObjectOptions(); return options.cacheControl(cacheControl); } public static CopyObjectOptions contentDisposition(String contentDisposition) { CopyObjectOptions options = new CopyObjectOptions(); return options.contentDisposition(contentDisposition); } public static CopyObjectOptions contentEncoding(String contentEncoding) { CopyObjectOptions options = new CopyObjectOptions(); return options.contentEncoding(contentEncoding); } public static CopyObjectOptions contentLanguage(String contentLanguage) { CopyObjectOptions options = new CopyObjectOptions(); return options.contentLanguage(contentLanguage); } public static CopyObjectOptions contentType(String contentType) { CopyObjectOptions options = new CopyObjectOptions(); return options.contentType(contentType); } /** * @see #overrideMetadataWith(Multimap) */ public static CopyObjectOptions overrideMetadataWith(Map metadata) { CopyObjectOptions options = new CopyObjectOptions(); return options.overrideMetadataWith(metadata); } } private static String maybeQuoteETag(String eTag) { if (!eTag.startsWith("\"") && !eTag.endsWith("\"")) { eTag = "\"" + eTag + "\""; } return eTag; } }