You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by ga...@apache.org on 2014/04/17 22:00:33 UTC

svn commit: r1588358 - in /chemistry/objectivecmis/branches/browser-binding: ObjectiveCMIS.xcodeproj/project.pbxproj ObjectiveCMIS/Bindings/Browser/CMISBrowserUtil.m ObjectiveCMIS/CMISNSDictionary+CMISUtil.h ObjectiveCMIS/CMISNSDictionary+CMISUtil.m

Author: gavincornwell
Date: Thu Apr 17 20:00:33 2014
New Revision: 1588358

URL: http://svn.apache.org/r1588358
Log:
CMIS-787: Browser Binding NSNull issue when serializing json data (applied patch in JIRA issue).

Added:
    chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/CMISNSDictionary+CMISUtil.h   (with props)
    chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/CMISNSDictionary+CMISUtil.m   (with props)
Modified:
    chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS.xcodeproj/project.pbxproj
    chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/Bindings/Browser/CMISBrowserUtil.m

Modified: chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS.xcodeproj/project.pbxproj
URL: http://svn.apache.org/viewvc/chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS.xcodeproj/project.pbxproj?rev=1588358&r1=1588357&r2=1588358&view=diff
==============================================================================
--- chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS.xcodeproj/project.pbxproj (original)
+++ chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS.xcodeproj/project.pbxproj Thu Apr 17 20:00:33 2014
@@ -215,6 +215,10 @@
 		BD5C9715162C11E3002DDC6E /* CMISHttpResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = BD5C9712162C11E3002DDC6E /* CMISHttpResponse.m */; };
 		BD70F11B17F4649B00AE2B0C /* CMISDocumentTypeDefinition.h in Headers */ = {isa = PBXBuildFile; fileRef = BD70F11917F4649B00AE2B0C /* CMISDocumentTypeDefinition.h */; };
 		BD70F11C17F4649B00AE2B0C /* CMISDocumentTypeDefinition.m in Sources */ = {isa = PBXBuildFile; fileRef = BD70F11A17F4649B00AE2B0C /* CMISDocumentTypeDefinition.m */; };
+		C94AB15B19002CCD00ACC3D4 /* CMISNSDictionary+CMISUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = C94AB15919002CCD00ACC3D4 /* CMISNSDictionary+CMISUtil.h */; };
+		C94AB15C19002CCD00ACC3D4 /* CMISNSDictionary+CMISUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = C94AB15A19002CCD00ACC3D4 /* CMISNSDictionary+CMISUtil.m */; };
+		C94AB15F19003A5A00ACC3D4 /* CMISBrowserVersioningService.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B9C8D518DE3379001D5C1B /* CMISBrowserVersioningService.m */; };
+		C94AB16019003A8200ACC3D4 /* CMISNSDictionary+CMISUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = C94AB15A19002CCD00ACC3D4 /* CMISNSDictionary+CMISUtil.m */; };
 		C97B945818FE828300EDC1A6 /* CMISObjectByPathUriBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = C97B945618FE828300EDC1A6 /* CMISObjectByPathUriBuilder.h */; };
 		C97B945918FE828300EDC1A6 /* CMISObjectByPathUriBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = C97B945718FE828300EDC1A6 /* CMISObjectByPathUriBuilder.m */; };
 		C97B947818FECA6400EDC1A6 /* CMISFolderTypeDefinition.h in Headers */ = {isa = PBXBuildFile; fileRef = C97B947618FECA6400EDC1A6 /* CMISFolderTypeDefinition.h */; };
