mirror of
https://bitbucket.org/vendoo/vendoo_v1.0.git
synced 2025-12-25 19:57:41 +00:00
121 lines
4.3 KiB
Objective-C
121 lines
4.3 KiB
Objective-C
//
|
|
// PicoSOAPReader.m
|
|
// Pico
|
|
//
|
|
// Created by bulldog on 13-3-13.
|
|
// Copyright (c) 2013 LeanSoft Technology. All rights reserved.
|
|
//
|
|
|
|
#import "PicoSOAPReader.h"
|
|
#import "GDataXMLNode.h"
|
|
#import "PicoBindingSchema.h"
|
|
#import "PicoPropertySchema.h"
|
|
#import "PicoClassSchema.h"
|
|
#import "PicoConstants.h"
|
|
#import "PicoConverter.h"
|
|
#import "PicoXMLElement.h"
|
|
#import "SOAP11Envelope.h"
|
|
#import "SOAP12Envelope.h"
|
|
#import "SOAP11Body.h"
|
|
#import "SOAP12Body.h"
|
|
#import "SOAP11Fault.h"
|
|
#import "SOAP12Fault.h"
|
|
|
|
#import "PicoXMLElement.h"
|
|
|
|
@interface PicoXMLReader (Private)
|
|
|
|
-(void)read:(id)value element:(GDataXMLElement *)element;
|
|
|
|
-(void)readAnyElement:(id)value element:(GDataXMLElement *)element;
|
|
|
|
-(BOOL)readAnyElement:(id)value element:(GDataXMLElement *)element bindClass:(Class) clazz;
|
|
|
|
@end
|
|
|
|
|
|
@implementation PicoSOAPReader
|
|
|
|
static NSString *SOAP11_NS = @"http://schemas.xmlsoap.org/soap/envelope/";
|
|
static NSString *SOAP12_NS = @"http://www.w3.org/2003/05/soap-envelope";
|
|
|
|
static NSString *INNER_CLASS_KEY = @"innerClass";
|
|
|
|
// Convert binary data to object of specific class
|
|
-(id)fromData:(NSData *)data withSOAPClass:(Class)soapClazz innerClass:(Class)innerClazz {
|
|
|
|
BOOL soap11 = (soapClazz == [SOAP11Envelope class]);
|
|
BOOL soap12 = (soapClazz == [SOAP12Envelope class]);
|
|
|
|
if (!soap11 && !soap12) {
|
|
@throw [NSException exceptionWithName:@"ReaderException" reason:[NSString stringWithFormat:@"can't read non-soap class : %@", NSStringFromClass(soapClazz)] userInfo:nil];
|
|
}
|
|
|
|
NSError *error;
|
|
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data error:&error];
|
|
|
|
if (!doc) {
|
|
@throw [NSException exceptionWithName:@"ReaderException" reason:[NSString stringWithFormat:@"fail to parse xml data , Error : %@", error] userInfo:[error userInfo]];
|
|
}
|
|
|
|
GDataXMLElement *rootElement = [doc rootElement];
|
|
PicoBindingSchema *bs = [PicoBindingSchema fromClass:soapClazz];
|
|
PicoClassSchema *cs = bs.classSchema;
|
|
NSString *xmlName = cs.xmlName;
|
|
if ([xmlName length] == 0) {
|
|
xmlName = bs.className;
|
|
}
|
|
NSString *rootName = [rootElement localName];
|
|
if (![xmlName isEqualToString: rootName]) {
|
|
@throw [NSException exceptionWithName:@"ReaderException" reason:[NSString stringWithFormat:@"root name mismatch , xml name : %@, root name : %@", xmlName, rootName] userInfo:nil];
|
|
}
|
|
|
|
// soap version check
|
|
NSString *soapNs = [rootElement URI];
|
|
if (soap11 && [soapNs isEqualToString:SOAP12_NS]) {
|
|
@throw [NSException exceptionWithName:@"ReaderException" reason:@"Expecting SOAP 1.1 response, but got SOAP 1.2 response" userInfo:nil];
|
|
} else if (soap12 && [soapNs isEqualToString:SOAP11_NS]) {
|
|
@throw [NSException exceptionWithName:@"ReaderException" reason:@"Expecting SOAP 1.2 response, but got SOAP 1.1 response" userInfo:nil];
|
|
}
|
|
|
|
NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary];
|
|
threadDictionary[INNER_CLASS_KEY] = innerClazz;
|
|
|
|
id obj = [soapClazz new];
|
|
|
|
[super read: obj element: rootElement];
|
|
|
|
return obj;
|
|
}
|
|
|
|
-(void)readAnyElement:(id)value element:(GDataXMLElement *)element {
|
|
PicoBindingSchema *bs = [PicoBindingSchema fromObject:value];
|
|
PicoPropertySchema *anyPs = bs.anyElementSchema;
|
|
if (!anyPs) return;
|
|
|
|
BOOL soap11 = [value isMemberOfClass:[SOAP11Body class]];
|
|
BOOL soap12 = [value isMemberOfClass:[SOAP12Body class]];
|
|
|
|
if (soap11 || soap12) {
|
|
NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary];
|
|
Class innerClazz = threadDictionary[INNER_CLASS_KEY];
|
|
|
|
BOOL success = [super readAnyElement:value element:element bindClass:innerClazz];
|
|
if (!success) {
|
|
Class faultClass = soap11? [SOAP11Fault class] : [SOAP12Fault class];
|
|
[super readAnyElement:value element:element bindClass:faultClass];
|
|
}
|
|
|
|
} else {
|
|
[super readAnyElement:value element:element];
|
|
}
|
|
}
|
|
|
|
-(id)fromString:(NSString *)string withSOAPClass:(Class)clazz innerClass:(Class)innerClazz {
|
|
NSData *data = [string dataUsingEncoding: CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)self.config.encoding)) allowLossyConversion:NO];
|
|
|
|
return [self fromData:data withSOAPClass:clazz innerClass:innerClazz];
|
|
}
|
|
|
|
@end
|