Tom Andersen
Committed by Ben Copsey

Added 'folder' support and fix bugs with S3

@@ -33,6 +33,9 @@ @@ -33,6 +33,9 @@
33 NSString *currentElement; 33 NSString *currentElement;
34 ASIS3BucketObject *currentObject; 34 ASIS3BucketObject *currentObject;
35 NSMutableArray *objects; 35 NSMutableArray *objects;
  36 +
  37 + NSMutableArray* foundFolders;
  38 + BOOL isTruncated;
36 } 39 }
37 40
38 // Fetch a bucket 41 // Fetch a bucket
@@ -57,6 +60,9 @@ @@ -57,6 +60,9 @@
57 // Returns an array of ASIS3BucketObjects created from the XML response 60 // Returns an array of ASIS3BucketObjects created from the XML response
58 - (NSArray *)bucketObjects; 61 - (NSArray *)bucketObjects;
59 62
  63 +// prefixes are like folders - get them by setting a delimiter string (usually always @"/")
  64 +-(NSArray*)commonPrefixes;
  65 +
60 //Builds a query string out of the list parameters we supplied 66 //Builds a query string out of the list parameters we supplied
61 - (void)createQueryString; 67 - (void)createQueryString;
62 68
@@ -66,4 +72,5 @@ @@ -66,4 +72,5 @@
66 @property (retain) NSString *marker; 72 @property (retain) NSString *marker;
67 @property (assign) int maxResultCount; 73 @property (assign) int maxResultCount;
68 @property (retain) NSString *delimiter; 74 @property (retain) NSString *delimiter;
  75 +@property (readonly) BOOL isTruncated;
69 @end 76 @end
@@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
16 @property (retain, nonatomic) NSString *currentElement; 16 @property (retain, nonatomic) NSString *currentElement;
17 @property (retain, nonatomic) ASIS3BucketObject *currentObject; 17 @property (retain, nonatomic) ASIS3BucketObject *currentObject;
18 @property (retain, nonatomic) NSMutableArray *objects; 18 @property (retain, nonatomic) NSMutableArray *objects;
  19 +@property (retain, nonatomic) NSMutableArray *foundFolders;
  20 +@property (readwrite) BOOL isTruncated;
19 @end 21 @end
20 22
21 @implementation ASIS3BucketRequest 23 @implementation ASIS3BucketRequest
@@ -57,6 +59,7 @@ @@ -57,6 +59,7 @@
57 [currentElement release]; 59 [currentElement release];
58 [currentContent release]; 60 [currentContent release];
59 [objects release]; 61 [objects release];
  62 + [foundFolders release];
60 [prefix release]; 63 [prefix release];
61 [marker release]; 64 [marker release];
62 [delimiter release]; 65 [delimiter release];
@@ -88,8 +91,12 @@ @@ -88,8 +91,12 @@
88 if ([self maxResultCount] > 0) { 91 if ([self maxResultCount] > 0) {
89 [queryParts addObject:[NSString stringWithFormat:@"delimiter=%hi",[self maxResultCount]]]; 92 [queryParts addObject:[NSString stringWithFormat:@"delimiter=%hi",[self maxResultCount]]];
90 } 93 }
91 - if ([queryParts count]) { 94 + if ([queryParts count])
92 - [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@?%@",[[self url] absoluteString],[queryParts componentsJoinedByString:@"&"]]]]; 95 + {
  96 + NSString* template = @"%@?%@";
  97 + if ([self.subResource length] > 0)
  98 + template = @"%@&%@";
  99 + [self setURL:[NSURL URLWithString:[NSString stringWithFormat:template,[[self url] absoluteString],[queryParts componentsJoinedByString:@"&"]]]];
93 } 100 }
94 } 101 }
95 102
@@ -99,21 +106,36 @@ @@ -99,21 +106,36 @@
99 [super main]; 106 [super main];
100 } 107 }
101 108
102 -- (NSArray *)bucketObjects 109 +-(void)makeBucketsAndPrefixes;
103 { 110 {
104 - if ([self objects]) {  
105 - return [self objects];  
106 - }  
107 [self setObjects:[[[NSMutableArray alloc] init] autorelease]]; 111 [self setObjects:[[[NSMutableArray alloc] init] autorelease]];
  112 + [self setFoundFolders:[[[NSMutableArray alloc] init] autorelease]];
108 NSXMLParser *parser = [[[NSXMLParser alloc] initWithData:[self responseData]] autorelease]; 113 NSXMLParser *parser = [[[NSXMLParser alloc] initWithData:[self responseData]] autorelease];
109 [parser setDelegate:self]; 114 [parser setDelegate:self];
110 [parser setShouldProcessNamespaces:NO]; 115 [parser setShouldProcessNamespaces:NO];
111 [parser setShouldReportNamespacePrefixes:NO]; 116 [parser setShouldReportNamespacePrefixes:NO];
112 [parser setShouldResolveExternalEntities:NO]; 117 [parser setShouldResolveExternalEntities:NO];
113 [parser parse]; 118 [parser parse];
  119 +}
  120 +
  121 +- (NSArray *)bucketObjects
  122 +{
  123 + if ([self objects]) {
  124 + return [self objects];
  125 + }
  126 + [self makeBucketsAndPrefixes];
114 return [self objects]; 127 return [self objects];
115 } 128 }
116 129
  130 +-(NSArray*)commonPrefixes;
  131 +{
  132 + if ([self foundFolders]) {
  133 + return [self foundFolders];
  134 + }
  135 + [self makeBucketsAndPrefixes];
  136 + return [self foundFolders];
  137 +}
  138 +
