// // PicoSOAPWriter.m // Pico // // Created by bulldog on 13-3-14. // Copyright (c) 2013 LeanSoft Technology. All rights reserved. // #import "PicoSOAPWriter.h" #import "XMLWriter.h" #import "PicoBindingSchema.h" #import "PicoClassSchema.h" #import "PicoConfig.h" #import "SOAP11Envelope.h" #import "SOAP12Envelope.h" #import "SOAP11Body.h" #import "SOAP12Body.h" @interface PicoXMLWriter (Private) -(void)writeObject:(XMLWriter *)xmlWriter source:(id)source; @end @implementation PicoSOAPWriter static NSString *SOAP_PREFIX = @"soapenv"; static NSString *XSI_PREFIX = @"xsi"; static NSString *XSI_NAMESPACE = @"http://www.w3.org/2001/XMLSchema-instance"; static NSString *XSD_PREFIX = @"xsd"; static NSString *XSD_NAMESPACE = @"http://www.w3.org/2001/XMLSchema"; -(NSString *)toString:(id)obj { if (obj == nil) { @throw [NSException exceptionWithName:@"WriterException" reason:@"Can't write nil object." userInfo:nil]; } if (![obj isMemberOfClass:[SOAP11Envelope class]] && ![obj isMemberOfClass:[SOAP12Envelope class]]) { @throw [NSException exceptionWithName:@"WriterException" reason:[NSString stringWithFormat:@"can't write non-soap object of type : %@", NSStringFromClass([obj class])] userInfo:nil]; } XMLWriter *xmlWriter = [[XMLWriter alloc] init]; _autoPrefixCount = 0; [xmlWriter writeStartDocumentWithEncodingAndVersion:self.config.encoding version:@"1.0"]; PicoBindingSchema *bindingSchema = [PicoBindingSchema fromObject:obj]; PicoClassSchema *classSchema = [bindingSchema classSchema]; NSString *xmlName = classSchema.xmlName; NSString *namespace = classSchema.nsURI; // set soap prefix [xmlWriter setPrefix:SOAP_PREFIX namespaceURI:namespace]; [xmlWriter setPrefix:XSI_PREFIX namespaceURI:XSI_NAMESPACE]; [xmlWriter setPrefix:XSD_PREFIX namespaceURI:XSD_NAMESPACE]; NSString *innerNamespace = [self findInnerClassNamespace:obj]; // set default namespace without prefix if (innerNamespace.length > 0 && ![xmlWriter getPrefix:innerNamespace]) { [xmlWriter setDefaultNamespace:innerNamespace]; } [xmlWriter writeStartElementWithNamespace:namespace localName:xmlName]; [super writeObject:xmlWriter source:obj]; [xmlWriter writeEndElementWithNamespace:namespace localName:xmlName]; [xmlWriter writeEndDocument]; NSString *xmlString = [xmlWriter toString]; xmlString = [NSMutableString stringWithString:xmlString]; return xmlString; } -(NSString *) findInnerClassNamespace:(id)obj { id innerObj = nil; if ([obj isMemberOfClass:[SOAP11Envelope class]]) { SOAP11Envelope *soap11Envelope = obj; SOAP11Body *soap11Body = soap11Envelope.body; if (soap11Body && soap11Body.any.count > 0) { innerObj = (soap11Body.any)[0]; } } else { //soap 12 SOAP12Envelope *soap12Envelope = obj; SOAP12Body *soap12Body = soap12Envelope.body; if (soap12Body && soap12Body.any.count > 0) { innerObj = (soap12Body.any)[0]; } } if (innerObj) { PicoBindingSchema *innerBindingSchema = [PicoBindingSchema fromObject:innerObj]; PicoClassSchema *innerClassSchema = [innerBindingSchema classSchema]; NSString *innerNamespace = innerClassSchema.nsURI; return innerNamespace; } return nil; } -(NSData *)toData:(id)obj { NSString *xmlString = [self toString:obj]; NSData *data = [xmlString dataUsingEncoding: CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)self.config.encoding)) allowLossyConversion:NO]; return data; } @end