You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by wo...@apache.org on 2010/09/16 23:43:41 UTC

svn commit: r997929 - in /incubator/libcloud/sandbox/java/trunk/src: base/connection/ base/interfaces/ base/types/ libcloud/providers/rackspace/ simplecloud/storage/ simplecloud/storage/data/ simplecloud/storage/interfaces/ simplecloud/storage/provider...

Author: woodser
Date: Thu Sep 16 21:43:40 2010
New Revision: 997929

URL: http://svn.apache.org/viewvc?rev=997929&view=rev
Log:
Additional SimpleCloud support.
- Generic "Item" to represent unit of data.
- Modifications to ConnectionKey & Response to support generic Item type
- SimpleCloud S3 adapter in progress (7/10 API calls working)

Added:
    incubator/libcloud/sandbox/java/trunk/src/base/interfaces/IItem.java
    incubator/libcloud/sandbox/java/trunk/src/base/types/
    incubator/libcloud/sandbox/java/trunk/src/base/types/Item.java
    incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/Example.java
      - copied, changed from r997113, incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/Main.java
Removed:
    incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/data/
    incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/Main.java
Modified:
    incubator/libcloud/sandbox/java/trunk/src/base/connection/ConnectionKey.java
    incubator/libcloud/sandbox/java/trunk/src/base/connection/LoggingConnection.java
    incubator/libcloud/sandbox/java/trunk/src/base/connection/Response.java
    incubator/libcloud/sandbox/java/trunk/src/base/interfaces/IConnection.java
    incubator/libcloud/sandbox/java/trunk/src/base/interfaces/IResponse.java
    incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceConnection.java
    incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/interfaces/IStorageAdapter.java
    incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Adapter.java
    incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Handler.java

Modified: incubator/libcloud/sandbox/java/trunk/src/base/connection/ConnectionKey.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/base/connection/ConnectionKey.java?rev=997929&r1=997928&r2=997929&view=diff
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/base/connection/ConnectionKey.java (original)
+++ incubator/libcloud/sandbox/java/trunk/src/base/connection/ConnectionKey.java Thu Sep 16 21:43:40 2010
@@ -22,12 +22,14 @@ import org.apache.http.client.methods.Ht
 import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.client.utils.URIUtils;
 import org.apache.http.client.utils.URLEncodedUtils;
+import org.apache.http.entity.InputStreamEntity;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.message.BasicNameValuePair;
 
 import base.Driver;
 import base.interfaces.IConnection;