@@ -446,6 +450,8 @@
 		BD5C9712162C11E3002DDC6E /* CMISHttpResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = CMISHttpResponse.m; path = Utils/CMISHttpResponse.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
 		BD70F11917F4649B00AE2B0C /* CMISDocumentTypeDefinition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CMISDocumentTypeDefinition.h; path = Bindings/CMISDocumentTypeDefinition.h; sourceTree = "<group>"; };
 		BD70F11A17F4649B00AE2B0C /* CMISDocumentTypeDefinition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CMISDocumentTypeDefinition.m; path = Bindings/CMISDocumentTypeDefinition.m; sourceTree = "<group>"; };
+		C94AB15919002CCD00ACC3D4 /* CMISNSDictionary+CMISUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CMISNSDictionary+CMISUtil.h"; sourceTree = "<group>"; };
+		C94AB15A19002CCD00ACC3D4 /* CMISNSDictionary+CMISUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CMISNSDictionary+CMISUtil.m"; sourceTree = "<group>"; };
 		C97B945618FE828300EDC1A6 /* CMISObjectByPathUriBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMISObjectByPathUriBuilder.h; sourceTree = "<group>"; };
 		C97B945718FE828300EDC1A6 /* CMISObjectByPathUriBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMISObjectByPathUriBuilder.m; sourceTree = "<group>"; };
 		C97B947618FECA6400EDC1A6 /* CMISFolderTypeDefinition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CMISFolderTypeDefinition.h; path = Bindings/CMISFolderTypeDefinition.h; sourceTree = "<group>"; };
@@ -519,6 +525,8 @@
 				58B9C8D518DE3379001D5C1B /* CMISBrowserVersioningService.m */,
 				58B9C8FC18E58028001D5C1B /* CMISBrowserUtil.h */,
 				58B9C8FD18E58028001D5C1B /* CMISBrowserUtil.m */,
+				C94AB15919002CCD00ACC3D4 /* CMISNSDictionary+CMISUtil.h */,
+				C94AB15A19002CCD00ACC3D4 /* CMISNSDictionary+CMISUtil.m */,
 			);
 			name = Browser;
 			sourceTree = "<group>";
@@ -868,6 +876,7 @@
 				8280731E1515405C00EF635C /* CMISServiceDocumentParser.h in Headers */,
 				828073201515405C00EF635C /* CMISAtomPubBinding.h in Headers */,
 				58B9C8FE18E58028001D5C1B /* CMISBrowserUtil.h in Headers */,
+				C94AB15B19002CCD00ACC3D4 /* CMISNSDictionary+CMISUtil.h in Headers */,
 				828073221515405C00EF635C /* CMISAtomPubObjectService.h in Headers */,
 				58B9C8E418DE344B001D5C1B /* CMISBrowserDiscoveryService.h in Headers */,
 				828073241515405C00EF635C /* CMISAtomPubRepositoryService.h in Headers */,
@@ -1166,6 +1175,7 @@
 				BD30D33E162D7DD7001FFF80 /* CMISRequest.m in Sources */,
 				4E39DF5D163A72B400F21DE6 /* CMISDateUtil.m in Sources */,
 				4E39DF61163A767B00F21DE6 /* CMISAtomParserUtil.m in Sources */,
+				C94AB15C19002CCD00ACC3D4 /* CMISNSDictionary+CMISUtil.m in Sources */,
 				4E10AC0016B916B500E2287E /* CMISDefaultNetworkProvider.m in Sources */,
 				4E3C32A916C4EF190099B21E /* CMISAtomPubVersioningService.m in Sources */,
 				82895A1B16D8A8C5007BC80A /* CMISLog.m in Sources */,
@@ -1186,8 +1196,10 @@
 				4EA61BE61564F73900C759E4 /* CMISQueryResult.m in Sources */,
 				4EA61BEB1564F75000C759E4 /* CMISErrors.m in Sources */,
 				FE417D6815761A34009056D2 /* CMISBaseTest.m in Sources */,
+				C94AB16019003A8200ACC3D4 /* CMISNSDictionary+CMISUtil.m in Sources */,
 				BD5C970016281A54002DDC6E /* CMISHttpRequest.m in Sources */,
 				BD5C970B1628293F002DDC6E /* CMISHttpUploadRequest.m in Sources */,
+				C94AB15F19003A5A00ACC3D4 /* CMISBrowserVersioningService.m in Sources */,
 				BD5C971016282977002DDC6E /* CMISHttpDownloadRequest.m in Sources */,
 				BD5C9715162C11E3002DDC6E /* CMISHttpResponse.m in Sources */,
 			);

