Issue 9 javadoc coverage

git-svn-id: http://jclouds.googlecode.com/svn/trunk@644 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-05-11 01:09:41 +00:00
parent 67683084ff
commit 0e07b7236f
87 changed files with 1128 additions and 232 deletions

View File

@ -28,10 +28,10 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.Utils;
import org.jclouds.command.FutureCommand;
import org.jclouds.command.FutureCommandClient;
import org.jclouds.lifecycle.BaseLifeCycle;
import org.jclouds.util.Utils;
import com.google.inject.Inject;

View File

@ -36,7 +36,6 @@ import com.google.inject.Singleton;
import com.google.inject.name.Named;
/**
* // TODO: Adrian: Document this!
*
* @author Adrian Cole
*/
@ -60,7 +59,6 @@ public abstract class FutureCommandConnectionPoolClientModule<C> extends
* occurred
*
* @param max
* @return
* @throws Exception
*/
@Provides

View File

@ -27,30 +27,30 @@ public interface HttpHeaders {
/**
* Can be used to specify caching behavior along the request/reply chain. Go
* to http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.
* to http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.9.
*/
public static final String CACHE_CONTROL = "Cache-Control";
/**
* Specifies presentational information for the object. Go to
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1.
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html?sec19.5.1.
*/
public static final String CONTENT_DISPOSITION = "Content-Disposition";
/**
* Specifies what content encodings have been applied to the object and thus
* what decoding mechanisms must be applied in order to obtain the
* media-type referenced by the Content-Type header field. Go to
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11.
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.11.
*/
public static final String CONTENT_ENCODING = "Content-Encoding";
/**
* The size of the object, in bytes. This is required. Go to
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13.
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.13.
*/
public static final String CONTENT_LENGTH = "Content-Length";
/**
* A standard MIME type describing the format of the contents. If none is
* provided, the default is binary/octet-stream. Go to
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17.
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.17.
*/
public static final String CONTENT_TYPE = "Content-Type";
/**
@ -70,7 +70,7 @@ public interface HttpHeaders {
*
* Authorization = "Authorization" ":" credentials
*
* @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html" />
*/
public static final String AUTHORIZATION = "Authorization";
public static final String HOST = "Host";

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.http;
/**

View File

@ -32,8 +32,8 @@ import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
/**
* Implies that the object can address {@link HttpResponse}s that contain status
* code 4xx.
* Implies that the object can address {@link org.jclouds.http.HttpResponse}s
* that contain status code 4xx.
*
* @author Adrian Cole
*/

View File

@ -32,7 +32,7 @@ import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
/**
* Implies that the object can address {@link HttpResponse}s that contain status
* Implies that the object can address {@link org.jclouds.http.HttpResponse}s that contain status
* code 3xx.
*
* @author Adrian Cole

View File

@ -32,7 +32,7 @@ import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
/**
* Implies that the object can address {@link HttpResponse}s that contain status
* Implies that the object can address {@link org.jclouds.http.HttpResponse}s that contain status
* code 5xx.
*
* @author Adrian Cole

View File

@ -26,9 +26,9 @@ package org.jclouds.http.commands.callables;
import java.io.IOException;
import java.io.InputStream;
import org.jclouds.Utils;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpFutureCommand;
import org.jclouds.util.Utils;
import com.google.inject.Inject;

View File

@ -28,9 +28,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.io.InputStream;
import org.apache.commons.io.IOUtils;
import org.jclouds.Utils;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpFutureCommand;
import org.jclouds.util.Utils;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

View File

@ -28,7 +28,7 @@ import java.net.URL;
import org.jclouds.http.HttpConstants;
import org.jclouds.http.HttpFutureCommandClient;
import org.jclouds.http.JavaUrlHttpFutureCommandClient;
import org.jclouds.http.internal.JavaUrlHttpFutureCommandClient;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;

View File

@ -21,11 +21,15 @@
* under the License.
* ====================================================================
*/
package org.jclouds.http;
package org.jclouds.http.handlers;
import java.io.IOException;
import org.jclouds.Utils;
import org.jclouds.http.HttpFutureCommand;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException;
import org.jclouds.http.HttpResponseHandler;
import org.jclouds.util.Utils;
/**
*

View File

@ -21,7 +21,7 @@
* under the License.
* ====================================================================
*/
package org.jclouds.http;
package org.jclouds.http.internal;
import java.net.URL;
import java.util.Collections;
@ -29,9 +29,15 @@ import java.util.List;
import javax.annotation.Resource;
import org.jclouds.http.HttpFutureCommand;
import org.jclouds.http.HttpFutureCommandClient;
import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseHandler;
import org.jclouds.http.annotation.ClientErrorHandler;
import org.jclouds.http.annotation.RedirectHandler;
import org.jclouds.http.annotation.ServerErrorHandler;
import org.jclouds.http.handlers.CloseContentAndSetExceptionHandler;
import org.jclouds.logging.Logger;
import com.google.inject.Inject;

View File

@ -21,7 +21,7 @@
* under the License.
* ====================================================================
*/
package org.jclouds.http;
package org.jclouds.http.internal;
import java.io.File;
import java.io.FileInputStream;
@ -34,6 +34,11 @@ import java.net.MalformedURLException;
import java.net.URL;
import org.apache.commons.io.IOUtils;
import org.jclouds.http.HttpFutureCommand;
import org.jclouds.http.HttpFutureCommandClient;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpResponse;
import com.google.inject.Inject;

View File

@ -39,7 +39,6 @@ import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import com.google.inject.Module;
import com.google.inject.ProvisionException;
import com.google.inject.TypeLiteral;
import com.google.inject.spi.InjectionListener;
@ -47,14 +46,14 @@ import com.google.inject.spi.TypeEncounter;
import com.google.inject.spi.TypeListener;
/**
* TypeListener that will bind {@link Logger} to members annotated with
* {@link Resource}
* TypeListener that will bind {@link org.jclouds.logging.Logger} to members annotated with
* {@link javax.annotation.Resource}
*
* This class is a TypeListener so that it can create a logger whose category is
* the same as the name of the injected instance's class.
*
* Note that this occurs post-object construction through
* {@link Module#bindListener}.
* {@link com.google.inject.Binder#bindListener}.
*
* Here's an example usage:
* <pre>

View File

@ -21,7 +21,7 @@
* under the License.
* ====================================================================
*/
package org.jclouds;
package org.jclouds.util;
import java.io.IOException;
import java.io.InputStream;

View File

@ -36,7 +36,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-gae</artifactId>
<name>Google App Engine Components</name>
<name>jclouds Google App Engine Components</name>
<packaging>jar</packaging>
<description>Google App Engine Components</description>

View File

@ -35,12 +35,12 @@ import java.net.URL;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.jclouds.http.BaseHttpFutureCommandClient;
import org.jclouds.http.HttpFutureCommand;
import org.jclouds.http.HttpFutureCommandClient;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.internal.BaseHttpFutureCommandClient;
import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPMethod;
@ -77,15 +77,17 @@ public class URLFetchServiceClient extends BaseHttpFutureCommandClient {
logger.trace("%1$s - converting request %2$s", target, request);
HTTPRequest gaeRequest = convert(request);
if (logger.isTraceEnabled())
logger.trace("%1$s - submitting request %2$s, headers: %3$s",
logger.trace(
"%1$s - submitting request %2$s, headers: %3$s",
target, gaeRequest.getURL(),
headersAsString(gaeRequest.getHeaders()));
gaeResponse = this.urlFetchService.fetch(gaeRequest);
if (logger.isTraceEnabled())
logger.trace(
"%1$s - received response code %2$s, headers: %3$s",
target, gaeResponse.getResponseCode(),
headersAsString(gaeResponse.getHeaders()));
logger
.trace(
"%1$s - received response code %2$s, headers: %3$s",
target, gaeResponse.getResponseCode(),
headersAsString(gaeResponse.getHeaders()));
response = convert(gaeResponse);
if (isRetryable(command, response))
continue;

View File

@ -35,14 +35,14 @@ import org.apache.http.HttpResponse;
import org.apache.http.nio.entity.ConsumingNHttpEntity;
import org.apache.http.nio.protocol.NHttpRequestExecutionHandler;
import org.apache.http.protocol.HttpContext;
import org.jclouds.http.CloseContentAndSetExceptionHandler;
import org.jclouds.http.HttpFutureCommand;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponseHandler;
import org.jclouds.http.annotation.ClientErrorHandler;
import org.jclouds.http.annotation.RedirectHandler;
import org.jclouds.http.annotation.ServerErrorHandler;
import org.jclouds.http.httpnio.HttpNioUtils;
import org.jclouds.http.handlers.CloseContentAndSetExceptionHandler;
import org.jclouds.http.httpnio.util.HttpNioUtils;
import org.jclouds.logging.Logger;
import com.google.inject.Inject;

View File

@ -21,7 +21,7 @@
* under the License.
* ====================================================================
*/
package org.jclouds.http.httpnio;
package org.jclouds.http.httpnio.util;
import java.io.File;
import java.io.IOException;

View File

@ -36,7 +36,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-jets3t</artifactId>
<name>JetS3t plug-in implemented by JClouds</name>
<name>jclouds JetS3t Adapter</name>
<packaging>jar</packaging>
<description>JetS3t plug-in implemented by JClouds</description>

View File

@ -29,10 +29,10 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.jclouds.Utils;
import org.jclouds.aws.s3.S3Connection;
import org.jclouds.aws.s3.S3Context;
import org.jclouds.aws.s3.S3ContextFactory;
import org.jclouds.util.Utils;
import org.jets3t.service.S3ObjectsChunk;
import org.jets3t.service.S3Service;
import org.jets3t.service.S3ServiceException;

View File

@ -35,9 +35,9 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jclouds-log4j</artifactId>
<name>jclouds log4j logging module</name>
<name>jclouds Log4J Logging Module</name>
<packaging>jar</packaging>
<description>Log4J logging module</description>
<description>jclouds Log4J Logging Module</description>
<scm>
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/extensions/log4j</connection>

34
pom.xml
View File

@ -36,7 +36,7 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>jclouds-multi</artifactId>
<packaging>pom</packaging>
<name>JClouds</name>
<name>jclouds</name>
<modules>
<module>project</module>
<module>core</module>
@ -47,13 +47,43 @@
</modules>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<links>
<link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
<link>http://java.sun.com/javaee/5/docs/api/</link>
</links>
<footer><![CDATA[
<!-- Google Analytics -->
<script type='text/javascript'>
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type='text/javascript'>
try {
var pageTracker = _gat._getTracker("UA-8638379-1");
pageTracker._trackPageview();
} catch(err) {}</script>
]]></footer>
</configuration>
<executions>
<execution>
<id>javadoc</id>
<phase>package</phase>
<goals>
<goal>aggregate</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.google.code.maven-license-plugin</groupId>
<artifactId>maven-license-plugin</artifactId>
<version>1.4.0</version>
<configuration>
<header>project/src/etc/header.txt</header>
<aggregate>true</aggregate>
<excludes>
<!-- amazon files have their own license -->
<exclude>**/src/main/java/com/amazon/**</exclude>

View File

@ -31,9 +31,9 @@
<groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId>
<packaging>pom</packaging>
<name>jclouds</name>
<url>http://code.google.com/p/jclouds</url>
<description>Concurrent API for Amazon Web Services</description>
<name>jclouds Project</name>
<url>http://www.jclouds.org</url>
<description>jclouds: Concurrent API for Cloud Services</description>
<inceptionYear>2009</inceptionYear>
<version>1.0-SNAPSHOT</version>
@ -157,6 +157,51 @@
<build>
<plugins>
<!-- Make sure we generate src jars too -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<inherited>true</inherited>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>javadoc</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<links>
<link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
<link>http://java.sun.com/javaee/5/docs/api/</link>
</links>
<footer><![CDATA[
<!-- Google Analytics -->
<script type='text/javascript'>
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type='text/javascript'>
try {
var pageTracker = _gat._getTracker("UA-8638379-1");
pageTracker._trackPageview();
} catch(err) {}</script>
]]></footer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>

View File

@ -36,9 +36,9 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-s3</artifactId>
<name>Amazon S3 Components Core</name>
<name>jclouds Amazon S3 Components Core</name>
<packaging>jar</packaging>
<description>Core components to access Amazon S3</description>
<description>jclouds Core components to access Amazon S3</description>
<scm>
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/s3</connection>

View File

@ -42,7 +42,7 @@ import org.jclouds.aws.s3.domain.S3Object;
* during processing will be wrapped in an {@link ExecutionException} as
* documented in {@link Future#get()}.
*
* @see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAPI.html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAPI.html" />
*
* @author Adrian Cole
*/

View File

@ -31,8 +31,7 @@ import org.jclouds.http.HttpResponseException;
/**
* Encapsulates an S3 Error from Amazon.
*
* @see http
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingRESTError.html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingRESTError.html" />
* @see S3Error
* @see ParseS3ErrorFromXmlContent
* @author Adrian Cole

View File

@ -45,11 +45,9 @@ import com.google.inject.name.Named;
* {@link CopyObjectOptions#overrideAcl(org.jclouds.aws.s3.domain.acl.CannedAccessPolicy)
* specify a new ACL} when generating a copy request.
*
* @see http
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectCOPY
* .html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectCOPY.html" />
* @see CopyObjectOptions
* @see CannedAccessPolicy
* @see org.jclouds.aws.s3.domain.acl.CannedAccessPolicy
* @author Adrian Cole
*
*/

View File

@ -43,8 +43,8 @@ import com.google.inject.name.Named;
* Only the owner of a bucket can delete it, regardless of the bucket's access
* control policy.
*
* @see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?
* RESTBucketDELETE.html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketDELETE.html"
* />
* @author Adrian Cole
*/
public class DeleteBucket extends S3FutureCommand<Boolean> {

View File

@ -35,8 +35,8 @@ import com.google.inject.name.Named;
* The DELETE request operation removes the specified object from Amazon S3.
* Once deleted, there is no method to restore or undelete an object.
*
* @see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?
* RESTObjectDELETE.html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?
* RESTObjectDELETE.html" />
* @author Adrian Cole
*/
public class DeleteObject extends S3FutureCommand<Boolean> {

View File

@ -61,9 +61,7 @@ import com.google.inject.name.Named;
* </ul>
*
* @see GetObjectOptions
* @see http
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectGET
* .html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectGET.html" />
* @author Adrian Cole
*/
public class GetObject extends S3FutureCommand<S3Object> {

View File

@ -40,7 +40,7 @@ import com.google.inject.name.Named;
/**
* Retrieves the metadata associated with the Key or
* {@link S3Object.Metadata#NOT_FOUND} if not available.
* {@link org.jclouds.aws.s3.domain.S3Object.Metadata#NOT_FOUND} if not available.
*
* <p/>
* The HEAD operation is used to retrieve information about a specific object or
@ -49,9 +49,8 @@ import com.google.inject.name.Named;
* bandwidth on the object data.
*
* @see GetObject
* @see http
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectHEAD
* .html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectHEAD.html"
* />
* @author Adrian Cole
*
*/

View File

@ -48,9 +48,8 @@ import com.google.inject.name.Named;
* List output is controllable via {@link ListBucketOptions}
*
* @see ListBucketOptions
* @see http
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET
* .html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html"
* />
* @author Adrian Cole
*
*/

View File

@ -35,9 +35,8 @@ import com.google.inject.name.Named;
* Returns a list of all of the buckets owned by the authenticated sender of the
* request.
*
* @see http
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTServiceGET
* .html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTServiceGET.html"
* />
* @author Adrian Cole
*
*/

View File

@ -41,9 +41,8 @@ import com.google.inject.name.Named;
* specify a Europe (EU) location constraint via {@link PutBucketOptions}.
*
* @see PutBucketOptions
* @see http
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketPUT
* .html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketPUT.html"
* />
* @author Adrian Cole
*
*/

View File

@ -48,9 +48,8 @@ import com.google.inject.name.Named;
*
*
* @see PutObjectOptions
* @see http
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectPUT
* .html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectPUT.html"
* />
* @author Adrian Cole
*/
public class PutObject extends S3FutureCommand<byte[]> {

View File

@ -36,7 +36,7 @@ import com.google.inject.assistedinject.Assisted;
import com.google.inject.name.Named;
/**
* // TODO: Adrian: Document this!
* Assembles the command objects for S3.
*
* @author Adrian Cole
*/

View File

@ -27,6 +27,13 @@ import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.http.HttpFutureCommand;
/**
* Conditionally adds the amazon host header to requests.
*
* @author Adrian Cole
*
* @param <T>
*/
public class S3FutureCommand<T> extends HttpFutureCommand<T> {
public S3FutureCommand(String method, String uri,
@ -43,9 +50,8 @@ public class S3FutureCommand<T> extends HttpFutureCommand<T> {
addHostHeader(checkNotNull(amazonHost, "amazonHost"));
}
protected void addHostHeader(String amazonHost, String bucketName) {
addHostHeader(checkNotNull(bucketName) + "." + amazonHost);
}
}

View File

@ -37,8 +37,9 @@ import org.jclouds.http.HttpHeaders;
import com.google.inject.Inject;
/**
* This parses @{link {@link S3Object.Metadata} from http headers.
* This parses @{link {@link org.jclouds.aws.s3.domain.S3Object.Metadata} from HTTP headers.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/RESTObjectGET.html" />
* @author Adrian Cole
*/
public class ParseMetadataFromHeaders extends
@ -53,7 +54,7 @@ public class ParseMetadataFromHeaders extends
/**
* parses the http response headers to create a new
* {@link S3Object.Metadata} object.
* {@link org.jclouds.aws.s3.domain.S3Object.Metadata} object.
*/
public S3Object.Metadata call() throws HttpException {
checkCode();

View File

@ -32,9 +32,10 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
/**
* Parses response headers and creates a new S3Object from them and the http
* Parses response headers and creates a new S3Object from them and the HTTP
* content.
*
* @see ParseMetadataFromHeaders
* @author Adrian Cole
*/
public class ParseObjectFromHeadersAndHttpContent extends
@ -83,7 +84,7 @@ public class ParseObjectFromHeadersAndHttpContent extends
object.setContentRange(contentRange);
object.getMetadata().setSize(
Long.parseLong(contentRange.substring(contentRange
.lastIndexOf('/')+1)));
.lastIndexOf('/') + 1)));
}
}

View File

@ -0,0 +1,28 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.
* ====================================================================
*/
/**
* This package contains response handlers for S3 commands.
* @author Adrian Cole
*/
package org.jclouds.aws.s3.commands.callables;

View File

@ -0,0 +1,28 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.
* ====================================================================
*/
/**
* This package contains modules who manage the dependencies of S3 command objects.
* @author Adrian Cole
*/
package org.jclouds.aws.s3.commands.config;

View File

@ -64,8 +64,8 @@ import com.google.common.collect.Multimap;
* );
* <code>
*
* Description of parameters taken from {@link http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectCOPY.html}
*
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectCOPY.html?"
* />
* @author Adrian Cole
*
*
@ -97,7 +97,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
public CannedAccessPolicy getAcl() {
return acl;
}
/**
* For use in the header x-amz-copy-source-if-unmodified-since
* <p />
@ -107,7 +107,8 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
* 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 (go to http://rfc.net/rfc2616.html#s3.3).
* @see <a href="http://rfc.net/rfc2616.html?s3.3"/>
* @return valid HTTP date
* @see CopyObjectOptions#ifSourceModifiedSince(DateTime)
*/
public String getIfModifiedSince() {
@ -123,8 +124,8 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
* 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 (go to http://rfc.net/rfc2616.html#s3.3).
*
* @see <a href="http://rfc.net/rfc2616.html?s3.3"/>
* @return valid HTTP date
* @see CopyObjectOptions#ifSourceUnmodifiedSince(DateTime)
*/
public String getIfUnmodifiedSince() {
@ -140,7 +141,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
* This header can be used with x-amz-copy-source-if-unmodified-since, but
* cannot be used with other conditional copy headers.
*
* @see CopyObjectOptions#ifSourceMd5Matches(String)
* @see CopyObjectOptions#ifSourceMd5Matches(byte[])
*/
public String getIfMatch() {
return getFirstHeaderOrNull("x-amz-copy-source-if-match");
@ -155,7 +156,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
* This header can be used with x-amz-copy-source-if-modified-since, but
* cannot be used with other conditional copy headers.
*
* @see CopyObjectOptions#ifSourceMd5DoesntMatch(String)
* @see CopyObjectOptions#ifSourceMd5DoesntMatch(byte[])
*/
public String getIfNoneMatch() {
return getFirstHeaderOrNull("x-amz-copy-source-if-none-match");
@ -287,7 +288,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
CopyObjectOptions options = new CopyObjectOptions();
return options.overrideAcl(acl);
}
/**
* @see CopyObjectOptions#getIfModifiedSince()
*/

View File

@ -53,8 +53,8 @@ import com.google.common.collect.Multimap;
* Future<S3Object> object = connection.getObject("bucket","objectName",range(0,1024).ifUnmodifiedSince(new DateTime().minusDays(1)));
* <code>
*
* Description of parameters taken from {@link http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectGET.html}
*
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectGET.html?"
* />
* @author Adrian Cole
*
*
@ -199,7 +199,7 @@ public class GetObjectOptions extends BaseHttpRequestOptions {
* Return the object only if its entity tag (ETag) is the same as the md5
* specified, otherwise return a 412 (precondition failed).
*
* @see GetObjectOptions#ifMd5Matches(String)
* @see GetObjectOptions#ifMd5Matches(byte[])
*/
public String getIfMatch() {
return this.getFirstHeaderOrNull(HttpHeaders.IF_MATCH);
@ -234,7 +234,7 @@ public class GetObjectOptions extends BaseHttpRequestOptions {
* Return the object only if its entity tag (ETag) is different from the one
* specified, otherwise return a 304 (not modified).
*
* @see GetObjectOptions#ifMd5DoesntMatch(String)
* @see GetObjectOptions#ifMd5DoesntMatch(byte[])
*/
public String getIfNoneMatch() {
return this
@ -250,7 +250,7 @@ public class GetObjectOptions extends BaseHttpRequestOptions {
GetObjectOptions options = new GetObjectOptions();
return options.range(start, end);
}
/**
* @see GetObjectOptions#startAt(long)
*/
@ -266,7 +266,7 @@ public class GetObjectOptions extends BaseHttpRequestOptions {
GetObjectOptions options = new GetObjectOptions();
return options.tail(count);
}
/**
* @see GetObjectOptions#getIfModifiedSince()
*/

View File

@ -31,7 +31,6 @@ import java.net.URLEncoder;
import org.jclouds.http.options.BaseHttpRequestOptions;
/**
* Contains options supported in the REST API for the GET bucket operation. <h2>
* Usage</h2> The recommended way to instantiate a GetBucketOptions object is to
@ -45,7 +44,8 @@ import org.jclouds.http.options.BaseHttpRequestOptions;
* Future<S3Bucket> bucket = connection.listBucket("bucketName",withPrefix("home/users").maxKeys(1000));
* <code>
*
* Description of parameters taken from {@link http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html}
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html?"
* />
*
* @author Adrian Cole
*
@ -69,7 +69,7 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
}
/**
* @see ListBucketOptions#prefix(String)
* @see ListBucketOptions#withPrefix(String)
*/
public String getPrefix() {
return options.get("prefix");
@ -91,7 +91,7 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
}
/**
* @see ListBucketOptions#marker(String)
* @see ListBucketOptions#afterMarker(String)
*/
public String getMarker() {
return options.get("marker");
@ -108,7 +108,7 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
}
/**
* @see ListBucketOptions#maxKeys(String)
* @see ListBucketOptions#maxResults(long)
*/
public String getMaxKeys() {
return options.get("max-keys");
@ -140,7 +140,7 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
/**
* @throws UnsupportedEncodingException
* @see ListBucketOptions#withPrefix
* @see ListBucketOptions#withPrefix(String)
*/
public static ListBucketOptions withPrefix(String prefix)
throws UnsupportedEncodingException {
@ -150,7 +150,7 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
/**
* @throws UnsupportedEncodingException
* @see ListBucketOptions#afterMarker
* @see ListBucketOptions#afterMarker(String)
*/
public static ListBucketOptions afterMarker(String marker)
throws UnsupportedEncodingException {
@ -159,7 +159,7 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
}
/**
* @see ListBucketOptions#maxResults
* @see ListBucketOptions#maxResults(long)
*/
public static ListBucketOptions maxResults(long maxKeys) {
ListBucketOptions options = new ListBucketOptions();
@ -168,7 +168,7 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
/**
* @throws UnsupportedEncodingException
* @see ListBucketOptions#delimiter
* @see ListBucketOptions#delimiter(String)
*/
public static ListBucketOptions delimiter(String delimiter)
throws UnsupportedEncodingException {

View File

@ -28,7 +28,6 @@ import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
import org.jclouds.aws.s3.reference.S3Headers;
import org.jclouds.http.options.BaseHttpRequestOptions;
import static com.google.common.base.Preconditions.*;
/**
@ -46,7 +45,8 @@ import static com.google.common.base.Preconditions.*;
* Future<Boolean> createdInEu = connection.putBucketIfNotExists("bucketName",createIn(EU));
* <code>
*
* Description of parameters taken from {@link http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketPUT.html}
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketPUT.html?"
* />
*
* @author Adrian Cole
*

View File

@ -27,7 +27,6 @@ import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
import org.jclouds.aws.s3.reference.S3Headers;
import org.jclouds.http.options.BaseHttpRequestOptions;
import static com.google.common.base.Preconditions.*;
/**
@ -46,7 +45,8 @@ import static com.google.common.base.Preconditions.*;
* Future<Boolean> publicly readable = connection.putObject("bucketName",new S3Object("key","value"), withAcl(CannedAccessPolicy.PUBLIC_READ));
* <code>
*
* Description of parameters taken from {@link http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectPUT.html}
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectPUT.html?"
* />
*
* @author Adrian Cole
*

View File

@ -21,19 +21,10 @@
* under the License.
* ====================================================================
*/
package org.jclouds.aws.s3.filters;
import org.jclouds.http.HttpRequestFilter;
/**
* // TODO: Adrian: Document this!
* This package contains request options for S3 REST commands.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/RESTAPI.html" />
* @author Adrian Cole
*/
public class RemoveTransferEncodingHeader implements HttpRequestFilter {
public void filter(org.jclouds.http.HttpRequest request)
throws org.jclouds.http.HttpException {
request.getHeaders().removeAll("Transfer-Encoding");
}
}
package org.jclouds.aws.s3.commands.options;

View File

@ -0,0 +1,29 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.
* ====================================================================
*/
/**
* This package contains all currently supported commands in the Amazon S3 REST Api.
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/RESTAPI.html" />
* @author Adrian Cole
*/
package org.jclouds.aws.s3.commands;

View File

@ -31,20 +31,19 @@ import javax.annotation.Resource;
import org.jclouds.aws.s3.S3Connection;
import org.jclouds.aws.s3.S3Context;
import org.jclouds.aws.s3.commands.config.S3CommandsModule;
import org.jclouds.aws.s3.filters.ParseS3ErrorFromXmlContent;
import org.jclouds.aws.s3.filters.RemoveTransferEncodingHeader;
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
import org.jclouds.aws.s3.handlers.ParseS3ErrorFromXmlContent;
import org.jclouds.aws.s3.internal.GuiceS3Context;
import org.jclouds.aws.s3.internal.LiveS3Connection;
import org.jclouds.aws.s3.internal.LiveS3InputStreamMap;
import org.jclouds.aws.s3.internal.LiveS3ObjectMap;
import org.jclouds.http.CloseContentAndSetExceptionHandler;
import org.jclouds.http.HttpConstants;
import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpResponseHandler;
import org.jclouds.http.annotation.ClientErrorHandler;
import org.jclouds.http.annotation.RedirectHandler;
import org.jclouds.http.annotation.ServerErrorHandler;
import org.jclouds.http.handlers.CloseContentAndSetExceptionHandler;
import org.jclouds.logging.Logger;
import com.google.inject.AbstractModule;
@ -56,7 +55,7 @@ import com.google.inject.assistedinject.FactoryProvider;
import com.google.inject.name.Named;
/**
* // TODO: Adrian: Document this!
* Configures the S3 connection, including logging and http transport.
*
* @author Adrian Cole
*/
@ -96,17 +95,15 @@ public class S3ContextModule extends AbstractModule {
bind(HttpResponseHandler.class).annotatedWith(ServerErrorHandler.class)
.to(ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
requestInjection(this);
logger.info("S3 Context = %1$s://%2$s:%3$s",
(isSecure ? "https" : "http"), address, port);
logger.info("S3 Context = %1$s://%2$s:%3$s", (isSecure ? "https"
: "http"), address, port);
}
@Provides
@Singleton
List<HttpRequestFilter> provideRequestFilters(
RemoveTransferEncodingHeader removTransferEncodingHeader,
RequestAuthorizeSignature requestAuthorizeSignature) {
List<HttpRequestFilter> filters = new ArrayList<HttpRequestFilter>();
filters.add(removTransferEncodingHeader);
filters.add(requestAuthorizeSignature);
return filters;
}

View File

@ -0,0 +1,28 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.
* ====================================================================
*/
/**
* This package contains modules who manage the dependencies of the S3Context, S3Connection, and S3 Map views.
* @author Adrian Cole
*/
package org.jclouds.aws.s3.config;

View File

@ -30,8 +30,8 @@ package org.jclouds.aws.s3.domain;
* object will have a new owner.
* <p/>
*
* @see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?
* RESTAccessPolicy.html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?
* RESTAccessPolicy.html" />
* @author Adrian Cole
*/
public class CanonicalUser {
@ -52,10 +52,18 @@ public class CanonicalUser {
return sb.toString();
}
/**
* To locate the CanonicalUser ID for a user, the user must perform the
* {@link org.jclouds.aws.s3.S3Connection#listBucket(String)} and retrieve
* {@link S3Bucket.Metadata#getOwner()}
*/
public String getId() {
return id;
}
/**
* read-only as is maintained by Amazon.
*/
public String getDisplayName() {
return displayName;
}

View File

@ -34,8 +34,30 @@ import org.joda.time.DateTime;
* A container that provides namespace, access control and aggregation of
* {@link S3Object}s
*
* <p/>
* Every object stored in Amazon S3 is contained in a bucket. Buckets partition
* the namespace of objects stored in Amazon S3 at the top level. Within a
* bucket, you can use any names for your objects, but bucket names must be
* unique across all of Amazon S3.
*
* Buckets are similar to Internet domain names. Just as Amazon is the only
* owner of the domain name Amazon.com, only one person or organization can own
* a bucket within Amazon S3. Once you create a uniquely named bucket in Amazon
* S3, you can organize and name the objects within the bucket in any way you
* like and the bucket will remain yours for as long as you like and as long as
* you have the Amazon S3 account.
*
* The similarities between buckets and domain names is not a coincidenceÑthere
* is a direct mapping between Amazon S3 buckets and subdomains of
* s3.amazonaws.com. Objects stored in Amazon S3 are addressable using the REST
* API under the domain bucketname.s3.amazonaws.com. For example, if the object
* homepage.html?is stored in the Amazon S3 bucket mybucket its address would be
* http://mybucket.s3.amazonaws.com/homepage.html?
*
* @author Adrian Cole
* @see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html
* @see <a
* href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html"
* />
*/
public class S3Bucket {
@Override
@ -76,6 +98,12 @@ public class S3Bucket {
return result;
}
/**
* System metadata of the S3Bucket
*
* @author Adrian Cole
*
*/
public static class Metadata {
@Override
public String toString() {
@ -114,6 +142,15 @@ public class S3Bucket {
return result;
}
/**
* Location constraint of the bucket.
*
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonS3/latest/RESTBucketLocationGET.html"
* />
* @author Adrian Cole
*
*/
public static enum LocationConstraint {
EU
}
@ -122,10 +159,26 @@ public class S3Bucket {
private DateTime creationDate;
private CanonicalUser canonicalUser;
/**
* @see #getName()
*/
public Metadata(String name) {
this.name = checkNotNull(name, "name");
}
/**
* To comply with Amazon S3 requirements, bucket names must:
*
* Contain lowercase letters, numbers, periods (.), underscores (_), and
* dashes (-)
*
* Start with a number or letter
*
* Be between 3 and 255 characters long
*
* Not be in an IP address style (e.g., "192.168.5.4")
*
*/
public String getName() {
return name;
}
@ -178,6 +231,9 @@ public class S3Bucket {
this.metadata = checkNotNull(metadata, "metadata");
}
/**
* @see org.jclouds.aws.s3.S3Connection#listBucket(String)
*/
public Set<S3Object.Metadata> getContents() {
return objects;
}
@ -186,6 +242,9 @@ public class S3Bucket {
this.objects = objects;
}
/**
* @return true, if the list contains all objects.
*/
public boolean isComplete() {
return isComplete;
}
@ -202,6 +261,21 @@ public class S3Bucket {
this.commonPrefixes = commonPrefixes;
}
/**
* Example:
* <p />
* if the following keys are in the bucket
*
* a/1/a<br/>
* a/1/b<br/>
* a/2/a<br/>
* a/2/b<br/>
* <p />
* and prefix is set to <code>a/</code> and delimiter is set to
* <code>/</code> then commonprefixes would return 1,2
*
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getPrefix()
*/
public Set<String> getCommonPrefixes() {
return commonPrefixes;
}
@ -210,6 +284,11 @@ public class S3Bucket {
this.prefix = prefix;
}
/**
* return keys that start with this.
*
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getPrefix()
*/
public String getPrefix() {
return prefix;
}
@ -218,6 +297,10 @@ public class S3Bucket {
this.maxKeys = maxKeys;
}
/**
* @return maximum results of the bucket.
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getMaxKeys()
*/
public long getMaxKeys() {
return maxKeys;
}
@ -226,6 +309,12 @@ public class S3Bucket {
this.marker = marker;
}
/**
* when set, bucket contains results whose keys are lexigraphically after
* marker.
*
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getMarker()
*/
public String getMarker() {
return marker;
}
@ -234,6 +323,16 @@ public class S3Bucket {
this.delimiter = delimiter;
}
/**
* when set, bucket results will not contain keys that have text following
* this delimiter.
* <p/>
* note that delimiter has no effect on prefix. prefix can contain the
* delimiter many times, or not at all. delimiter only restricts after the
* prefix.
*
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getMarker()
*/
public String getDelimiter() {
return delimiter;
}

View File

@ -29,9 +29,7 @@ import java.util.Map;
/**
* When an Amazon S3 request is in error, the client receives an error response.
*
* @see http
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?ErrorResponse
* .html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?ErrorResponse.html" />
* @author Adrian Cole
*
*/
@ -67,7 +65,7 @@ public class S3Error {
* It is meant to be read and understood by programs that detect and handle
* errors by type
*
* @see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/ErrorCode.html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/ErrorCode.html" />
*/
public String getCode() {
return code;
@ -81,8 +79,7 @@ public class S3Error {
* The error message contains a generic description of the error condition
* in English.
*
* @see http
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/ErrorMessage.html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/ErrorMessage.html" />
*/
public String getMessage() {
return message;

View File

@ -31,6 +31,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import org.jclouds.aws.s3.commands.options.GetObjectOptions;
import org.jclouds.aws.s3.util.S3Utils;
import org.jclouds.aws.s3.util.S3Utils.Md5InputStreamResult;
import org.jclouds.http.ContentTypes;
@ -40,8 +41,13 @@ import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
/**
* // TODO: Adrian: Document this!
* Amazon S3 is designed to store objects. Objects are stored in
* {@link S3Bucket buckets} and consist of a {@link S3Object#getValue() value},
* a {@link S3Object#getKey key}, {@link S3Object.Metadata#getUserMetadata()
* metadata}, and an access control policy.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?UsingObjects.html"
* />
* @author Adrian Cole
*/
public class S3Object {
@ -70,6 +76,15 @@ public class S3Object {
setData(data);
}
/**
* System and user Metadata for the {@link S3Object}.
*
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingMetadata.html"
* />
* @author Adrian Cole
*
*/
public static class Metadata {
public static final Metadata NOT_FOUND = new Metadata("NOT_FOUND");
@ -82,7 +97,7 @@ public class S3Object {
private Multimap<String, String> allHeaders = HashMultimap.create();
private Multimap<String, String> userMetadata = HashMultimap.create();
private DateTime lastModified;
private String dataType = ContentTypes.UNKNOWN_MIME_TYPE;
private String dataType = ContentTypes.BINARY;
private String cacheControl;
private String dataDisposition;
private String dataEncoding;
@ -91,6 +106,10 @@ public class S3Object {
private CanonicalUser owner = null;
private String storageClass = null;
/**
* @see #getKey()
* @param key
*/
public Metadata(String key) {
checkNotNull(key, "key");
checkArgument(!key.startsWith("/"), "keys cannot start with /");
@ -149,6 +168,16 @@ public class S3Object {
return result;
}
/**
* The key is the handle that you assign to an object that allows you
* retrieve it later. A key is a sequence of Unicode characters whose
* UTF-8 encoding is at most 1024 bytes long. Each object in a bucket
* must have a unique key.
*
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingKeys.html"
* />
*/
public String getKey() {
return key;
}
@ -161,6 +190,15 @@ public class S3Object {
this.lastModified = lastModified;
}
/**
* The size of the object, in bytes.
*
* @see <a href=
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.13."
* />
*
* @return
*/
public long getSize() {
return size;
}
@ -169,6 +207,16 @@ public class S3Object {
this.size = size;
}
/**
* A standard MIME type describing the format of the contents. If none
* is provided, the default is binary/octet-stream.
*
* @see <a href=
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.17."
* />
*
* @return
*/
public String getContentType() {
return dataType;
}
@ -181,6 +229,9 @@ public class S3Object {
this.md5 = md5;
}
/**
* @return the md5 value stored in the Etag header returned by S3.
*/
public byte[] getMd5() {
return md5;
}
@ -189,6 +240,14 @@ public class S3Object {
this.userMetadata = userMetadata;
}
/**
*
* Any header starting with <code>x-amz-meta-</code> is considered user
* metadata. It will be stored with the object and returned when you
* retrieve the object. The total size of the HTTP request, not
* including the body, must be less than 8 KB.
*
*/
public Multimap<String, String> getUserMetadata() {
return userMetadata;
}
@ -211,6 +270,9 @@ public class S3Object {
this.storageClass = storageClass;
}
/**
* Currently defaults to 'STANDARD' and not used.
*/
public String getStorageClass() {
return storageClass;
}
@ -219,6 +281,12 @@ public class S3Object {
this.cacheControl = cacheControl;
}
/**
* Can be used to specify caching behavior along the request/reply
* chain.
*
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.9.
*/
public String getCacheControl() {
return cacheControl;
}
@ -227,6 +295,11 @@ public class S3Object {
this.dataDisposition = dataDisposition;
}
/**
* Specifies presentational information for the object.
*
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html?sec19.5.1."/>
*/
public String getContentDisposition() {
return dataDisposition;
}
@ -235,6 +308,15 @@ public class S3Object {
this.dataEncoding = dataEncoding;
}
/**
* Specifies what content encodings have been applied to the object and
* thus what decoding mechanisms must be applied in order to obtain the
* media-type referenced by the Content-Type header field.
*
* @see <a href=
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.11"
* />
*/
public String getContentEncoding() {
return dataEncoding;
}
@ -243,21 +325,46 @@ public class S3Object {
this.allHeaders = allHeaders;
}
/**
*
* @return all http response headers associated with this S3Object
*/
public Multimap<String, String> getAllHeaders() {
return allHeaders;
}
}
/**
* @see Metadata#getKey()
*/
public String getKey() {
return metadata.getKey();
}
/**
* Sets payload for the request or the content from the response. If size
* isn't set, this will attempt to discover it.
*
* @param data
* typically InputStream for downloads, or File, byte [], String,
* or InputStream for uploads.
*/
public void setData(Object data) {
this.data = checkNotNull(data, "data");
if (getMetadata().getSize() == -1)
this.getMetadata().setSize(S3Utils.calculateSize(data));
}
/**
* generate an MD5 Hash for the current data.
*
* <h2>Note</h2>
* <p/>
* If this is an InputStream, it will be converted to a byte array first.
*
* @throws IOException
* if there is a problem generating the hash.
*/
public void generateMd5() throws IOException {
checkState(data != null, "data");
if (data instanceof InputStream) {
@ -271,6 +378,11 @@ public class S3Object {
}
}
/**
*
* @return InputStream, if downloading, or whatever was set during
* {@link #setData(Object)}
*/
public Object getData() {
return data;
}
@ -279,6 +391,10 @@ public class S3Object {
this.metadata = metadata;
}
/**
*
* @return System and User metadata relevant to this object.
*/
public Metadata getMetadata() {
return metadata;
}
@ -320,6 +436,20 @@ public class S3Object {
this.contentLength = contentLength;
}
/**
* Returns the total size of the downloaded object, or the chunk that's
* available.
* <p/>
* Chunking is only used when
* {@link org.jclouds.aws.s3.S3Connection#getObject(String, String, org.jclouds.aws.s3.commands.options.GetObjectOptions) }
* is called with options like tail, range, or startAt.
*
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
* @see GetObjectOptions
* @return the length in bytes that can be be obtained from
* {@link #getData()}
*
*/
public long getContentLength() {
return contentLength;
}
@ -328,6 +458,13 @@ public class S3Object {
this.contentRange = contentRange;
}
/**
* If this is not-null, {@link #getContentLength() } will the size of chunk
* of the S3Object available via {@link #getData()}
*
* @see org.jclouds.http.HttpHeaders#CONTENT_RANGE
* @see GetObjectOptions
*/
public String getContentRange() {
return contentRange;
}

View File

@ -38,8 +38,8 @@ package org.jclouds.aws.s3.domain.acl;
* object, the object already exists with some other pre-existing access control
* policy).
*
* @see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?
* RESTAccessPolicy.html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?
* RESTAccessPolicy.html" />
* @author Adrian Cole
*
*/

View File

@ -0,0 +1,29 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.
* ====================================================================
*/
/**
* This package contains components that represent authorization state.
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/RESTAccessPolicy.html" />
* @author Adrian Cole
*/
package org.jclouds.aws.s3.domain.acl;

View File

@ -0,0 +1,29 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.
* ====================================================================
*/
/**
* This package contains the core components of S3.
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/Components.html" />
* @author Adrian Cole
*/
package org.jclouds.aws.s3.domain;

View File

@ -37,10 +37,18 @@ import org.jclouds.http.HttpHeaders;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter;
import com.google.inject.Inject;
import com.google.inject.name.Named;
/**
* Signs the S3 request. This will update timestamps at most once per second.
*
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonS3/latest/RESTAuthentication.html"
* />
* @author Adrian Cole
*
*/
public class RequestAuthorizeSignature implements HttpRequestFilter {
private static final String[] firstHeadersToSign = new String[] {
HttpHeaders.CONTENT_MD5, HttpHeaders.CONTENT_TYPE, HttpHeaders.DATE };
@ -51,7 +59,8 @@ public class RequestAuthorizeSignature implements HttpRequestFilter {
public static final long BILLION = 1000000000;
private final AtomicReference<String> timeStamp;
private AtomicLong trigger = new AtomicLong(System.nanoTime() + 1 * BILLION);
private final AtomicLong trigger = new AtomicLong(System.nanoTime() + 1
* BILLION);
/**
* Start the time update service. Amazon clocks need to be within 900
@ -60,10 +69,12 @@ public class RequestAuthorizeSignature implements HttpRequestFilter {
* slow, synchronized command.
*/
synchronized void updateIfTimeOut() {
if (trigger.get() - System.nanoTime() <= 0) {
timeStamp.set(createNewStamp());
trigger.set(System.nanoTime() + 1 * BILLION);
}
trigger.set(System.nanoTime() + 1 * BILLION);
}
// this is a hotspot when submitted concurrently, so be lazy.
@ -120,8 +131,7 @@ public class RequestAuthorizeSignature implements HttpRequestFilter {
throws HttpException {
String signature;
try {
signature = S3Utils.hmacSha1Base64(toSign, secretKey
.getBytes());
signature = S3Utils.hmacSha1Base64(toSign, secretKey.getBytes());
} catch (Exception e) {
throw new HttpException("error signing request", e);
}
@ -137,7 +147,8 @@ public class RequestAuthorizeSignature implements HttpRequestFilter {
request.getHeaders().put(HttpHeaders.DATE, timestampAsHeaderString());
}
private static void appendAmzHeaders(HttpRequest request, StringBuilder toSign) {
private static void appendAmzHeaders(HttpRequest request,
StringBuilder toSign) {
Set<String> headers = new TreeSet<String>(request.getHeaders().keySet());
for (String header : headers) {
if (header.startsWith("x-amz-")) {
@ -150,13 +161,15 @@ public class RequestAuthorizeSignature implements HttpRequestFilter {
}
}
private static void appendHttpHeaders(HttpRequest request, StringBuilder toSign) {
private static void appendHttpHeaders(HttpRequest request,
StringBuilder toSign) {
for (String header : firstHeadersToSign)
toSign.append(valueOrEmpty(request.getHeaders().get(header)))
.append("\n");
}
private static void appendBucketName(HttpRequest request, StringBuilder toSign) {
private static void appendBucketName(HttpRequest request,
StringBuilder toSign) {
String hostHeader = request.getHeaders().get(HttpHeaders.HOST)
.iterator().next();
if (hostHeader.endsWith(".s3.amazonaws.com"))

View File

@ -0,0 +1,29 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.
* ====================================================================
*/
/**
* This package contains HttpRequestFilters needed to operate the REST api.
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/RESTAuthentication.html" />
* @author Adrian Cole
*/
package org.jclouds.aws.s3.filters;

View File

@ -21,7 +21,7 @@
* under the License.
* ====================================================================
*/
package org.jclouds.aws.s3.filters;
package org.jclouds.aws.s3.handlers;
import java.io.InputStream;
@ -30,6 +30,7 @@ import javax.annotation.Resource;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.S3ResponseException;
import org.jclouds.aws.s3.domain.S3Error;
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
import org.jclouds.aws.s3.reference.S3Headers;
import org.jclouds.aws.s3.xml.S3ParserFactory;
import org.jclouds.http.HttpFutureCommand;
@ -43,6 +44,7 @@ import com.google.inject.Inject;
/**
* This will parse and set an appropriate exception on the command object.
*
* @see S3Error
* @author Adrian Cole
*
*/

View File

@ -0,0 +1,29 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.
* ====================================================================
*/
/**
* This package contains HttpResponseHandlers needed to operate the REST api.
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/RESTAuthentication.html" />
* @author Adrian Cole
*/
package org.jclouds.aws.s3.handlers;

View File

@ -37,17 +37,28 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.Utils;
import org.jclouds.aws.s3.S3Connection;
import org.jclouds.aws.s3.S3Map;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.util.Utils;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.name.Named;
/**
* Implements core Map functionality with an {@link S3Connection}
* <p/>
* All commands will wait a maximum of ${jclouds.s3.map.timeout} milliseconds to
* complete before throwing an exception.
*
* @author Adrian Cole
*
* @param <V>
* value of the map
*/
public abstract class BaseS3Map<V> implements S3Map<String, V> {
protected final S3Connection connection;
@ -108,6 +119,11 @@ public abstract class BaseS3Map<V> implements S3Map<String, V> {
return object.getMetadata().getMd5();
}
/**
* attempts asynchronous gets on all objects.
*
* @see S3Connection#getObject(String, String)
*/
protected Set<S3Object> getAllObjects() {
Set<S3Object> objects = new HashSet<S3Object>();
Set<Future<S3Object>> futureObjects = new HashSet<Future<S3Object>>();

View File

@ -38,8 +38,9 @@ import com.google.inject.Inject;
import com.google.inject.Injector;
/**
* // TODO: Adrian: Document return getConnection!
* Uses a Guice Injector to configure the objects served by S3Context methods.
*
* @see Injector
* @author Adrian Cole
*/
public class GuiceS3Context implements S3Context {
@ -93,6 +94,8 @@ public class GuiceS3Context implements S3Context {
/**
* {@inheritDoc}
*
* @see Closer
*/
public void close() {
try {

View File

@ -51,10 +51,11 @@ import org.jclouds.http.HttpFutureCommandClient;
import com.google.inject.Inject;
/**
* {@inheritDoc} Uses {@link HttpFutureCommandClient} to invoke the REST API of
* S3.
* Uses {@link HttpFutureCommandClient} to invoke the REST API of S3.
*
* @see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?
* @see <a
* href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?"
* />
* @author Adrian Cole
*/
public class LiveS3Connection implements S3Connection {

View File

@ -35,17 +35,22 @@ import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.jclouds.Utils;
import org.jclouds.aws.s3.S3Connection;
import org.jclouds.aws.s3.S3InputStreamMap;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.util.Utils;
import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
/**
* Map representation of a live connection to S3.
* Map representation of a live connection to S3. All put operations will result
* in Md5 calculation. If this is not desired, use {@link LiveS3ObjectMap}
* instead.
*
* @see S3Connection
* @see BaseS3Map
* @author Adrian Cole
*/
public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
@ -56,10 +61,10 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
super(connection, bucket);
}
/*
* (non-Javadoc)
/**
* {@inheritDoc}
*
* @see org.jclouds.aws.s3.S3ObjectMapi#get(java.lang.Object)
* @see S3Connection#getObject(String, String)
*/
public InputStream get(Object o) {
try {
@ -73,10 +78,10 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
}
}
/*
* (non-Javadoc)
/**
* {@inheritDoc}
*
* @see org.jclouds.aws.s3.S3ObjectMapi#remove(java.lang.Object)
* @see S3Connection#deleteObject(String, String)
*/
public InputStream remove(Object o) {
InputStream old = get(o);
@ -91,10 +96,10 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
return old;
}
/*
* (non-Javadoc)
/**
* {@inheritDoc}
*
* @see org.jclouds.aws.s3.S3ObjectMapi#values()
* @see #getAllObjects()
*/
public Collection<InputStream> values() {
Collection<InputStream> values = new LinkedList<InputStream>();
@ -105,10 +110,10 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
return values;
}
/*
* (non-Javadoc)
/**
* {@inheritDoc}
*
* @see org.jclouds.aws.s3.S3ObjectMapi#entrySet()
* @see #getAllObjects()
*/
public Set<Map.Entry<String, InputStream>> entrySet() {
Set<Map.Entry<String, InputStream>> entrySet = new HashSet<Map.Entry<String, InputStream>>();
@ -119,6 +124,9 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
return entrySet;
}
/**
* {@inheritDoc}
*/
public class Entry implements java.util.Map.Entry<String, InputStream> {
private InputStream value;
@ -137,50 +145,62 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
return value;
}
/**
* {@inheritDoc}
*
* @see LiveS3InputStreamMap#put(String, InputStream)
*/
public InputStream setValue(InputStream value) {
return put(key, value);
}
}
private InputStream putInternal(String s, Object o) {
S3Object object = new S3Object(s);
try {
InputStream returnVal = containsKey(s) ? get(s) : null;
object.setData(o);
object.generateMd5();
connection.putObject(bucket, object).get(
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
return returnVal;
} catch (Exception e) {
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException(String.format(
"Error adding object %1$s:%2$s", bucket, object), e);
}
}
/*
* (non-Javadoc)
/**
* {@inheritDoc}
*
* @see org.jclouds.aws.s3.S3ObjectMap#putAll(java.util.Map)
* @see #putAllInternal(Map)
*/
public void putAll(Map<? extends String, ? extends InputStream> map) {
putAllInternal(map);
}
/**
* {@inheritDoc}
*
* @see #putAllInternal(Map)
*/
public void putAllBytes(Map<? extends String, ? extends byte[]> map) {
putAllInternal(map);
}
/**
* {@inheritDoc}
*
* @see #putAllInternal(Map)
*/
public void putAllFiles(Map<? extends String, ? extends File> map) {
putAllInternal(map);
}
/**
* {@inheritDoc}
*
* @see #putAllInternal(Map)
*/
public void putAllStrings(Map<? extends String, ? extends String> map) {
putAllInternal(map);
}
private void putAllInternal(Map<? extends String, ? extends Object> map) {
/**
* submits requests to add all objects and collects the results later. All
* values will have md5 calculated first. As a side-effect of this, the
* content will be copied into a byte [].
*
* @see S3Connection#putObject(String, S3Object)
*/
@VisibleForTesting
void putAllInternal(Map<? extends String, ? extends Object> map) {
try {
List<Future<byte[]>> puts = new ArrayList<Future<byte[]>>();
for (String key : map.keySet()) {
@ -199,43 +219,64 @@ public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
}
}
/*
* (non-Javadoc)
/**
* {@inheritDoc}
*
* @see org.jclouds.aws.s3.S3ObjectMap#putString(java.lang.String,
* java.lang.String)
* @see #putInternal(String, Object)
*/
public InputStream putString(String key, String value) {
return putInternal(key, value);
}
/*
* (non-Javadoc)
/**
* {@inheritDoc}
*
* @see org.jclouds.aws.s3.S3ObjectMap#putFile(java.lang.String,
* java.io.File)
* @see #putInternal(String, Object)
*/
public InputStream putFile(String key, File value) {
return putInternal(key, value);
}
/*
* (non-Javadoc)
/**
* {@inheritDoc}
*
* @see org.jclouds.aws.s3.S3ObjectMap#putBytes(java.lang.String, byte[])
* @see #putInternal(String, Object)
*/
public InputStream putBytes(String key, byte[] value) {
return putInternal(key, value);
}
/*
* (non-Javadoc)
/**
* {@inheritDoc}
*
* @see org.jclouds.aws.s3.S3ObjectMap#put(java.lang.String,
* java.io.InputStream)
* @see #putInternal(String, Object)
*/
public InputStream put(String key, InputStream value) {
return putInternal(key, value);
}
/**
*
* calculates md5 before adding the object to s3. As a side-effect of this,
* the content will be copied into a byte []. *
*
* @see S3Connection#putObject(String, S3Object)
*/
@VisibleForTesting
InputStream putInternal(String s, Object o) {
S3Object object = new S3Object(s);
try {
InputStream returnVal = containsKey(s) ? get(s) : null;
object.setData(o);
object.generateMd5();
connection.putObject(bucket, object).get(
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
return returnVal;
} catch (Exception e) {
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException(String.format(
"Error adding object %1$s:%2$s", bucket, object), e);
}
}
}

View File

@ -32,10 +32,10 @@ import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.jclouds.Utils;
import org.jclouds.aws.s3.S3Connection;
import org.jclouds.aws.s3.S3ObjectMap;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.util.Utils;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@ -43,6 +43,9 @@ import com.google.inject.assistedinject.Assisted;
/**
* Map representation of a live connection to S3.
*
* @see S3Connection
* @see BaseS3Map
*
* @author Adrian Cole
*/
public class LiveS3ObjectMap extends BaseS3Map<S3Object> implements S3ObjectMap {
@ -52,6 +55,11 @@ public class LiveS3ObjectMap extends BaseS3Map<S3Object> implements S3ObjectMap
super(connection, bucket);
}
/**
* {@inheritDoc}
*
* @see #values()
*/
public Set<java.util.Map.Entry<String, S3Object>> entrySet() {
Set<Map.Entry<String, S3Object>> entrySet = new HashSet<Map.Entry<String, S3Object>>();
for (S3Object value : values()) {
@ -79,12 +87,22 @@ public class LiveS3ObjectMap extends BaseS3Map<S3Object> implements S3ObjectMap
return value;
}
/**
* {@inheritDoc}
*
* @see LiveS3ObjectMap#put(String, S3Object)
*/
public S3Object setValue(S3Object value) {
return put(key, value);
}
}
/**
* {@inheritDoc}
*
* @see S3Connection#getObject(String, String)
*/
public S3Object get(Object key) {
try {
return connection.getObject(bucket, key.toString()).get(
@ -96,6 +114,11 @@ public class LiveS3ObjectMap extends BaseS3Map<S3Object> implements S3ObjectMap
}
}
/**
* {@inheritDoc}
*
* @see S3Connection#putObject(String, S3Object)
*/
public S3Object put(String key, S3Object value) {
S3Object returnVal = get(key);
try {
@ -103,12 +126,18 @@ public class LiveS3ObjectMap extends BaseS3Map<S3Object> implements S3ObjectMap
TimeUnit.MILLISECONDS);
} catch (Exception e) {
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException(String.format(
"Error putting object %1$s:%2$s%n%1$s", bucket, key, value), e);
throw new S3RuntimeException(
String.format("Error putting object %1$s:%2$s%n%1$s",
bucket, key, value), e);
}
return returnVal;
}
/**
* {@inheritDoc} attempts to put all objects asynchronously.
*
* @see S3Connection#putObject(String, S3Object)
*/
public void putAll(Map<? extends String, ? extends S3Object> map) {
try {
List<Future<byte[]>> puts = new ArrayList<Future<byte[]>>();
@ -125,6 +154,11 @@ public class LiveS3ObjectMap extends BaseS3Map<S3Object> implements S3ObjectMap
}
}
/**
* {@inheritDoc}
*
* @see S3Connection#deleteObject(String, String)
*/
public S3Object remove(Object key) {
S3Object old = get(key);
try {
@ -138,6 +172,11 @@ public class LiveS3ObjectMap extends BaseS3Map<S3Object> implements S3ObjectMap
return old;
}
/**
* {@inheritDoc}
*
* @see #getAllObjects()
*/
public Collection<S3Object> values() {
return getAllObjects();
}

View File

@ -0,0 +1,28 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.
* ====================================================================
*/
/**
* This package contains implementation classes for the jclouds-s3 public api
* @author Adrian Cole
*/
package org.jclouds.aws.s3.internal;

View File

@ -1,7 +1,30 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.
* ====================================================================
*/
/**
* This package contains an Amazon S3 client implemented by {@link HttpFutureCommand} commands.
*
* @see http://aws.amazon.com/s3/
* @see <a href="http://aws.amazon.com/s3"/>
* @author Adrian Cole
*/
package org.jclouds.aws.s3;

View File

@ -27,7 +27,7 @@ import org.jclouds.command.pool.PoolConstants;
import org.jclouds.http.HttpConstants;
/**
* // TODO: Adrian: Document this!
* Configuration properties and constants used in S3 connections.
*
* @author Adrian Cole
*/
@ -35,6 +35,10 @@ public interface S3Constants extends HttpConstants, PoolConstants, S3Headers {
public static final String PROPERTY_AWS_SECRETACCESSKEY = "jclouds.aws.secretaccesskey";
public static final String PROPERTY_AWS_ACCESSKEYID = "jclouds.aws.accesskeyid";
/**
* longest time a single Map operation can take before throwing an
* exception.
*/
public static final String PROPERTY_S3_MAP_TIMEOUT = "jclouds.s3.map.timeout";
}

View File

@ -25,7 +25,15 @@ package org.jclouds.aws.s3.reference;
import org.jclouds.http.HttpHeaders;
public interface S3Headers extends HttpHeaders{
/**
* Additional headers specified by Amazon S3 REST API.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/index.html?RESTAuthentication.html"
* />
* @author Adrian Cole
*
*/
public interface S3Headers extends HttpHeaders {
/**
* The canned ACL to apply to the object. Options include private,

View File

@ -0,0 +1,28 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.
* ====================================================================
*/
/**
* This package contains properties and reference data used in S3.
* @author Adrian Cole
*/
package org.jclouds.aws.s3.reference;

View File

@ -28,6 +28,12 @@ import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
/**
* Parses dates found in XML responses and HTTP response headers.
*
* @author Adrian Cole
*
*/
public class DateService {
private DateTimeFormatter headerDateFormat = DateTimeFormat
.forPattern("EEE, dd MMM yyyy HH:mm:ss 'GMT'");

View File

@ -43,9 +43,16 @@ import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Base64;
import org.jclouds.Utils;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.util.Utils;
/**
* Encryption, Hashing, and IO Utilities needed to sign and verify S3 requests
* and responses.
*
* @author Adrian Cole
*
*/
public class S3Utils extends Utils {
private static final Pattern IP_PATTERN = Pattern

View File

@ -0,0 +1,28 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.
* ====================================================================
*/
/**
* This package contains utilities needed for S3.
* @author Adrian Cole
*/
package org.jclouds.aws.s3.util;

View File

@ -32,7 +32,12 @@ import com.google.inject.Inject;
/**
* Parses the response from Amazon S3 COPY Object command.
* <p/>
* CopyObjectResult is the document we expect to parse.
*
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTObjectCOPY.html"
* />
* @author Adrian Cole
*/
public class CopyObjectHandler extends

View File

@ -29,9 +29,8 @@ import org.jclouds.http.commands.callables.xml.ParseSax;
/**
* Parses the error from the Amazon S3 REST API.
*
* @see http
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?UsingRESTError
* .html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?UsingRESTError.html"
* />
* @author Adrian Cole
*/
public class ErrorHandler extends ParseSax.HandlerWithResult<S3Error> {

View File

@ -38,9 +38,8 @@ import com.google.inject.Inject;
* <p/>
* ListAllMyBucketsResult xmlns="http://doc.s3.amazonaws.com/2006-03-01"
*
* @see http
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTServiceGET
* .html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTServiceGET.html"
* />
* @author Adrian Cole
*/
public class ListAllMyBucketsHandler extends

View File

@ -40,9 +40,8 @@ import com.google.inject.Inject;
* <p/>
* ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01"
*
* @see http
* ://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET
* .html
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html"
* />
* @author Adrian Cole
*/
public class ListBucketHandler extends ParseSax.HandlerWithResult<S3Bucket> {

View File

@ -0,0 +1,28 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.
* ====================================================================
*/
/**
* This package contains logic that assembles xml parsing callables.
* @author Adrian Cole
*/
package org.jclouds.aws.s3.xml.config;

View File

@ -0,0 +1,28 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.
* ====================================================================
*/
/**
* This package contains xml logic that parses S3 responses.
* @author Adrian Cole
*/
package org.jclouds.aws.s3.xml;

View File

@ -34,8 +34,8 @@ import java.util.TreeSet;
import java.util.Map.Entry;
import org.apache.commons.io.IOUtils;
import org.jclouds.Utils;
import org.jclouds.aws.s3.internal.BaseS3Map;
import org.jclouds.util.Utils;
import org.testng.annotations.Test;
/**

View File

@ -56,12 +56,11 @@ import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import com.google.inject.Module;
@Test
public class S3IntegrationTest {
protected static final String TEST_STRING = "<apples><apple name=\"fuji\" /></apples>";
protected static final String TEST_STRING = "<apples><apple name=\"fuji\"></apple> </apples>";
protected byte[] goodMd5;
protected byte[] badMd5;
@ -184,8 +183,8 @@ public class S3IntegrationTest {
protected void deleteEverything() throws Exception {
try {
List<S3Bucket.Metadata> metadata = client.listOwnedBuckets().get(10,
TimeUnit.SECONDS);
List<S3Bucket.Metadata> metadata = client.listOwnedBuckets().get(
10, TimeUnit.SECONDS);
List<Future<Boolean>> results = new ArrayList<Future<Boolean>>();
for (S3Bucket.Metadata metaDatum : metadata) {
if (metaDatum.getName().startsWith(bucketPrefix.toLowerCase())) {

View File

@ -1,6 +1,6 @@
/**
*
* Getright (C) 2009 Adrian Cole <adrian@jclouds.org>
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.aws.s3.commands.callables;
import static org.testng.Assert.*;

View File

@ -25,14 +25,14 @@ package org.jclouds.aws.s3.config;
import static org.testng.Assert.assertEquals;
import org.jclouds.aws.s3.filters.ParseS3ErrorFromXmlContent;
import org.jclouds.aws.s3.handlers.ParseS3ErrorFromXmlContent;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.http.CloseContentAndSetExceptionHandler;
import org.jclouds.http.HttpResponseHandler;
import org.jclouds.http.annotation.ClientErrorHandler;
import org.jclouds.http.annotation.RedirectHandler;
import org.jclouds.http.annotation.ServerErrorHandler;
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
import org.jclouds.http.handlers.CloseContentAndSetExceptionHandler;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

View File

@ -40,6 +40,6 @@ public class S3ObjectTest {
File file = new File("hello.txt");
object.setData(file);
assertEquals(object.getMetadata().getContentType(),
ContentTypes.UNKNOWN_MIME_TYPE);
ContentTypes.BINARY);
}
}