+import base.interfaces.IItem;
 
 /*
  * Manages a connection with a secret access key.
@@ -80,6 +82,10 @@ public abstract class ConnectionKey impl
 	public void connect() {
 		connect(host, port);
 	}
+	
+	public void connect(String host) {
+		connect(host, -1);
+	}
 
 	public void connect(String host, int port) {
 		this.host = host;
@@ -94,9 +100,10 @@ public abstract class ConnectionKey impl
 	}
 
 	public Response request(String method, String path,
-			Map<String, String> headers, Map<String, String> params, String data) {
+			Map<String, String> headers, Map<String, String> params, Object data) {
 		this.method = method;
 		this.path = path;
+		IItem item = data instanceof IItem ? (IItem)data : null;
 		
 		// Connect if not already connected
 		if (httpClient == null) {
@@ -107,6 +114,10 @@ public abstract class ConnectionKey impl
 		Map<String, String> reqHeaders = new HashMap<String, String>();
 		reqHeaders.put("User-Agent", getUserAgent());		// 3: libcloud headers
 		reqHeaders.put("Host", host);
+		if (item != null) {									// 4: item headers
+			if (item.getContentType() != null) reqHeaders.put("Content-Type", item.getContentType());
+			if (item.getContentEncoding() != null) reqHeaders.put("Content-Encoding", item.getContentEncoding());
+		}
 		if (headers != null) reqHeaders.putAll(headers);	// 2: argument headers
 		reqHeaders = addDefaultHeaders(reqHeaders);			// 1: provider headers
 		
@@ -138,15 +149,22 @@ public abstract class ConnectionKey impl
 		} else {
 			throw new IllegalArgumentException("Illegal HTTP method: " + method);
 		}
-
+		
 		// Encode and add the payload data
-		String encoded = encodeData(data);
-		if (encoded != null && !encoded.equals("")) {
-			try {
-				((HttpEntityEnclosingRequest) request).setEntity(new StringEntity(encoded));
-			} catch (UnsupportedEncodingException e) {
-				e.printStackTrace();
-				return null;
+		if (data instanceof IItem) {
+			InputStreamEntity entity = new InputStreamEntity(item.getContent(), item.getContentLength());
+			entity.setContentType(item.getContentType());
+			entity.setContentEncoding(item.getContentEncoding());
+			((HttpEntityEnclosingRequest)request).setEntity(entity);
+		} else {
+			String encoded = encodeData((String)data);
+			if (encoded != null && !encoded.equals("")) {
+				try {
+					((HttpEntityEnclosingRequest) request).setEntity(new StringEntity(encoded));
+				} catch (UnsupportedEncodingException e) {
+					e.printStackTrace();
+					return null;
+				}
 			}
 		}
 

Modified: incubator/libcloud/sandbox/java/trunk/src/base/connection/LoggingConnection.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/base/connection/LoggingConnection.java?rev=997929&r1=997928&r2=997929&view=diff
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/base/connection/LoggingConnection.java (original)
+++ incubator/libcloud/sandbox/java/trunk/src/base/connection/LoggingConnection.java Thu Sep 16 21:43:40 2010
@@ -34,7 +34,7 @@ public class LoggingConnection extends C
 			}
 		}
 
-		logEntry += "\r\n" + response.body + "\r\n";
+		logEntry += "\r\n" + response.getBody() + "\r\n";
 		logEntry += "\n# -------- end response ------------\n";
 		
 		return logEntry;

Modified: incubator/libcloud/sandbox/java/trunk/src/base/connection/Response.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/base/connection/Response.java?rev=997929&r1=997928&r2=997929&view=diff
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/base/connection/Response.java (original)
+++ incubator/libcloud/sandbox/java/trunk/src/base/connection/Response.java Thu Sep 16 21:43:40 2010
@@ -1,17 +1,16 @@
 package base.connection;
 
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
+import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.http.Header;
-import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.ProtocolVersion;
 
+import base.interfaces.IItem;
 import base.interfaces.IResponse;
+import base.types.Item;
 
 
 public class Response implements IResponse {
@@ -20,7 +19,7 @@ public class Response implements IRespon
 	
 	protected String phrase;
 	
-	protected String body;
+	protected IItem item;
 	
 	protected ProtocolVersion version;
 	
@@ -37,23 +36,8 @@ public class Response implements IRespon
 		// Retrieve reason from response
 		phrase = response.getStatusLine().getReasonPhrase();
 		
-		// Retrieve body from response
-		body = null;
-		HttpEntity entity = response.getEntity();
-		if (entity != null) {
-			try {
-				String line = null;
-				StringBuffer bodySb = new StringBuffer();
-				BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
-				while ((line = reader.readLine()) != null) {
-					bodySb.append(line);
-				}
-				body = bodySb.toString();
-				entity.consumeContent();
-			} catch (IOException ioe) {
-				ioe.printStackTrace();
-			}
-		}
+		// Set the item using the responses's entity
+		item = new Item(response.getEntity());
 		
 		// Retrieve headers from response
 		headers = new HashMap<String, String>();
@@ -63,7 +47,15 @@ public class Response implements IRespon
 	}
 
 	public String getBody() {
-		return body;
+		return item.getContentString();
+	}
+	
+	public InputStream getBodyStream() {
+		return item.getContent();
+	}
+	
+	public IItem getItem() {
+		return item;
 	}
 
 	public ProtocolVersion getVersion() {
@@ -90,7 +82,7 @@ public class Response implements IRespon
 			sb.append('\t' + key + ": " + headers.get(key) + '\n');
 		}
 		sb.append("Body: ");
-		sb.append(body);
+		sb.append("[disabled - see Item]");
 		return sb.toString();
 	}
 }

Modified: incubator/libcloud/sandbox/java/trunk/src/base/interfaces/IConnection.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/base/interfaces/IConnection.java?rev=997929&r1=997928&r2=997929&view=diff
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/base/interfaces/IConnection.java (original)
+++ incubator/libcloud/sandbox/java/trunk/src/base/interfaces/IConnection.java Thu Sep 16 21:43:40 2010
@@ -7,9 +7,11 @@ import base.connection.Response;
 public interface IConnection {
 
 	public void connect();
+	
+	public void connect(String host);
 
 	public void connect(String host, int port);
 	
 	public Response request(String method, String action,
-			Map<String, String> headers, Map<String, String> params, String data);
+			Map<String, String> headers, Map<String, String> params, Object data);
 }

Added: incubator/libcloud/sandbox/java/trunk/src/base/interfaces/IItem.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/base/interfaces/IItem.java?rev=997929&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/base/interfaces/IItem.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/base/interfaces/IItem.java Thu Sep 16 21:43:40 2010
@@ -0,0 +1,81 @@
+package base.interfaces;
+
+import java.io.InputStream;
+
+/*
+ * Defines the base unit of generic "data" for sending and receiving.
+ */
+public interface IItem {
+	
+	/*
+	 * Represents the content's stream as a String.
+	 * 
+	 * NOTE: The data's InputStream may not be consumable after this
+	 * 
+	 * @return String represents the data as a String
+	 */
+	public String getContentString();
+	
+	/*
+	 * Sets the String that represents this data.
+	 * 
+	 * @param data is the String that represents this data
+	 */
+	public void setContentString(String data);
+	
+	/*
+	 * Returns the raw InputStream of the data.
+	 * 
+	 * @return InputStream is the data's InputStream
+	 */
+	public InputStream getContent();
+	
+	/*
+	 * Sets the InputStream which defines this data.
+	 * 
+	 * @param stream is the InputStream to define the data
+	 */
+	public void setContent(InputStream stream);
+	
+	/*
+	 * Indicates this data's Content-Type.
+	 * 
+	 * @return String defines this data's Content-Type.
+	 */
+	public String getContentType();
+	
+	/*
+	 * Sets the Content-Type of this data.
+	 * 
+	 * @param type is this data's Content-Type
+	 */
+	public void setContentType(String type);
+	
+	/*
+	 * Indicates this data's Content-Encoding.
+	 * 
+	 * @return String defines this data's Content-Encoding.
+	 */
+	public String getContentEncoding();
+	
+	/*
+	 * Sets the Content-Encoding of this data.
+	 * 
+	 * @param encoding indicates the data's encoding
+	 */
+	public void setContentEncoding(String encoding);
+	
+	/*
+	 * Indicates the length of the data.
+	 * 
+	 * @return long indicates the length of the data
+	 */
+	public long getContentLength();
+	
+	/*
+	 * Sets the Content-Length of this data.
+	 * 
+	 * @param length is the data's length
+	 */
+	public void setContentLength(long length);
+}