Modified: chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/Bindings/Browser/CMISBrowserUtil.m
URL: http://svn.apache.org/viewvc/chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/Bindings/Browser/CMISBrowserUtil.m?rev=1588358&r1=1588357&r2=1588358&view=diff
==============================================================================
--- chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/Bindings/Browser/CMISBrowserUtil.m (original)
+++ chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/Bindings/Browser/CMISBrowserUtil.m Thu Apr 17 20:00:33 2014
@@ -29,6 +29,7 @@
 #import "CMISItemTypeDefinition.h"
 #import "CMISSecondaryTypeDefinition.h"
 #import "CMISErrors.h"
+#import "CMISNSDictionary+CMISUtil.h"
 
 @implementation CMISBrowserUtil
 
@@ -48,28 +49,28 @@
         NSArray *repos = [jsonDictionary allValues];
         for (NSDictionary *repo in repos) {
             CMISRepositoryInfo *repoInfo = [CMISRepositoryInfo new];
-            repoInfo.identifier = repo[kCMISBrowserJSONRepositoryId];
-            repoInfo.name = repo[kCMISBrowserJSONRepositoryName];
-            repoInfo.desc = repo[kCMISBrowserJSONRepositoryDescription];
-            repoInfo.vendorName = repo[kCMISBrowserJSONVendorName];
-            repoInfo.productName = repo[kCMISBrowserJSONProductName];
-            repoInfo.productVersion = repo[kCMISBrowserJSONProductVersion];
-            repoInfo.rootFolderId = repo[kCMISBrowserJSONRootFolderId];
-            repoInfo.repositoryUrl = repo[kCMISBrowserJSONRepositoryUrl];
-            repoInfo.rootFolderUrl = repo[kCMISBrowserJSONRootFolderUrl];
+            repoInfo.identifier = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONRepositoryId];
+            repoInfo.name = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONRepositoryName];
+            repoInfo.desc = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONRepositoryDescription];
+            repoInfo.vendorName = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONVendorName];
+            repoInfo.productName = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONProductName];
+            repoInfo.productVersion = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONProductVersion];
+            repoInfo.rootFolderId = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONRootFolderId];
+            repoInfo.repositoryUrl = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONRepositoryUrl];
+            repoInfo.rootFolderUrl = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONRootFolderUrl];
             
-            repoInfo.repositoryCapabilities = repo[kCMISBrowserJSONCapabilities]; //TODO should be own type instead of dictionary
+            repoInfo.repositoryCapabilities = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONCapabilities]; //TODO should be own type instead of dictionary
             //TOOD aclCapabilities
-            repoInfo.latestChangeLogToken = repo[kCMISBrowserJSONLatestChangeLogToken];
+            repoInfo.latestChangeLogToken = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONLatestChangeLogToken];
             
-            repoInfo.cmisVersionSupported = repo[kCMISBrowserJSONCMISVersionSupported];
-            repoInfo.thinClientUri = repo[kCMISBrowserJSONThinClientUri];
+            repoInfo.cmisVersionSupported = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONCMISVersionSupported];
+            repoInfo.thinClientUri = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONThinClientUri];
 
-            //TODO repoInfo.changesIncomplete = repo[kCMISBrowserJSONChangesIncomplete];
+            //TODO repoInfo.changesIncomplete = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONChangesIncomplete);
             //TODO changesOnType
 
-            repoInfo.principalIdAnonymous = repo[kCMISBrowserJSONPrincipalIdAnonymous];
-            repoInfo.principalIdAnyone = repo[kCMISBrowserJSONPrincipalIdAnyone];
+            repoInfo.principalIdAnonymous = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONPrincipalIdAnonymous];
+            repoInfo.principalIdAnyone = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONPrincipalIdAnyone];
             
             //handle extensions
             repoInfo.extensions = [CMISBrowserUtil convertExtensions:repo cmisKeys:[CMISBrowserConstants repositoryInfoKeys]];