117 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 139 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
118 { 140 {
119 [self setCurrentElement:elementName]; 141 [self setCurrentElement:elementName];
@@ -141,9 +163,12 @@ @@ -141,9 +163,12 @@
141 [[self currentObject] setOwnerID:[self currentContent]]; 163 [[self currentObject] setOwnerID:[self currentContent]];
142 } else if ([elementName isEqualToString:@"DisplayName"]) { 164 } else if ([elementName isEqualToString:@"DisplayName"]) {
143 [[self currentObject] setOwnerName:[self currentContent]]; 165 [[self currentObject] setOwnerName:[self currentContent]];
  166 + } else if ([elementName isEqualToString:@"Prefix"]) {
  167 + [foundFolders addObject:[NSString stringWithString:[self currentContent]]];
  168 + } else if ([elementName isEqualToString:@"IsTruncated"]) {
  169 + self.isTruncated = [[NSString stringWithString:[self currentContent]] boolValue];
144 } 170 }
145 } 171 }
146 -  
147 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 172 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
148 { 173 {
149 [self setCurrentContent:[[self currentContent] stringByAppendingString:string]]; 174 [self setCurrentContent:[[self currentContent] stringByAppendingString:string]];
@@ -169,8 +194,11 @@ @@ -169,8 +194,11 @@
169 @synthesize currentElement; 194 @synthesize currentElement;
170 @synthesize currentObject; 195 @synthesize currentObject;
171 @synthesize objects; 196 @synthesize objects;
  197 +@synthesize foundFolders;
172 @synthesize prefix; 198 @synthesize prefix;
173 @synthesize marker; 199 @synthesize marker;
174 @synthesize maxResultCount; 200 @synthesize maxResultCount;
175 @synthesize delimiter; 201 @synthesize delimiter;
  202 +@synthesize isTruncated;
  203 +
176 @end 204 @end
@@ -31,7 +31,7 @@ @@ -31,7 +31,7 @@
31 + (id)requestWithBucket:(NSString *)bucket key:(NSString *)key subResource:(NSString *)subResource 31 + (id)requestWithBucket:(NSString *)bucket key:(NSString *)key subResource:(NSString *)subResource
32 { 32 {
33 NSString *path = [ASIS3Request stringByURLEncodingForS3Path:key]; 33 NSString *path = [ASIS3Request stringByURLEncodingForS3Path:key];
34 - ASIS3ObjectRequest *request = [[[self alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@.s3.amazonaws.com%@?",bucket,path,subResource]]] autorelease]; 34 + ASIS3ObjectRequest *request = [[[self alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@.s3.amazonaws.com%@?%@",bucket,path,subResource]]] autorelease];
35 [request setBucket:bucket]; 35 [request setBucket:bucket];
36 [request setKey:key]; 36 [request setKey:key];
37 return request; 37 return request;