Modified: incubator/libcloud/sandbox/java/trunk/src/base/interfaces/IResponse.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/base/interfaces/IResponse.java?rev=997929&r1=997928&r2=997929&view=diff
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/base/interfaces/IResponse.java (original)
+++ incubator/libcloud/sandbox/java/trunk/src/base/interfaces/IResponse.java Thu Sep 16 21:43:40 2010
@@ -1,14 +1,50 @@
 package base.interfaces;
 
+import java.io.InputStream;
 import java.util.Map;
 
+/*
+ * Defines a request's response.
+ */
 public interface IResponse {
 	
+	/*
+	 * Indicates the status of the request (e.g. 200)
+	 */
 	public int getStatus();
 	
+	/*
+	 * Returns the content of the response as a String.
+	 * 
+	 * @return String is the body of the response interpreted as a String
+	 */
 	public String getBody();
 	
+	/*
+	 * Returns the raw InputStream of the response.
+	 * 
+	 * @return InputStream is a stream of bytes composing the response content
+	 */
+	public InputStream getBodyStream();
+	
+	/*
+	 * Returns the response's content as an Item.
+	 * 
+	 * @return IItem is the response's content as an Item
+	 */
+	public IItem getItem();
+	
+	/*
+	 * Indicates the phrase of the response status.
+	 * 
+	 * @return String is the phrase corresponding with the status
+	 */
 	public String getPhrase();
 	
+	/*
+	 * Returns the headers included in the request's response.
+	 * 
+	 * @return Map<String, String> are the respone's headers
+	 */
 	public Map<String, String> getHeaders();
 }