@@ -98,13 +99,15 @@
     CMISTypeDefinition *typeDef = nil;
     if (!serialisationError) {
         //TODO check for valid baseTypeId (cmis:document, cmis:folder, cmis:relationship, cmis:policy, [cmis:item, cmis:secondary])
-        CMISBaseType baseType = [CMISEnums enumForBaseId:jsonDictionary[kCMISBrowserJSONBaseId]];
+        CMISBaseType baseType = [CMISEnums enumForBaseId:[jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONBaseId]];
         switch (baseType) {
-            case CMISBaseTypeDocument:
+            case CMISBaseTypeDocument: {
                 typeDef = [CMISDocumentTypeDefinition new];
-                ((CMISDocumentTypeDefinition*)typeDef).contentStreamAllowed = [CMISEnums enumForContentStreamAllowed:jsonDictionary[kCMISBrowserJSONContentStreamAllowed]];
-                ((CMISDocumentTypeDefinition*)typeDef).versionable = [jsonDictionary[kCMISBrowserJSONVersionable] boolValue];
+                ((CMISDocumentTypeDefinition*)typeDef).contentStreamAllowed = [CMISEnums enumForContentStreamAllowed:
+                                                                               [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONContentStreamAllowed]];
+                ((CMISDocumentTypeDefinition*)typeDef).versionable = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONVersionable];
                 break;
+            }
             case CMISBaseTypeFolder:
                 typeDef = [CMISFolderTypeDefinition new];
                 break;
@@ -112,7 +115,7 @@
             case CMISBaseTypeRelationship: {
                 typeDef = [CMISRelationshipTypeDefinition new];
                 
-                id allowedSourceTypes = jsonDictionary[kCMISBrowserJSONAllowedSourceTypes];
+                id allowedSourceTypes = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONAllowedSourceTypes];
                 if([allowedSourceTypes isKindOfClass:NSArray.class]){
                     NSMutableArray *types = [[NSMutableArray alloc] init];
                     for (id type in allowedSourceTypes) {
@@ -123,7 +126,7 @@
                     ((CMISRelationshipTypeDefinition*)typeDef).allowedSourceTypes = types;
                 }
                 
-                id allowedTargetTypes = jsonDictionary[kCMISBrowserJSONAllowedTargetTypes];
+                id allowedTargetTypes = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONAllowedTargetTypes];
                 if([allowedTargetTypes isKindOfClass:NSArray.class]){
                     NSMutableArray *types = [[NSMutableArray alloc] init];
                     for (id type in allowedTargetTypes) {
@@ -142,29 +145,29 @@
                 typeDef = [CMISSecondaryTypeDefinition new];
                 break;
             default:
-                if (outError != NULL) *outError = [CMISErrors createCMISErrorWithCode:kCMISErrorCodeInvalidArgument detailedDescription:[NSString stringWithFormat:@"Type '%@' does not match a base type!", jsonDictionary[kCMISBrowserJSONBaseId]]];
+                if (outError != NULL) *outError = [CMISErrors createCMISErrorWithCode:kCMISErrorCodeInvalidArgument detailedDescription:[NSString stringWithFormat:@"Type '%@' does not match a base type!", [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONBaseId]]];
                 return nil;
         }
 
         typeDef.baseTypeId = baseType;
-        typeDef.description = jsonDictionary[kCMISBrowserJSONDescription];
-        typeDef.displayName = jsonDictionary[kCMISBrowserJSONDisplayName];
-        typeDef.id = jsonDictionary[kCMISBrowserJSONId];
-        typeDef.controllablePolicy = [jsonDictionary[kCMISBrowserJSONControllablePolicy] boolValue];
-        typeDef.controllableAcl = [jsonDictionary[kCMISBrowserJSONControllableAcl] boolValue];
-        typeDef.creatable = [jsonDictionary[kCMISBrowserJSONCreateable] boolValue];
-        typeDef.fileable = [jsonDictionary[kCMISBrowserJSONFileable] boolValue];
-        typeDef.fullTextIndexed = [jsonDictionary[kCMISBrowserJSONFullTextIndexed] boolValue];
-        typeDef.includedInSupertypeQuery = [jsonDictionary[kCMISBrowserJSONIncludedInSuperTypeQuery] boolValue];
-        typeDef.queryable = [jsonDictionary[kCMISBrowserJSONQueryable] boolValue];
-        typeDef.localName = jsonDictionary[kCMISBrowserJSONLocalName];
-        typeDef.localNameSpace = jsonDictionary[kCMISBrowserJSONLocalNamespace];
-        typeDef.parentTypeId = jsonDictionary[kCMISBrowserJSONParentId];
-        typeDef.queryName = jsonDictionary[kCMISBrowserJSONQueryName];
+        typeDef.description = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONDescription];
+        typeDef.displayName = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONDisplayName];
+        typeDef.id = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONId];
+        typeDef.controllablePolicy = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONControllablePolicy];
+        typeDef.controllableAcl = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONControllableAcl];
+        typeDef.creatable = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONCreateable];
+        typeDef.fileable = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONFileable];
+        typeDef.fullTextIndexed = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONFullTextIndexed];
+        typeDef.includedInSupertypeQuery = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONIncludedInSuperTypeQuery];
+        typeDef.queryable = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONQueryable];
+        typeDef.localName = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONLocalName];
+        typeDef.localNameSpace = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONLocalNamespace];
+        typeDef.parentTypeId = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONParentId];
+        typeDef.queryName = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONQueryName];
         
         //TODO type mutability
         
