]> err.no Git - sope/blobdiff - sope-core/EOControl/EOKeyValueArchiver.m
improved logs for decoding errors
[sope] / sope-core / EOControl / EOKeyValueArchiver.m
index ec932804692025b5e5658c3ab949b79691aa8511..f2eabf527bb1b258ec62552b902df1ea29ff4bf2 100644 (file)
@@ -132,6 +132,54 @@ static BOOL isPListObject(id _obj) {
   [super dealloc];
 }
 
+/* class handling */
+
+- (Class)classForName:(NSString *)_name {
+  /*
+    This method maps class names. It is intended for archives which are
+    written by the Java bridge and therefore use fully qualified Java
+    package names.
+    
+    The mapping is hardcoded for now, this could be extended to use a
+    dictionary if considered necessary.
+  */
+  NSString *lastComponent = nil;
+  Class   clazz;
+  NSRange r;
+
+  if (_name == nil)
+    return nil;
+  
+  if ((clazz = NSClassFromString(_name)) != Nil)
+    return clazz;
+  
+  /* check for Java like . names (eg com.webobjects.directtoweb.Assignment) */
+  
+  r = [_name rangeOfString:@"." options:NSBackwardsSearch];
+  if (r.length > 0) {
+    lastComponent = [_name substringFromIndex:(r.location + r.length)];
+    
+    /* first check whether the last name directly matches a class */
+    if ((clazz = NSClassFromString(lastComponent)) != Nil)
+      return clazz;
+    
+    /* then check some hardcoded prefixes */
+    
+    if ([_name hasPrefix:@"com.webobjects.directtoweb"]) {
+      NSString *s;
+      
+      s = [@"D2W" stringByAppendingString:lastComponent];
+      if ((clazz = NSClassFromString(lastComponent)) != Nil)
+       return clazz;
+    }
+    
+    NSLog(@"WARNING(%s): could not map Java class in unarchiver: '%@'",
+         __PRETTY_FUNCTION__, _name);
+  }
+  
+  return Nil;
+}
+
 /* decoding */
 
 - (id)decodeObjectForKey:(NSString *)_key {
@@ -147,11 +195,27 @@ static BOOL isPListObject(id _obj) {
     obj = [[self->plist copy] autorelease];
   }
   else if ((className = [self->plist objectForKey:@"class"]) != nil) {
-    obj = [NSClassFromString(className) alloc];
-    obj = [obj initWithKeyValueUnarchiver:self];
+    Class clazz;
+
+    if ((clazz = [self classForName:className]) != nil) {
+      obj = [clazz alloc];
+      obj = [obj initWithKeyValueUnarchiver:self];
     
-    [self->unarchivedObjects addObject:obj];
-    [obj release];
+      if (obj != nil)
+       [self->unarchivedObjects addObject:obj];
+      else {
+       NSLog(@"WARNING(%s): could not unarchive object %@",
+             __PRETTY_FUNCTION__, self->plist);
+      }
+      if (self->unarchivedObjects != nil)
+       [obj release];
+      else
+       [obj autorelease];
+    }
+    else {
+      NSLog(@"WARNING(%s): did not find class specified in archive '%@': %@",
+           __PRETTY_FUNCTION__, className, self->plist);
+    }
   }
   else {
     obj = nil;