Added: incubator/libcloud/sandbox/java/trunk/src/base/types/Item.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/base/types/Item.java?rev=997929&view=auto
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/base/types/Item.java (added)
+++ incubator/libcloud/sandbox/java/trunk/src/base/types/Item.java Thu Sep 16 21:43:40 2010
@@ -0,0 +1,120 @@
+package base.types;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import org.apache.http.HttpEntity;
+
+import base.interfaces.IItem;
+
+public class Item implements IItem {
+	
+	private String string;
+	private InputStream content;
+	private String type;
+	private String encoding;
+	private long length;
+	
+	public Item() {
+		this.string = null;
+		this.content = null;
+		this.type = null;
+		this.encoding = null;
+		this.length = -1;
+	}
+	
+	public Item(InputStream content, String contentType, String contentEncoding, long length) {
+		this.content = content;
+		this.type = contentType;
+		this.encoding = contentEncoding;
+		this.length = length;
+		this.string = null;
+	}
+	
+	public Item(HttpEntity entity) {
+		this.string = null;
+		this.content = null;
+		this.type = null;
+		this.encoding = null;
+		this.length = -1;
+		
+		if (entity == null) return;
+		try {
+			this.content = entity.getContent();
+			this.length = entity.getContentLength();
+			if (entity.getContentType() != null) this.type = entity.getContentType().getValue();
+			if (entity.getContentEncoding() != null) this.encoding = entity.getContentEncoding().getValue();
+		} catch (IllegalStateException e1) {
+			e1.printStackTrace();
+		} catch (IOException e1) {
+			e1.printStackTrace();
+		}
+	}
+
+	public String getContentString() {
+		// Can only consume once
+		if (string != null) return string;
+		
+		// No response if stream is null
+		if (content == null) return "";
+		
+		// Lets consume some InputStream
+		try {
+			String line = null;
+			StringBuffer sb = new StringBuffer();
+			BufferedReader reader = new BufferedReader(new InputStreamReader(content));
+			while ((line = reader.readLine()) != null) {
+				sb.append(line);
+			}
+			string = sb.toString();
+			return string;
+		} catch (IOException ioe) {
+			ioe.printStackTrace();
+		}
+		return null;
+	}
+
+	public void setContentString(String data) {
+		this.string = data;
+	}
+
+	public InputStream getContent() {
+		return content;
+	}
+
+	public void setContent(InputStream content) {
+		this.content = content;
+	}
+
+	public String getContentType() {
+		return type;
+	}
+
+	public void setContentType(String type) {
+		this.type = type;
+	}
+
+	public String getContentEncoding() {
+		return encoding;
+	}
+
+	public void setContentEncoding(String encoding) {
+		this.encoding = encoding;
+	}
+
+	public long getContentLength() {
+		return length;
+	}
+
+	public void setContentLength(long length) {
+		this.length = length;
+	}
+	
+	public String toString() {
+		return "<Content-Type=" + type + ", " + 
+			"Encoding=" + encoding + ", " + 
+			"Length=" + length + "...>";
+	}
+}

Modified: incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceConnection.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceConnection.java?rev=997929&r1=997928&r2=997929&view=diff
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceConnection.java (original)
+++ incubator/libcloud/sandbox/java/trunk/src/libcloud/providers/rackspace/RackspaceConnection.java Thu Sep 16 21:43:40 2010
@@ -37,7 +37,7 @@ public class RackspaceConnection extends
 		
 		RackspaceConnection connection = new RackspaceConnection(username, apiKey, DEFAULT_SECURE, 
 				AUTH_HOST, DEFAULT_PORT, null);