-        NSDictionary *propertyDefinitions = jsonDictionary[kCMISBrowserJSONPropertyDefinitions];
+        NSDictionary *propertyDefinitions = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONPropertyDefinitions];
         for (NSDictionary *propertyDefDictionary in [propertyDefinitions allValues]) {
             [typeDef addPropertyDefinition:[CMISBrowserUtil convertPropertyDefinition:propertyDefDictionary]];
         }
@@ -207,25 +210,28 @@
         objectList = [CMISObjectList new];
         
         // parse the objects
+        BOOL isArray = [jsonDictionary isKindOfClass:NSArray.class];
         NSArray *objectsArray;
-        if([jsonDictionary isKindOfClass:NSArray.class]){ // is NSArray
+        if(isArray){
             objectsArray = jsonDictionary;
             
             objectList.hasMoreItems = NO;
             objectList.numItems = (int)objectsArray.count;
         } else { // is NSDictionary
-            objectsArray = jsonDictionary[kCMISBrowserJSONObjects];
+            objectsArray = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONObjects];
             
             // retrieve the paging data
-            objectList.hasMoreItems = [jsonDictionary[kCMISBrowserJSONHasMoreItems] boolValue];
-            objectList.numItems = [jsonDictionary[kCMISBrowserJSONNumberItems] intValue];
+            objectList.hasMoreItems = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONHasMoreItems];
+            objectList.numItems = [jsonDictionary cmis_intForKey:kCMISBrowserJSONNumberItems];
         }
         if (objectsArray) {
             NSMutableArray *objects = [NSMutableArray arrayWithCapacity:objectsArray.count];
             for (NSDictionary *dictionary in objectsArray) {
-                NSDictionary *objectDictionary = dictionary[kCMISBrowserJSONObject];
-                if(!objectDictionary) {
+                NSDictionary *objectDictionary;
+                if(isArray){
                     objectDictionary = dictionary;
+                } else {
+                    objectDictionary = [dictionary cmis_objectForKeyNotNull:kCMISBrowserJSONObject];
                 }
                 CMISObjectData *objectData = [CMISBrowserUtil convertObject:objectDictionary];
                 if(objectData){
@@ -268,11 +274,11 @@
     }
     
     CMISObjectData *objectData = [CMISObjectData new];
-    NSDictionary *propertiesJson = dictionary[kCMISBrowserJSONSuccinctProperties];
-    objectData.identifier = propertiesJson[kCMISPropertyObjectId];
+    NSDictionary *propertiesJson = [dictionary cmis_objectForKeyNotNull:kCMISBrowserJSONSuccinctProperties];
+    objectData.identifier = [propertiesJson cmis_objectForKeyNotNull:kCMISPropertyObjectId];
     
     // determine the object type
-    NSString *baseType = propertiesJson[kCMISPropertyBaseTypeId];
+    NSString *baseType = [propertiesJson cmis_objectForKeyNotNull:kCMISPropertyBaseTypeId];
     if ([baseType isEqualToString:kCMISPropertyObjectTypeIdValueDocument]) {
         objectData.baseType = CMISBaseTypeDocument;
     } else if ([baseType isEqualToString:kCMISPropertyObjectTypeIdValueFolder]) {
@@ -280,15 +286,15 @@
     }
     
     // set the properties
-    NSDictionary *propertiesExtension = dictionary[kCMISBrowserJSONPropertiesExtension];
+    NSDictionary *propertiesExtension = [dictionary cmis_objectForKeyNotNull:kCMISBrowserJSONPropertiesExtension];
     objectData.properties = [CMISBrowserUtil convertSuccinctProperties:propertiesJson propertiesExtension:propertiesExtension];
     
     // relationships
-    NSArray *relationshipsJson = dictionary[kCMISBrowserJSONRelationships];
+    NSArray *relationshipsJson = [dictionary cmis_objectForKeyNotNull:kCMISBrowserJSONRelationships];
     objectData.relationships = [CMISBrowserUtil convertObjects:relationshipsJson];
     
     //renditions
-    NSArray *renditionsJson = dictionary[kCMISBrowserJSONRenditions];
+    NSArray *renditionsJson = [dictionary cmis_objectForKeyNotNull:kCMISBrowserJSONRenditions];
     objectData.renditions = [self renditionsFromArray:renditionsJson];
     
     // handle extensions
@@ -328,12 +334,17 @@
     NSArray *propNames = [propertiesJson allKeys];
     for (NSString *propName in propNames) {
         CMISPropertyData *propertyData;
-        id propValue = propertiesJson[propName];
+        id propValue = [propertiesJson cmis_objectForKeyNotNull:propName];
         if ([propValue isKindOfClass:[NSArray class]]) {
             propertyData = [CMISPropertyData createPropertyForId:propName arrayValue:propValue type:CMISPropertyTypeString];
         }
         else {
-            propertyData = [CMISPropertyData createPropertyForId:propName stringValue:propValue];
+            if(propValue){
+                propertyData = [CMISPropertyData createPropertyForId:propName stringValue:propValue];
+            } else {
+                //TODO create convenient method for nil values?
+                propertyData = [CMISPropertyData createPropertyForId:propName arrayValue:[NSArray array] type:CMISPropertyTypeString];
+            }
         }
         
         [properties addProperty:propertyData];
@@ -354,14 +365,14 @@
     NSMutableArray *renditions = [[NSMutableArray alloc] initWithCapacity:array.count];
     for(NSDictionary *renditionJson in array){
         CMISRenditionData *renditionData = [CMISRenditionData new];
-        renditionData.height = [NSNumber numberWithLongLong:[renditionJson[kCMISBrowserJSONRenditionHeight] longLongValue]];
-        renditionData.kind = renditionJson[kCMISBrowserJSONRenditionKind];
-        renditionData.length = [NSNumber numberWithLongLong:[renditionJson[kCMISBrowserJSONRenditionLength] longLongValue]];
-        renditionData.mimeType = renditionJson[kCMISBrowserJSONRenditionMimeType];
-        renditionData.renditionDocumentId = renditionJson[kCMISBrowserJSONRenditionDocumentId];
-        renditionData.streamId = renditionJson[kCMISBrowserJSONRenditionStreamId];
-        renditionData.title = renditionJson[kCMISBrowserJSONRenditionTitle];
-        renditionData.width = [NSNumber numberWithLongLong:[renditionJson[kCMISBrowserJSONRenditionWidth] longLongValue]];
+        renditionData.height = [NSNumber numberWithLongLong:[[renditionJson cmis_objectForKeyNotNull:kCMISBrowserJSONRenditionHeight] longLongValue]];
+        renditionData.kind = [renditionJson cmis_objectForKeyNotNull:kCMISBrowserJSONRenditionKind];
+        renditionData.length = [NSNumber numberWithLongLong:[[renditionJson cmis_objectForKeyNotNull:kCMISBrowserJSONRenditionLength] longLongValue]];
+        renditionData.mimeType = [renditionJson cmis_objectForKeyNotNull:kCMISBrowserJSONRenditionMimeType];
+        renditionData.renditionDocumentId = [renditionJson cmis_objectForKeyNotNull:kCMISBrowserJSONRenditionDocumentId];
+        renditionData.streamId = [renditionJson cmis_objectForKeyNotNull:kCMISBrowserJSONRenditionStreamId];
+        renditionData.title = [renditionJson cmis_objectForKeyNotNull:kCMISBrowserJSONRenditionTitle];
+        renditionData.width = [NSNumber numberWithLongLong:[[renditionJson cmis_objectForKeyNotNull:kCMISBrowserJSONRenditionWidth] longLongValue]];
         
         // handle extensions
         renditionData.extensions = [CMISBrowserUtil convertExtensions:renditionJson cmisKeys:[CMISBrowserConstants renditionKeys]];
@@ -380,20 +391,20 @@
     
     // create property definition and add to type definition
     CMISPropertyDefinition *propDef = [CMISPropertyDefinition new];
-    propDef.id = propertyDictionary[kCMISBrowserJSONId];
-    propDef.localName = propertyDictionary[kCMISBrowserJSONLocalName];
-    propDef.localNamespace = propertyDictionary[kCMISBrowserJSONLocalNamespace];
-    propDef.queryName = propertyDictionary[kCMISBrowserJSONQueryName];
-    propDef.description = propertyDictionary[kCMISBrowserJSONDescription];
-    propDef.displayName = propertyDictionary[kCMISBrowserJSONDisplayName];
-    propDef.inherited = [propertyDictionary[kCMISBrowserJSONInherited] boolValue];
-    propDef.openChoice = [propertyDictionary[kCMISBrowserJSONOpenChoice] boolValue];
-    propDef.orderable = [propertyDictionary[kCMISBrowserJSONOrderable] boolValue];
-    propDef.queryable = [propertyDictionary[kCMISBrowserJSONQueryable] boolValue];
-    propDef.required = [propertyDictionary[kCMISBrowserJSONRequired] boolValue];
+    propDef.id = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONId];
+    propDef.localName = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONLocalName];
+    propDef.localNamespace = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONLocalNamespace];
+    propDef.queryName = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONQueryName];
+    propDef.description = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONDescription];
+    propDef.displayName = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONDisplayName];
+    propDef.inherited = [propertyDictionary cmis_boolForKey:kCMISBrowserJSONInherited];
+    propDef.openChoice = [propertyDictionary cmis_boolForKey:kCMISBrowserJSONOpenChoice];
+    propDef.orderable = [propertyDictionary cmis_boolForKey:kCMISBrowserJSONOrderable];
+    propDef.queryable = [propertyDictionary cmis_boolForKey:kCMISBrowserJSONQueryable];
+    propDef.required = [propertyDictionary cmis_boolForKey:kCMISBrowserJSONRequired];
     
     // determine property type
