package org.xmlsh.aws;
import java.io.IOException;
import java.util.List;
import javax.xml.stream.XMLStreamException;
import org.xmlsh.annotations.Command;
import org.xmlsh.aws.util.AWSS3Command;
import org.xmlsh.aws.util.S3Path;
import org.xmlsh.core.CoreException;
import org.xmlsh.core.Options;
import org.xmlsh.core.UnexpectedException;
import org.xmlsh.core.XValue;
import org.xmlsh.util.Util;
import com.amazonaws.AmazonClientException;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.ListMultipartUploadsRequest;
import com.amazonaws.services.s3.model.ListObjectsRequest;
import com.amazonaws.services.s3.model.ListVersionsRequest;
import com.amazonaws.services.s3.model.MultipartUpload;
import com.amazonaws.services.s3.model.MultipartUploadListing;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.amazonaws.services.s3.model.S3VersionSummary;
import com.amazonaws.services.s3.model.VersionListing;
import net.sf.saxon.s9api.SaxonApiException;
@Command(name = "s3ls")
public class s3ls extends AWSS3Command {
private boolean bLongListing;
private String mDelim = S3Path.kDEF_DELIM;
private boolean bMetadata;
private boolean bRecurse = false;
private boolean bVersions;
/**
* @param args
* @throws IOException
*/
@Override
public int run(List<XValue> args) throws Exception {
Options opts = getOptions(
"delim:,r=recurse,l=long,lm=long-metadata,m=multipart,meta=metadata,versions");
parseOptions(opts, args);
args = opts.getRemainingArgs();
setSerializeOpts(this.getSerializeOpts(opts));
bLongListing = opts.hasOpt("l") || opts.hasOpt("lm");
bMetadata = opts.hasOpt("metadata") || opts.hasOpt("lm");
bVersions = opts.hasOpt("versions");
try {
getS3Client(opts);
} catch (UnexpectedException e) {
usage(e.getLocalizedMessage());
return 1;
}
mDelim = opts.getOptString("delim", S3Path.kDEF_DELIM);
bRecurse = opts.hasOpt("r");
int ret;
S3Path s3path = null;
switch(args.size()){
case 0:
s3path = getS3Path();
break;
case 1:
s3path = getS3Path(args.get(0));
break;
default:
usage();
return 1;
}
if(!s3path.hasBucket())
ret = listBuckets();
else if(bVersions)
ret = listVersions(s3path);
else if(opts.hasOpt("m"))
ret = listMultipart(s3path);
else
ret = list(s3path);
return ret;
}
private int listBuckets()
throws IOException, XMLStreamException, SaxonApiException, CoreException {
startResult();
traceCall("listBuckets");
List<Bucket> buckets = getAWSClient().listBuckets();
for(Bucket bucket : buckets) {
startElement("bucket");
attribute("name", bucket.getName());
if(bLongListing) {
attribute("create-date",
Util.formatXSDateTime(bucket.getCreationDate()));
attribute("owner", bucket.getOwner().getDisplayName());
}
if(bMetadata)
;
endElement();
}
endResult();
return 0;
}
private int listMultipart(S3Path path)
throws XMLStreamException, IOException, SaxonApiException, CoreException {
if(!path.hasBucket()) {
usage();
return 1;
}
startResult();
writePath(path);
ListMultipartUploadsRequest request = getListMultipartRequest(path,
this.bRecurse ? null : mDelim);
MultipartUploadListing list = getAWSClient().listMultipartUploads(request);
do {
List<MultipartUpload> uploads = list.getMultipartUploads();
for(MultipartUpload obj : uploads) {
startElement("file");
attribute("key", obj.getKey());
if(bLongListing) {
attribute("initiated",
Util.formatXSDateTime(obj.getInitiated()));
attribute("initiator", obj.getInitiator().getId());
attribute("uploadId", obj.getUploadId());
attribute("owner", obj.getOwner().getDisplayName());
attribute("storage-class", obj.getStorageClass());
}
endElement();
}
if(list.isTruncated()) {
request.setUploadIdMarker(list.getUploadIdMarker());
request.setKeyMarker(list.getKeyMarker());
list = getAWSClient().listMultipartUploads(request);
}
else
break;
} while(true);
endResult();
return 0;
}
private int list(S3Path path) throws IOException, XMLStreamException,
SaxonApiException, AmazonClientException, CoreException {
if(!path.hasBucket()) {
usage();
return 1;
}
startResult();
writePath(path);
ListObjectsRequest request = getListRequest(path, bRecurse ? null : mDelim);
traceCall("listObjects");
ObjectListing list = getAWSClient().listObjects(request);
do {
List<String> prefixes = list.getCommonPrefixes();
if(prefixes != null && prefixes.size() > 0) {
for(String p : prefixes) {
startElement("directory");
attribute("name", p);
endElement();
}
}
List<S3ObjectSummary> objs = list.getObjectSummaries();
for(S3ObjectSummary obj : objs) {
startElement("file");
attribute("key", obj.getKey());
attribute("type",
S3Path.isDirectory(obj.getKey(), mDelim) ? "directory" : "file");
if(bLongListing) {
attribute("size", Long.toString(obj.getSize()));
attribute("etag", obj.getETag());
attribute("mod-date",
Util.formatXSDateTime(obj.getLastModified()));
attribute("owner", obj.getOwner().getDisplayName());
attribute("storage-class", obj.getStorageClass());
}
if(bMetadata) {
ObjectMetadata data = getAWSClient()
.getObjectMetadata(path.getBucket(), obj.getKey());
writeMeta(data);
}
endElement();
}
if(list.isTruncated()) {
// String marker = list.getNextMarker();
list = getAWSClient().listNextBatchOfObjects(list);
}
else
break;
} while(true);
endResult();
return 0;
}
private int listVersions(S3Path path) throws IOException, XMLStreamException,
SaxonApiException, AmazonClientException, CoreException {
if(!path.hasBucket()) {
usage();
return 1;
}
startResult();
writePath(path);
ListVersionsRequest request = getListVersionsRequest(path,
bRecurse ? null : mDelim);
traceCall("listVersions");
VersionListing list = getAWSClient().listVersions(request);
do {
List<String> prefixes = list.getCommonPrefixes();
if(prefixes != null && prefixes.size() > 0) {
for(String p : prefixes) {
startElement("directory");
attribute("name", p);
endElement();
}
}
List<S3VersionSummary> objs = list.getVersionSummaries();
for(S3VersionSummary obj : objs) {
startElement("file");
attribute("key", obj.getKey());
attribute("type",
S3Path.isDirectory(obj.getKey(), mDelim) ? "directory" : "file");
attribute("version", obj.getVersionId());
if(bLongListing) {
attribute("size", Long.toString(obj.getSize()));
attribute("etag", obj.getETag());
attribute("mod-date",
Util.formatXSDateTime(obj.getLastModified()));
attribute("owner", obj.getOwner().getDisplayName());
attribute("storage-class", obj.getStorageClass());
}
if(bMetadata) {
ObjectMetadata data = getAWSClient()
.getObjectMetadata(path.getBucket(), obj.getKey());
writeMeta(data);
}
endElement();
}
if(list.isTruncated()) {
// String marker = list.getNextMarker();
list = getAWSClient().listNextBatchOfVersions(list);
}
else
break;
} while(true);
endResult();
return 0;
}
private void writePath(S3Path path)
throws XMLStreamException {
attribute("bucket", path.getBucket());
attribute("prefix", Util.notNull(path.getPrefix()));
attribute("delim", Util.notNull(mDelim));
}
@Override
public void usage() {
super.usage("Usage: s3ls [options] [bucket/prefix]");
}
}