00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #import "XMLToObjectParser.h"
00013 #import "DropIO.h"
00014
00015 @implementation XMLToObjectParser
00016
00017 - (NSArray *)items
00018 {
00019 return items;
00020 }
00021
00022 @synthesize dropioError;
00023
00024 - (NSString*)camelCaseStringFromString:(NSString*)aStr
00025 {
00026 NSArray* parts = [aStr componentsSeparatedByString:@"_"];
00027
00028 NSMutableString* result = [[[NSMutableString alloc] init] autorelease];
00029
00030 NSEnumerator* partEnum = [parts objectEnumerator];
00031 NSString* partStr = [partEnum nextObject];
00032 [result appendString:partStr];
00033 while ((partStr = [partEnum nextObject]) != nil)
00034 {
00035 [result appendString:[partStr capitalizedString]];
00036 }
00037
00038 return result;
00039 }
00040
00041 - (id)parseXMLAtURL:(NSURL *)url
00042 fromNodeName:(NSString *)aNodeName
00043 toObject:(NSString *)aClassName
00044 parseError:(NSError **)pError
00045 {
00046 NSURLRequest* xmlReq = [[NSURLRequest alloc] initWithURL:url];
00047
00048
00049 NSURLResponse* xmlResp = nil;
00050 NSData* xmlData = [NSURLConnection sendSynchronousRequest:xmlReq
00051 returningResponse:&xmlResp
00052 error:pError];
00053 if ((pError != nil) && ((*pError) != nil))
00054 return self;
00055
00056
00057
00058
00059
00060 return [self parseXMLData:xmlData
00061 fromNodeName:aNodeName
00062 toObject:aClassName
00063 parseError:pError];
00064 }
00065
00066 - (id)parseXMLData:(NSData *)data
00067 fromNodeName:(NSString *)aNodeName
00068 toObject:(NSString *)aClassName
00069 parseError:(NSError **)pError
00070 {
00071 [items release];
00072 items = [[NSMutableArray alloc] init];
00073
00074 nodeName = aNodeName;
00075 className = aClassName;
00076
00077 NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
00078 [parser setDelegate:self];
00079
00080 [parser parse];
00081
00082 NSError* parserError = [parser parserError];
00083 if ((parserError != nil) && (pError != nil))
00084 *pError = parserError;
00085
00086 if ((dropioErrorUserInfo != nil) && (pError != nil))
00087 {
00088 NSString* msgStr = [dropioErrorUserInfo objectForKey:kDropIOErrorMessage];
00089 NSString* actionStr = [dropioErrorUserInfo objectForKey:kDropIOErrorAction];
00090 NSString* resultStr = [dropioErrorUserInfo objectForKey:kDropIOErrorResult];
00091 NSInteger errCode = kDropIOErrorCode_Unknown;
00092 if (msgStr != nil)
00093 {
00094 [dropioErrorUserInfo setObject:msgStr forKey:NSLocalizedFailureReasonErrorKey];
00095 [dropioErrorUserInfo setObject:msgStr forKey:NSLocalizedDescriptionKey];
00096
00097
00098 if ([msgStr isEqualToString:kDropIOErrorMessage_TokenInvalid])
00099 errCode = kDropIOErrorCode_TokenInvalid;
00100 else
00101 if ([msgStr isEqualToString:kDropIOErrorMessage_RateLimitExceeded])
00102 errCode = kDropIOErrorCode_RateLimitExceeded;
00103 else
00104 if ([msgStr isEqualToString:kDropIOErrorMessage_AssetCreationFailed])
00105 errCode = kDropIOErrorCode_AssetCreationFailed;
00106 else
00107 if ([msgStr isEqualToString:kDropIOErrorMessage_AssetDeleted])
00108 errCode = kDropIOErrorCode_AssetDeleted;
00109 else
00110 if ([msgStr isEqualToString:kDropIOErrorMessage_DropDeleted])
00111 errCode = kDropIOErrorCode_DropDeleted;
00112 }
00113 if ([actionStr isEqualToString:@"send_to"] && [resultStr isEqualToString:kDropIOErrorResult_Success])
00114 errCode = kDropIOErrorCode_SendToSuccess;
00115
00116 *pError = [NSError errorWithDomain:kDropIOErrorDomain code:errCode userInfo:dropioErrorUserInfo];
00117 }
00118
00119 [parser release];
00120
00121 return self;
00122 }
00123
00124 - (void)parser:(NSXMLParser *)parser
00125 didStartElement:(NSString *)elementName
00126 namespaceURI:(NSString *)namespaceURI
00127 qualifiedName:(NSString *)qName
00128 attributes:(NSDictionary *)attributeDict
00129 {
00130
00131
00132 NSString* elName = [self camelCaseStringFromString:elementName];
00133
00134 if([elName isEqualToString:nodeName]) {
00135
00136 item = [[NSClassFromString(className) alloc] init];
00137 }
00138 else
00139 if([elName isEqualToString:@"response"]) {
00140
00141 dropioErrorUserInfo = [[NSMutableDictionary alloc] initWithCapacity:5];
00142 }
00143 else {
00144
00145 if (currentNodeName != nil)
00146 {
00147
00148 [currentNodeName release];
00149 }
00150
00151 if (currentNodeContent != nil)
00152 {
00153
00154 [currentNodeContent release];
00155 }
00156
00157 currentNodeName = [elName copy];
00158 currentNodeContent = [[NSMutableString alloc] init];
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 }
00179
00180
00181 }
00182
00183 - (void)parser:(NSXMLParser *)parser
00184 didEndElement:(NSString *)elementName
00185 namespaceURI:(NSString *)namespaceURI
00186 qualifiedName:(NSString *)qName
00187 {
00188
00189
00190 NSString* elName = [self camelCaseStringFromString:elementName];
00191
00192 if([elName isEqualToString:nodeName]) {
00193 [items addObject:item];
00194
00195 [item release];
00196 item = nil;
00197 }
00198 else
00199 if([elName isEqualToString:currentNodeName]) {
00200
00201
00202 NSString* elemKey = elName;
00203 NSRange colon = [elemKey rangeOfString:@":"];
00204 if (colon.location != NSNotFound)
00205 elemKey = [elemKey substringFromIndex:(colon.location+1)];
00206
00207
00208
00209
00210 if (item != nil)
00211 [item setValue:currentNodeContent forKey:elemKey];
00212 else
00213 if (dropioErrorUserInfo != nil)
00214 [dropioErrorUserInfo setValue:currentNodeContent forKey:elemKey];
00215
00216
00217 [currentNodeContent release];
00218 currentNodeContent = nil;
00219
00220
00221 [currentNodeName release];
00222 currentNodeName = nil;
00223 }
00224
00225
00226 }
00227
00228 - (void)parser:(NSXMLParser *)parser
00229 foundCharacters:(NSString *)string
00230 {
00231 if (currentNodeContent != nil)
00232 [currentNodeContent appendString:string];
00233 }
00234
00235 - (void)parser:(NSXMLParser*)parser
00236 foundCDATA:(NSData*)CDATABlock
00237 {
00238 if (currentNodeContent != nil)
00239 {
00240 NSString* cdataStr = [[[NSString alloc] initWithData:CDATABlock encoding:NSUTF8StringEncoding] autorelease];
00241 [currentNodeContent appendString:cdataStr];
00242 }
00243 }
00244
00245 - (void)parser:(NSXMLParser *)parser
00246 parseErrorOccurred:(NSError *)parseError
00247 {
00248 NSLog(@"XML Parse Error %i: Description: %@, Line: %i, Column: %i",
00249 [parseError code],
00250 [[parser parserError] description],
00251 [parser lineNumber],
00252 [parser columnNumber]);
00253 }
00254
00255 - (void)dealloc
00256 {
00257 [currentNodeContent release];
00258 [currentNodeName release];
00259 [dropioErrorUserInfo release];
00260 [dropioError release];
00261 [items release];
00262 [super dealloc];
00263 }
00264
00265 @end