-    NSString *typeString = propertyDictionary[kCMISBrowserJSONPropertyType];
+    NSString *typeString = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONPropertyType];
     if ([typeString isEqualToString:kCMISBrowserJSONPropertyTypeValueString]) {
         propDef.propertyType = CMISPropertyTypeString;
     } else if ([typeString isEqualToString:kCMISBrowserJSONPropertyTypeValueId]) {
@@ -413,7 +424,7 @@
     }
     
     // determine cardinality
-    NSString *cardinalityString = propertyDictionary[kCMISBrowserJSONCardinality];
+    NSString *cardinalityString = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONCardinality];
     if ([cardinalityString isEqualToString:kCMISBrowserJSONCardinalityValueSingle]) {
         propDef.cardinality = CMISCardinalitySingle;
     } else if ([cardinalityString isEqualToString:kCMISBrowserJSONCardinalityValueMultiple]) {
@@ -421,7 +432,7 @@
     }
     
     // determine updatability
-    NSString *updatabilityString = propertyDictionary[kCMISBrowserJSONUpdateability];
+    NSString *updatabilityString = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONUpdateability];
     if ([updatabilityString isEqualToString:kCMISBrowserJSONUpdateabilityValueReadOnly]) {
         propDef.updatability = CMISUpdatabilityReadOnly;
     } else if ([updatabilityString isEqualToString:kCMISBrowserJSONUpdateabilityValueReadWrite]) {
@@ -457,7 +468,7 @@
             extensions = [[NSMutableArray alloc] init];
         }
         
