Permalink
Browse files

Added support for filtering and rendering classes with different mapp…

…ings.

Minor updates to Objective-C syntax.
  • Loading branch information...
1 parent 4314e97 commit f8ea4c8b471dd3f8637e67908a7fc9beb3fc221a @ioquatix ioquatix committed Feb 21, 2012
@@ -26,7 +26,7 @@ @implementation SWXMLBooleanMapping
} else
result = falseString;
- return [SWXMLTags tagNamed:self->tag forCDATA:result];
+ return [SWXMLTags tagNamed:self.tag forCDATA:result];
}
@end
View
@@ -13,20 +13,18 @@
@interface SWXMLClassMapping : NSObject {
//Class objectClass;
- NSString *objectClassName;
- NSString *tag;
- NSArray *members;
+ NSString * _objectClassName;
+ NSString * _tag;
+ NSArray * _members;
// List of tags (SWXMLMemberMapping)
}
+@property(nonatomic,retain) NSString * objectClassName;
+@property(nonatomic,retain) NSString * tag;
+@property(nonatomic,retain) NSArray * members;
+
- initWithTag: (NSString*)tag forClass: (NSString*)objectClassName;
- (NSString*) serializeObject: (id)object withMapping: (SWXMLMapping*)mapping;
-- (void) setMembers: (NSArray*)members;
-- (NSArray*) members;
-
-- (NSString*) tag;
-- (NSString*) objectClassName;
-
@end
View
@@ -11,54 +11,35 @@
@implementation SWXMLClassMapping
+@synthesize objectClassName = _objectClassName, tag = _tag, members = _members;
+
- (NSString*) serializeObject: (id)object withMapping: (SWXMLMapping*)mapping {
- id i = [members objectEnumerator];
- SWXMLMemberMapping *memberMapping;
-
- //NSMutableDictionary *attributes = [NSMutableDictionary new];
- NSMutableArray *children = [[NSMutableArray new] autorelease];
+ NSMutableArray * children = [[NSMutableArray new] autorelease];
- while ((memberMapping = [i nextObject]) != nil) {
+ for (SWXMLMemberMapping * memberMapping in self.members) {
[children addObject:[memberMapping serializedObjectMember:object withMapping:mapping]];
}
- return [SWXMLTags tagNamed:self->tag forValue:[children componentsJoinedByString:@"\n"]];
+ return [SWXMLTags tagNamed:self.tag forValue:[children componentsJoinedByString:@"\n"]];
}
-- initWithTag: (NSString*)tagName forClass: (NSString*)className {
+- initWithTag: (NSString*)tag forClass: (NSString*)className {
self = [super init];
if (self) {
- self->tag = [tagName retain];
- self->objectClassName = [className retain];
+ self.tag = tag;
+ self.objectClassName = className;
}
return self;
}
- (void) dealloc {
- [tag release];
- [objectClassName release];
+ self.tag = nil;
+ self.objectClassName = nil;
+ self.members = nil;
[super dealloc];
}
-
-- (void) setMembers: (NSArray*)newMembers {
- [self->members release];
- self->members = [newMembers retain];
-}
-
-- (NSArray*) members {
- return [[self->members retain] autorelease];
-}
-
-- (NSString*) tag {
- return [[tag retain] autorelease];
-}
-
-- (NSString*) objectClassName {
- return [[objectClassName retain] autorelease];
-}
-
@end
@@ -11,7 +11,13 @@
@class SWXMLMemberMapping;
@interface SWXMLCollectionMapping : SWXMLMemberMapping {
-
+ NSString * _filterClassName, * _objectClassName;
}
+// Select only specific objects that match the given class name if specified:
+@property(nonatomic,retain) NSString * filterClassName;
+
+// Remap the class name of a given object with this name if specified:
+@property(nonatomic,retain) NSString * objectClassName;
+
@end
@@ -11,13 +11,43 @@
@implementation SWXMLCollectionMapping
-- serializedObjectMember: (id)object withMapping: (SWXMLMapping*)mapping {
- NSString* collection = [mapping serializeObject:[object valueForKeyPath:[self keyPath]]];
+@synthesize objectClassName = _objectClassName, filterClassName = _filterClassName;
+
+- initWithTag: (NSString*)tag keyPath: (NSString*)keyPath attributes: (NSDictionary*)attributes {
+ self = [super initWithTag:tag keyPath:keyPath attributes:attributes];
+
+ if (self) {
+ self.filterClassName = [attributes valueForKey:@"filter"];
+ self.objectClassName = [attributes valueForKey:@"class"];
+ }
+
+ return self;
+}
- //NSLog (@"SWXMLCollectionMapping: %@", mapping);
- //NSLog (@"SWXMLCollectionMapping: %@", collection);
+- serializedObjectMember: (id)object withMapping: (SWXMLMapping*)mapping {
+ id collection = [object valueForKeyPath:[self keyPath]];
+
+ // This might be considered too simple as it won't catch derived classes, but it is fine for now...
+ if (self.filterClassName) {
+ NSMutableArray * items = [NSMutableArray array];
+
+ for (id item in collection) {
+ if ([[item className] isEqualToString:self.filterClassName])
+ [items addObject:item];
+ }
+
+ collection = items;
+ }
+
+ SWXMLClassMapping * classMapping = nil;
+
+ if (self.objectClassName) {
+ classMapping = [mapping.objectMappings objectForKey:self.objectClassName];
+ }
+
+ NSString * buffer = [mapping serializeObject:collection withClassMapping:classMapping];
- return [SWXMLTags tagNamed:[self tag] forValue:collection];
+ return [SWXMLTags tagNamed:self.tag forValue:buffer];
}
@end
View
@@ -17,24 +17,24 @@ @implementation SWXMLDateMapping
NSDate *date = [object valueForKeyPath:[self keyPath]];
NSString *format;
- format = [self->attributes valueForKey:@"format"];
+ format = [self.attributes valueForKey:@"format"];
if (!format)
format = @"%d-%m-%Y";
- NSString *tzName = [self->attributes valueForKey:@"timezone"];
+ NSString *tzName = [self.attributes valueForKey:@"timezone"];
if (tzName)
timezone = [[[NSTimeZone alloc] initWithName:tzName] autorelease];
- NSString *lcName = [self->attributes valueForKey:@"locale"];
+ NSString *lcName = [self.attributes valueForKey:@"locale"];
if (lcName)
locale = [[[NSLocale alloc] initWithLocaleIdentifier:lcName] autorelease];
/* Even though locale isn't an NSDictionary, it still responds to objectForKey - I suspect this is the intended usage
If not, it will probably be a bug and lead to WWIII or something else */
NSString *formattedDate = [date descriptionWithCalendarFormat:format timeZone:timezone locale:(NSDictionary*)locale];
- return [SWXMLTags tagNamed:self->tag forCDATA:formattedDate];
+ return [SWXMLTags tagNamed:self.tag forCDATA:formattedDate];
}
@end
View
@@ -35,19 +35,26 @@
*/
+@class SWXMLClassMapping;
+
@interface SWXMLMapping : NSObject {
- NSDictionary *objectMappings;
+ NSDictionary * objectMappings;
}
-+ (SWXMLMapping*) mappingFromURL: (NSURL*)loc;
++ (SWXMLMapping*) mappingFromURL:(NSURL *)schemaURL;
+
+@property(nonatomic,retain) NSDictionary * objectMappings;
+
+// Includes <?xml ... ?>
+- (NSString*) serialize:(id)root;
-- (NSString*) serializeObject: (id)object;
-- (NSString*) serializeSet: (NSSet*)set;
-- (NSString*) serializeArray: (NSArray*)arr;
-- (NSString*) serializeDictionary: (NSDictionary*)dict;
+- (NSString*) serializeObject:(id)object;
+- (NSString*) serializeObject:(id)object withClassMapping:(SWXMLClassMapping *)classMapping;
-- (void) setObjectMappings: (NSDictionary*)objectMappings;
-- (NSDictionary*) objectMappings;
+- (NSString*) serializeEnumerator:(NSEnumerator*)enumerator withClassMapping:(SWXMLClassMapping*)classMapping;
+- (NSString*) serializeSet:(NSSet*)set withClassMapping:(SWXMLClassMapping *)classMapping;
+- (NSString*) serializeArray:(NSArray*)array withClassMapping:(SWXMLClassMapping *)classMapping;
+- (NSString*) serializeDictionary:(NSDictionary*)dictionary withClassMapping:(SWXMLClassMapping *)classMapping;
//- (NSString*) tag;
//- (void) setTag: (NSString*)newTag;
View
@@ -7,53 +7,43 @@
//
#import "SWXMLMapping.h"
-//Private
#import "SWXMLMappingParser.h"
-
-@interface SWXMLMapping (Private)
-- (NSString*) serializeEnumerator: (NSEnumerator*)i;
-@end
+#import "SWXMLClassMapping.h"
@implementation SWXMLMapping
-+ (SWXMLMapping*) mappingFromURL: (NSURL*)loc {
- SWXMLMappingParser *parser = [[[SWXMLMappingParser alloc] initWithURL:loc] autorelease];
- SWXMLMapping *mapping = [[[SWXMLMapping alloc] init] autorelease];
- NSDictionary *objectMappings;
-
- objectMappings = [parser parse];
+
++ (SWXMLMapping*) mappingFromURL:(NSURL*)schemaURL {
+ SWXMLMappingParser * parser = [[[SWXMLMappingParser alloc] initWithURL:schemaURL] autorelease];
+ SWXMLMapping * mapping = [[[SWXMLMapping alloc] init] autorelease];
- [mapping setObjectMappings:objectMappings];
+ // ??? root container tag?
//[mapping setTag:[[parser mappingAttributes] objectForKey:@"tag"]];
+ mapping.objectMappings = [parser parse];
+
return mapping;
}
-- (void) setObjectMappings: (NSDictionary*)newObjectMappings {
- [self->objectMappings autorelease];
- self->objectMappings = [newObjectMappings retain];
-}
-
-- (NSDictionary*) objectMappings {
- return [[self->objectMappings retain] autorelease];
-}
+@synthesize objectMappings;
-- (NSString*) serializeEnumerator: (NSEnumerator*)i {
- id obj;
- NSMutableString *str = [[NSMutableString new] autorelease];
+- (NSString*) serializeEnumerator:(NSEnumerator*)enumerator withClassMapping:(SWXMLClassMapping *)classMapping {
+ NSMutableArray * lines = [NSMutableArray array];
- while ((obj = [i nextObject]) != nil) {
- [str appendFormat:@"%@\n", [self serializeObject:obj]];
+ for (id object in enumerator) {
+ [lines addObject:[self serializeObject:object withClassMapping:classMapping]];
}
- return str;
+ return [lines componentsJoinedByString:@"\n"];
}
+
/*
- (NSString*) serialize: (id)root withTag: (NSString*)tag {
NSString *serializedString = [self serializeObject:root];
return [SWXMLTags tagNamed:tag forValue:serializedString];
}
*/
+
- (NSString*) serialize: (id)root {
NSString *serializedXML = [self serializeObject:root];
NSString *XMLTag = [SWXMLTags tagForXML];
@@ -62,48 +52,53 @@ - (NSString*) serialize: (id)root {
//[self serialize:root withTag:[self tag]];
}
+- (NSString*) serializeObject:(id)object {
+ return [self serializeObject:object withClassMapping:nil];
+}
+
/* Serializes an arbitraty object to XML */
-- (NSString*) serializeObject: (id)object {
+- (NSString*) serializeObject:(id)object withClassMapping:(SWXMLClassMapping *)classMapping {
Class objectClass = [object class];
+
/* Determine the type of object */
if ([object isKindOfClass:[NSSet class]])
- return [self serializeSet:object];
+ return [self serializeSet:object withClassMapping:classMapping];
else if ([object isKindOfClass:[NSArray class]])
- return [self serializeArray:object];
+ return [self serializeArray:object withClassMapping:classMapping];
else if ([object isKindOfClass:[NSDictionary class]])
- return [self serializeDictionary:object];
+ return [self serializeDictionary:object withClassMapping:classMapping];
else {
- /* We need to find the SWXMLClassMapping to serialize this object
- The data structure stores Class => ObjectMapping*, so we need to
- traverse up the class heirarchy to get a more generic mapping object
- if a specific one does not exist */
- SWXMLClassMapping *objectMapping = nil;
- while (objectClass && objectClass != [NSObject class]) {
- objectMapping = [self->objectMappings objectForKey:[objectClass className]];
- if (objectMapping != nil)
- break;
- else
- objectClass = [objectClass superclass];
+ // We need to find the SWXMLClassMapping to serialize this object. The data structure stores Class => ObjectMapping*, so we need to traverse up the class heirarchy to get a more generic mapping object if a specific one does not exist.
+
+ // A class mapping may have been provided already, otherwise search for an appropriate one:
+ if (classMapping == nil) {
+ while (objectClass && objectClass != [NSObject class]) {
+ classMapping = [self->objectMappings objectForKey:[objectClass className]];
+ if (classMapping != nil)
+ break;
+ else
+ objectClass = [objectClass superclass];
+ }
}
- if (objectMapping == nil) {
+ if (classMapping == nil) {
NSLog (@"No object mapping for %@", [object className]);
return nil;
}
- return [objectMapping serializeObject: object withMapping:self];
+ return [classMapping serializeObject:object withMapping:self];
}
}
-- (NSString*) serializeSet: (NSSet*)set {
- return [self serializeEnumerator:[set objectEnumerator]];
+- (NSString *)serializeSet:(NSSet *)set withClassMapping:(SWXMLClassMapping *)classMapping {
+ return [self serializeEnumerator:set.objectEnumerator withClassMapping:classMapping];
}
-- (NSString*) serializeArray: (NSArray*)arr {
- return [self serializeObject:[arr objectEnumerator]];
+- (NSString *)serializeArray:(NSArray *)array withClassMapping:(SWXMLClassMapping *)classMapping {
+ return [self serializeEnumerator:array.objectEnumerator withClassMapping:classMapping];
}
-- (NSString*) serializeDictionary: (NSDictionary*)dict {
+- (NSString*) serializeDictionary: (NSDictionary*)dict withClassMapping:(SWXMLClassMapping *)classMapping {
return @"";
}
/*
Oops, something went wrong.

0 comments on commit f8ea4c8

Please sign in to comment.