-		IResponse response = connection.request("GET", "v1.0", headers, null, null);
+		IResponse response = connection.request("GET", "v1.0", headers, null, "");
 		
 		if (response.getStatus() == SUCCESSFUL_AUTH) {
 			Map<String, String> responseHeaders = response.getHeaders();

Copied: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/Example.java (from r997113, incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/Main.java)
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/Example.java?p2=incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/Example.java&p1=incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/Main.java&r1=997113&r2=997929&rev=997929&view=diff
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/Main.java (original)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/Example.java Thu Sep 16 21:43:40 2010
@@ -1,14 +1,39 @@
-package simplecloud.storage.providers.amazon;
+package simplecloud.storage;
 
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Map;
 
-public class Main {
+import simplecloud.storage.providers.amazon.S3Adapter;
+import base.types.Item;
+
+public class Example {
 
 	public static void main(String [] args) {
-		S3Adapter adapter = new S3Adapter("access key id", "access key", "s3.amazonaws.com");
+		S3Adapter adapter = new S3Adapter("your access key id", "your access key", "s3.amazonaws.com");
 		Map<String, String> options = new HashMap<String, String>();
-		options.put(S3Adapter.Type.BUCKET.toString(), "ericlibcloud");
-		adapter.fetchItem("/hello.jpg", options);
+		
+		// Upload something
+		try {
+			String localPath = "/Users/Eric/libcloud_demo.jpg";
+			String contentType = "image/jpeg";
+			File file = new File(localPath);
+			InputStream stream = new BufferedInputStream(new FileInputStream(file));
+			Item item = new Item(stream, contentType, null, file.length());
+			options.put(S3Adapter.Type.SRC_BUCKET.toString(), "ericlibcloud");
+			adapter.storeItem("/libcloud_demo_stored.jpg", item, options);
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		}
+		
+//		options.put(S3Adapter.Type.SRC_BUCKET.toString(), "ericlibcloud");
+//		for (String item : adapter.listItems("/", options)) {
+//			System.out.println(item);
+//		}
+//		adapter.renameItem("/libcloud_demo.jpg", "libcloud_demo2.jpg", options);
 	}
 }

Modified: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/interfaces/IStorageAdapter.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/interfaces/IStorageAdapter.java?rev=997929&r1=997928&r2=997929&view=diff
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/interfaces/IStorageAdapter.java (original)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/interfaces/IStorageAdapter.java Thu Sep 16 21:43:40 2010
@@ -3,7 +3,7 @@ package simplecloud.storage.interfaces;
 import java.util.List;
 import java.util.Map;
 
-import simplecloud.storage.data.Item;
+import base.interfaces.IItem;
 
 /*
  * Common interface for unstructured cloud storage.
@@ -13,9 +13,9 @@ import simplecloud.storage.data.Item;
  */
 public interface IStorageAdapter {
 	
-	public Item fetchItem(String path, Map<String, String> options);
+	public IItem fetchItem(String path, Map<String, String> options);
 	
-	public boolean storeItem(String destinationPath, Item item, Map<String, String> options);
+	public boolean storeItem(String destinationPath, IItem item, Map<String, String> options);
 	
 	public void deleteItem(String path, Map<String, String> options);
 	

Modified: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Adapter.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Adapter.java?rev=997929&r1=997928&r2=997929&view=diff
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Adapter.java (original)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Adapter.java Thu Sep 16 21:43:40 2010
@@ -1,10 +1,26 @@
 package simplecloud.storage.providers.amazon;
 
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
 import simplecloud.storage.StorageAdapter;
-import simplecloud.storage.data.Item;
+import base.interfaces.IItem;
 import base.interfaces.IResponse;
 
 /*
@@ -14,8 +30,12 @@ public class S3Adapter extends StorageAd
 	
 	private final String HOST;
 	
+	/*
+	 * TEMP TODO: see if this is of value.
+	 */
 	public enum Type {
-		BUCKET("bucket");
+		SRC_BUCKET("srcBucket"),
+		DEST_BUCKET("destBucket");
 		
 		private String value;
 		private Type(String value) {
@@ -38,53 +58,81 @@ public class S3Adapter extends StorageAd
 		connection = new S3Connection(accessId, accessKey, host, this);
 	}
 
-	@Override
-	public Item fetchItem(String path, Map<String, String> options) {
-		String bucket = options.get(Type.BUCKET.toString());
-		connection.connect(bucket + '.' + HOST, -1);	// TODO: connect to port only (add method)
+	public IItem fetchItem(String path, Map<String, String> options) {
+		String bucket = options.get(Type.SRC_BUCKET.toString());
+		connection.connect(bucket + '.' + HOST);
 		IResponse response = connection.request("GET", path, null, null, null);
-		System.out.println("Response: " + response.toString());
-		//S3Handler handler = new S3Handler(response);
-		return null;
+		S3Handler rh = new S3Handler(response);
+		return (IItem)rh.getParsedObject();
 	}
 
-	@Override
-	public boolean storeItem(String destinationPath, Item item,
-			Map<String, String> options) {
-		// TODO Auto-generated method stub
-		return false;
+	public boolean storeItem(String destinationPath, IItem item, Map<String, String> options) {
+		String bucket = options.get(Type.SRC_BUCKET.toString());
+		connection.connect(bucket + '.' + HOST);
+		IResponse response = connection.request("PUT", destinationPath, null, null, item);
+		new S3Handler(response);
+		return response.getStatus() == 200;
 	}
-
-	@Override
+	
 	public void deleteItem(String path, Map<String, String> options) {
-		// TODO Auto-generated method stub
-		
+		String bucket = options.get(Type.SRC_BUCKET.toString());
+		connection.connect(bucket + '.' + HOST);
+		IResponse response = connection.request("DELETE", path, null, null, null);
+		new S3Handler(response);
 	}
 
-	@Override
-	public void copyItem(String sourcePath, String destinationPath,
-			Map<String, String> options) {
-		// TODO Auto-generated method stub
-		
+	public void copyItem(String sourcePath, String destinationPath, Map<String, String> options) {
+		String srcBucket = options.get(Type.SRC_BUCKET.toString());
+		String destBucket = options.get(Type.DEST_BUCKET.toString());
+		connection.connect(destBucket + '.' + HOST);
+		Map<String, String> headers = new HashMap<String, String>();
+		headers.put("x-amz-copy-source", '/' + srcBucket + sourcePath);
+		IResponse response = connection.request("PUT", destinationPath, headers, null, null);
+		new S3Handler(response);
 	}
 
-	@Override
 	public void moveItem(String sourcePath, String destinationPath,
 			Map<String, String> options) {
-		// TODO Auto-generated method stub
-		
+		// Copy the item
+		String srcBucket = options.get(Type.SRC_BUCKET.toString());
+		String destBucket = options.get(Type.DEST_BUCKET.toString());
+		connection.connect(destBucket + '.' + HOST);
+		Map<String, String> headers = new HashMap<String, String>();
+		headers.put("x-amz-copy-source", '/' + srcBucket + sourcePath);
+		IResponse response = connection.request("PUT", destinationPath, headers, null, null);
+		new S3Handler(response);
+		
+		// Delete the original
+		connection.connect(srcBucket + '.' + HOST);
+		response = connection.request("DELETE", sourcePath, null, null, null);
+		new S3Handler(response);
 	}
 
-	@Override
 	public void renameItem(String path, String name, Map<String, String> options) {
-		// TODO Auto-generated method stub
-		
+		String destPath = path.substring(0, path.lastIndexOf('/') + 1) + name;
+		options.put(Type.DEST_BUCKET.toString(), options.get(Type.SRC_BUCKET.toString()));
+		moveItem(path, destPath, options);
 	}
 
-	@Override
 	public List<String> listItems(String path, Map<String, String> options) {
-		// TODO Auto-generated method stub
-		return null;
+		String bucket = options.get(Type.SRC_BUCKET.toString());
+		connection.connect(bucket + '.' + HOST);
+		IResponse response = connection.request("GET", path, null, null, null);
+		S3Handler rh = new S3Handler(response);
+		IItem item = (IItem)rh.getParsedObject();
+		try {
+			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+			DocumentBuilder db = dbf.newDocumentBuilder();
+			Document doc = db.parse(item.getContent());
+			return parseItems(doc.getDocumentElement());
+		} catch (ParserConfigurationException e) {
+			e.printStackTrace();
+		} catch (SAXException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return null;	// Error
 	}
 
 	@Override
@@ -106,5 +154,19 @@ public class S3Adapter extends StorageAd
 		// TODO Auto-generated method stub
 		
 	}
-
+	
+	private List<String> parseItems(Element elem) {
+		XPath xpath = XPathFactory.newInstance().newXPath();
+		try {
+			List<String> items = new ArrayList<String>();
+			NodeList keys = (NodeList)xpath.evaluate("Contents/Key", elem, XPathConstants.NODESET);
+			for (int i = 0; i < keys.getLength(); i++) {
+				items.add(keys.item(i).getTextContent());
+			}
+			return items;
+		} catch (XPathExpressionException e) {
+			e.printStackTrace();
+		}
+		return null;	// Error
+	}
 }

Modified: incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Handler.java
URL: http://svn.apache.org/viewvc/incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Handler.java?rev=997929&r1=997928&r2=997929&view=diff
==============================================================================
--- incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Handler.java (original)
+++ incubator/libcloud/sandbox/java/trunk/src/simplecloud/storage/providers/amazon/S3Handler.java Thu Sep 16 21:43:40 2010
@@ -1,12 +1,28 @@
 package simplecloud.storage.providers.amazon;
 
+import java.io.IOException;
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import libcloud.exceptions.InvalidCredsException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
 import base.connection.ResponseHandler;
 import base.interfaces.IResponse;
 
 /*
  * Custom handles responses from S3.
- * 
- * TODO: override parseError()
  */
 public class S3Handler extends ResponseHandler {
 
@@ -15,6 +31,45 @@ public class S3Handler extends ResponseH
 	}
 	
 	protected void parseBody() {
-		object = null;
+		object = response.getItem();
+	}
+	
+	protected String parseError() {
+		try {
+			// Parse errors
+			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+			DocumentBuilder db = dbf.newDocumentBuilder();
+			Document doc = db.parse(new InputSource(new StringReader(response.getBody())));
+			XPath xpath = XPathFactory.newInstance().newXPath();
+			NodeList errors = (NodeList)xpath.evaluate("/Error", doc.getDocumentElement(), XPathConstants.NODESET);
+			
+			// Process errors
+			StringBuffer sb = new StringBuffer();
+			for (int i = 0; i < errors.getLength(); i++) {
+				String error = (String)xpath.evaluate("Code", errors.item(i));
+				String message = (String)xpath.evaluate("Message", errors.item(i));
+				if (error.equals("InvalidClientTokenId")) {
+					throw new InvalidCredsException(response.getStatus() + " " + error + ": " + message);
+				} else if (error.equals("SignatureDoesNotMatch")) {
+					throw new InvalidCredsException(response.getStatus() + " " + error + ": " + message);
+				} else if (error.equals("AuthFailure")) {
+					throw new InvalidCredsException(response.getStatus() + " " + error + ": " + message);
+				} else if (error.equals("OptInRequired")) {
+					throw new InvalidCredsException(response.getStatus() + " " + error + ": " + message);
+				} else {
+					sb.append(response.getStatus() + " " + error + ": " + message + '\n');
+				}
+			}
+			return sb.toString().trim();
+		} catch (ParserConfigurationException e) {
+			e.printStackTrace();
+		} catch (SAXException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		} catch (XPathExpressionException e) {
+			e.printStackTrace();
+		}
+		return super.parseError();
 	}
 }