-        id value = source[key];
+        id value = [source cmis_objectForKeyNotNull:key];
         if ([value isKindOfClass:NSDictionary.class]) {
             [extensions addObject:[[CMISExtensionElement alloc] initNodeWithName:key namespaceUri:nil attributes:nil children:[CMISBrowserUtil convertExtension:value]]];
         } else if ([value isKindOfClass:NSArray.class]) {
@@ -478,7 +489,7 @@
     NSMutableArray *extensions = [[NSMutableArray alloc] init]; // array of CMISExtensionElement's
     
     for (NSString *key in dictionary.keyEnumerator) {
-        id value = dictionary[key];
+        id value = [dictionary cmis_objectForKeyNotNull:key];
         if ([value isKindOfClass:NSDictionary.class]) {
             [extensions addObject:[[CMISExtensionElement alloc] initNodeWithName:key namespaceUri:nil attributes:nil children:[CMISBrowserUtil convertExtension:value]]];
         } else if ([value isKindOfClass:NSArray.class]) {

Added: chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/CMISNSDictionary+CMISUtil.h
URL: http://svn.apache.org/viewvc/chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/CMISNSDictionary%2BCMISUtil.h?rev=1588358&view=auto
==============================================================================
--- chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/CMISNSDictionary+CMISUtil.h (added)
+++ chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/CMISNSDictionary+CMISUtil.h Thu Apr 17 20:00:33 2014
@@ -0,0 +1,33 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+@interface NSDictionary (CMISUtil)
+
+///returns the object or nil if value is NSNull for given key
+- (id)cmis_objectForKeyNotNull:(id)aKey;
+
+///convenient method; returns BOOL value or NO if value is NSNull for given key
+- (BOOL)cmis_boolForKey:(id)aKey;
+
+///convenient method; returns int value or 0 if value is NSNull for given key
+- (int)cmis_intForKey:(id)aKey;
+
+@end

Propchange: chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/CMISNSDictionary+CMISUtil.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/CMISNSDictionary+CMISUtil.m
URL: http://svn.apache.org/viewvc/chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/CMISNSDictionary%2BCMISUtil.m?rev=1588358&view=auto
==============================================================================
--- chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/CMISNSDictionary+CMISUtil.m (added)
+++ chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/CMISNSDictionary+CMISUtil.m Thu Apr 17 20:00:33 2014
@@ -0,0 +1,40 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import "CMISNSDictionary+CMISUtil.h"
+
+@implementation NSDictionary (CMISUtil)
+
+- (id)cmis_objectForKeyNotNull:(id)aKey
+{
+    id value = self[aKey];
+    return value == [NSNull null] ? nil : value;
+}
+
+- (BOOL)cmis_boolForKey:(id)aKey
+{
+    return [[self cmis_objectForKeyNotNull:aKey] boolValue];
+}
+
+- (int)cmis_intForKey:(id)aKey
+{
+    return [[self cmis_objectForKeyNotNull:aKey] intValue];
+}
+
+@end

Propchange: chemistry/objectivecmis/branches/browser-binding/ObjectiveCMIS/CMISNSDictionary+CMISUtil.m
------------------------------------------------------------------------------
    svn:eol-style = native