- Implemented Negative Type Cache - Fixed Progress Block Callback Issue for Uploads that get cancelled right before completion - Added Interface to CMISQueryStatement Class that allows setting Array Parameters for WHERE IN Clauses - Fixed Bug that could cause Completion Blocks get called multiple times if already completed or failed Request gets cancelled - Support for setting Property values to nil git-svn-id: https://svn.apache.org/repos/asf/chemistry/objectivecmis/trunk@1658384 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ObjectiveCMIS/Bindings/Browser/CMISBrowserUtil.m b/ObjectiveCMIS/Bindings/Browser/CMISBrowserUtil.m index f05c4ed..1a85eeb 100644 --- a/ObjectiveCMIS/Bindings/Browser/CMISBrowserUtil.m +++ b/ObjectiveCMIS/Bindings/Browser/CMISBrowserUtil.m
@@ -37,8 +37,11 @@ #import "CMISPrincipal.h" #import "CMISAllowableActions.h" -NSString * const kCMISBrowserMinValueJSONProperty = @"\"minValue\":0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049,"; -NSString * const kCMISBrowserMaxValueJSONProperty = @"\"maxValue\":179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,"; +NSString * const kCMISBrowserMinValueAlfrescoJSONProperty = @"\"minValue\":0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049,"; +NSString * const kCMISBrowserMinValueECMJSONProperty = @"\"minValue\":-179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,"; + +NSString * const kCMISBrowserMaxValueAlfrescoJSONProperty = @"\"maxValue\":179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,"; +NSString * const kCMISBrowserMaxValueECMJSONProperty = @"\"maxValue\":179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,"; @interface NSObject (CMISUtil) @@ -136,8 +139,10 @@ NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; // remove the minValue and maxValue properties as they are effectively indicating any reasonable value is valid - jsonString = [jsonString stringByReplacingOccurrencesOfString:kCMISBrowserMinValueJSONProperty withString:@""]; - jsonString = [jsonString stringByReplacingOccurrencesOfString:kCMISBrowserMaxValueJSONProperty withString:@""]; + jsonString = [jsonString stringByReplacingOccurrencesOfString:kCMISBrowserMinValueAlfrescoJSONProperty withString:@""]; + jsonString = [jsonString stringByReplacingOccurrencesOfString:kCMISBrowserMinValueECMJSONProperty withString:@""]; + jsonString = [jsonString stringByReplacingOccurrencesOfString:kCMISBrowserMaxValueAlfrescoJSONProperty withString:@""]; + jsonString = [jsonString stringByReplacingOccurrencesOfString:kCMISBrowserMaxValueECMJSONProperty withString:@""]; // re-try and JSON parse serialisationError = nil; @@ -402,11 +407,12 @@ objectData.baseType = CMISBaseTypeFolder; } - objectData.acl = [CMISBrowserUtil convertAcl:[dictionary cmis_objectForKeyNotNull:kCMISBrowserJSONAcl]]; //TODO here we should pass isExactAcl:nil! + BOOL isExactAcl = [dictionary cmis_boolForKey:kCMISBrowserJSONIsExact]; + objectData.acl = [CMISBrowserUtil convertAcl:[dictionary cmis_objectForKeyNotNull:kCMISBrowserJSONAcl] isExactAcl:isExactAcl]; objectData.allowableActions = [CMISBrowserUtil convertAllowableActions:[dictionary cmis_objectForKeyNotNull:kCMISBrowserJSONAllowableActions]]; - objectData.isExactAcl = [dictionary cmis_boolForKey:kCMISBrowserJSONIsExact]; + objectData.isExactAcl = isExactAcl; // TODO set policyIds @@ -830,7 +836,7 @@ return result; } -+ (CMISAcl *)convertAcl:(NSDictionary *)jsonDictionary ++ (CMISAcl *)convertAcl:(NSDictionary *)jsonDictionary isExactAcl:(BOOL)isExact { if (!jsonDictionary) { return nil; @@ -876,7 +882,7 @@ result.aces = [aces copy]; - //TODO result.isExact = isExact; // there should be a "isExcat" parameter of this method + result.isExact = isExact; result.extensions = [CMISObjectConverter convertExtensions:jsonDictionary cmisKeys:[CMISBrowserConstants aclKeys]];
diff --git a/ObjectiveCMIS/Bindings/CMISQueryStatement.h b/ObjectiveCMIS/Bindings/CMISQueryStatement.h index 600460c..4941466 100644 --- a/ObjectiveCMIS/Bindings/CMISQueryStatement.h +++ b/ObjectiveCMIS/Bindings/CMISQueryStatement.h
@@ -119,6 +119,18 @@ - (void)setStringContainsAtIndex:(NSUInteger)parameterIndex string:(NSString*)string; /** + * Sets the designated parameter to the given list of strings. + * Strings will be concatenated by ',' + * Use this method to proide a list of values for an IN (?) statement + * + * @param parameterIndex + * the parameter index (one-based) + * @param stringArray + * the values + */ +- (void)setStringArrayAtIndex:(NSUInteger)parameterIndex stringArray:(NSArray*)stringArray; + +/** * Sets the designated parameter to the given number. * * @param parameterIndex
diff --git a/ObjectiveCMIS/Bindings/CMISQueryStatement.m b/ObjectiveCMIS/Bindings/CMISQueryStatement.m index 26d0efd..53f8ff2 100644 --- a/ObjectiveCMIS/Bindings/CMISQueryStatement.m +++ b/ObjectiveCMIS/Bindings/CMISQueryStatement.m
@@ -76,6 +76,20 @@ } } +- (void)setStringArrayAtIndex:(NSUInteger)parameterIndex stringArray:(NSArray*)stringArray { + NSMutableString *paramStr = [NSMutableString string]; + for (NSString *value in stringArray) { + if ([value isKindOfClass:NSString.class] && value.length > 0) { + [paramStr appendFormat:@"%@, ", [CMISQueryStatement escapeString:value withSurroundingQuotes:YES]]; + } + } + if (paramStr.length > 2) { + self.parametersDictionary[@(parameterIndex)] = [paramStr substringToIndex:paramStr.length-2]; + } else { + self.parametersDictionary[@(parameterIndex)] = [NSString string]; // Empty list + } +} + - (void)setUrlAtIndex:(NSUInteger)parameterIndex url:(NSURL*)url { if (url) { NSError *error;
diff --git a/ObjectiveCMIS/Client/CMISSession.m b/ObjectiveCMIS/Client/CMISSession.m index d63fc19..4a0131f 100644 --- a/ObjectiveCMIS/Client/CMISSession.m +++ b/ObjectiveCMIS/Client/CMISSession.m
@@ -351,15 +351,22 @@ - (CMISRequest*)retrieveTypeDefinition:(NSString *)typeId completionBlock:(void (^)(CMISTypeDefinition *typeDefinition, NSError *error))completionBlock { - CMISTypeDefinition *typeDefinition = [self.typeCache objectForKey:typeId]; + id typeDefinition = [self.typeCache objectForKey:typeId]; if (typeDefinition) { - completionBlock(typeDefinition, nil); + if (typeDefinition == [NSNull null]) { + completionBlock(nil, [CMISErrors createCMISErrorWithCode:kCMISErrorCodeObjectNotFound detailedDescription:nil]); + } else { + completionBlock(typeDefinition, nil); + } return nil; } return [self.binding.repositoryService retrieveTypeDefinition:typeId completionBlock:^(CMISTypeDefinition *typeDefinition, NSError *error) { if (typeDefinition) { [self.typeCache setObject:typeDefinition forKey:typeId]; + } else if ([error.domain isEqualToString:kCMISErrorDomainName] && error.code == kCMISErrorCodeObjectNotFound) { + // Negative type cache + [self.typeCache setObject:[NSNull null] forKey:typeId]; } completionBlock(typeDefinition, error); }];
diff --git a/ObjectiveCMIS/Common/CMISConstants.h b/ObjectiveCMIS/Common/CMISConstants.h index 03564d5..4a723c9 100644 --- a/ObjectiveCMIS/Common/CMISConstants.h +++ b/ObjectiveCMIS/Common/CMISConstants.h
@@ -36,8 +36,11 @@ extern NSString * const kCMISPropertyContentStreamFileName; extern NSString * const kCMISPropertyContentStreamLength; extern NSString * const kCMISPropertyContentStreamMediaType; +extern NSString * const kCMISPropertyContentStreamHash; extern NSString * const kCMISPropertyObjectTypeId; extern NSString * const kCMISPropertyVersionSeriesId; +extern NSString * const kCMISPropertyVersionSeriesCheckedOutBy; +extern NSString * const kCMISPropertyVersionSeriesCheckedOutId; extern NSString * const kCMISPropertyVersionLabel; extern NSString * const kCMISPropertyIsLatestVersion; extern NSString * const kCMISPropertyIsMajorVersion;
diff --git a/ObjectiveCMIS/Common/CMISConstants.m b/ObjectiveCMIS/Common/CMISConstants.m index 39fe8d1..d4ab836 100644 --- a/ObjectiveCMIS/Common/CMISConstants.m +++ b/ObjectiveCMIS/Common/CMISConstants.m
@@ -45,8 +45,11 @@ NSString * const kCMISPropertyContentStreamFileName = @"cmis:contentStreamFileName"; NSString * const kCMISPropertyContentStreamLength = @"cmis:contentStreamLength"; NSString * const kCMISPropertyContentStreamMediaType = @"cmis:contentStreamMimeType"; +NSString * const kCMISPropertyContentStreamHash = @"cmis:contentStreamHash"; NSString * const kCMISPropertyObjectTypeId = @"cmis:objectTypeId"; NSString * const kCMISPropertyVersionSeriesId = @"cmis:versionSeriesId"; +NSString * const kCMISPropertyVersionSeriesCheckedOutBy = @"cmis:versionSeriesCheckedOutBy"; +NSString * const kCMISPropertyVersionSeriesCheckedOutId= @"cmis:versionSeriesCheckedOutId"; NSString * const kCMISPropertyVersionLabel = @"cmis:versionLabel"; NSString * const kCMISPropertyIsLatestVersion = @"cmis:isLatestVersion"; NSString * const kCMISPropertyIsMajorVersion = @"cmis:isMajorVersion"; @@ -57,7 +60,6 @@ NSString * const kCMISPropertySecondaryObjectTypeIds = @"cmis:secondaryObjectTypeIds"; NSString * const kCMISPropertyDescription = @"cmis:description"; - // Property values NSString * const kCMISPropertyObjectTypeIdValueDocument = @"cmis:document";
diff --git a/ObjectiveCMIS/Utils/CMISHttpRequest.m b/ObjectiveCMIS/Utils/CMISHttpRequest.m index 73c9d1d..3ad9575 100644 --- a/ObjectiveCMIS/Utils/CMISHttpRequest.m +++ b/ObjectiveCMIS/Utils/CMISHttpRequest.m
@@ -147,7 +147,10 @@ if (self.completionBlock) { NSString *detailedDescription = [NSString stringWithFormat:@"Could not create network session for %@", urlRequest.URL]; NSError *cmisError = [CMISErrors createCMISErrorWithCode:kCMISErrorCodeConnection detailedDescription:detailedDescription]; - self.completionBlock(nil, cmisError); + void (^completionBlock)(CMISHttpResponse *httpResponse, NSError *error); + completionBlock = self.completionBlock; + self.completionBlock = nil; // Prevent multiple execution if method on this request gets called inside completion block + completionBlock(nil, cmisError); } } @@ -173,8 +176,10 @@ self.urlSession = nil; - NSError *cmisError = [CMISErrors createCMISErrorWithCode:kCMISErrorCodeCancelled detailedDescription:@"Request was cancelled"]; - completionBlock(nil, cmisError); + if (completionBlock) { + NSError *cmisError = [CMISErrors createCMISErrorWithCode:kCMISErrorCodeCancelled detailedDescription:@"Request was cancelled"]; + completionBlock(nil, cmisError); + } } } @@ -210,7 +215,10 @@ // call the completion block on the main thread dispatch_async(dispatch_get_main_queue(), ^{ - self.completionBlock(httpResponse, cmisError); + void (^completionBlock)(CMISHttpResponse *httpResponse, NSError *error); + completionBlock = self.completionBlock; + self.completionBlock = nil; // Prevent multiple execution if method on this request gets called inside completion block + completionBlock(nil, cmisError); }); }
diff --git a/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m b/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m index 4c33f4e..f64928d 100644 --- a/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m +++ b/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m
@@ -87,6 +87,7 @@ @property (nonatomic, copy) void (^progressBlock)(unsigned long long bytesUploaded, unsigned long long bytesTotal); @property (nonatomic, assign) BOOL useCombinedInputStream; @property (nonatomic, assign) BOOL base64Encoding; +@property (nonatomic, assign) BOOL transferCompleted; @property (nonatomic, strong) NSInputStream *combinedInputStream; @property (nonatomic, strong) NSOutputStream *encoderStream; @property (nonatomic, strong) NSData *streamStartData; @@ -170,6 +171,7 @@ completionBlock:completionBlock]; if (self) { _progressBlock = progressBlock; + _transferCompleted = NO; } return self; } @@ -205,6 +207,9 @@ - (void)cancel { + if (self.transferCompleted) { + return; + } self.progressBlock = nil; [super cancel]; @@ -258,8 +263,14 @@ } if (self.bytesExpected == 0) { + if (totalBytesSent >= totalBytesExpectedToSend) { + self.transferCompleted = YES; + } self.progressBlock((unsigned long long)totalBytesSent, (unsigned long long)totalBytesExpectedToSend); } else { + if (totalBytesSent >= self.bytesExpected) { + self.transferCompleted = YES; + } self.progressBlock((unsigned long long)totalBytesSent, self.bytesExpected); } }
diff --git a/ObjectiveCMIS/Utils/CMISObjectConverter.m b/ObjectiveCMIS/Utils/CMISObjectConverter.m index 887ea7c..1d700da 100644 --- a/ObjectiveCMIS/Utils/CMISObjectConverter.m +++ b/ObjectiveCMIS/Utils/CMISObjectConverter.m
@@ -140,178 +140,182 @@ Class expectedType = nil; BOOL validType = YES; - switch (propertyDefinition.propertyType) { - case(CMISPropertyTypeString): { - expectedType = [NSString class]; - if ([propertyValue isKindOfClass:expectedType]) { - [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId stringValue:propertyValue]]; - } else if ([propertyValue isKindOfClass:[NSArray class]]) { - for (id propertyValueItemValue in propertyValue) { - if (![propertyValueItemValue isKindOfClass:expectedType]) { - validType = NO; - break; + if (propertyValue == [NSNull null]) { + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:nil type:propertyDefinition.propertyType]]; + } else { + switch (propertyDefinition.propertyType) { + case(CMISPropertyTypeString): { + expectedType = [NSString class]; + if ([propertyValue isKindOfClass:expectedType]) { + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId stringValue:propertyValue]]; + } else if ([propertyValue isKindOfClass:[NSArray class]]) { + for (id propertyValueItemValue in propertyValue) { + if (![propertyValueItemValue isKindOfClass:expectedType]) { + validType = NO; + break; + } } - } - if (validType) { - [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:propertyValue type:propertyDefinition.propertyType]]; - } - } else { - validType = NO; - } - break; - } - case(CMISPropertyTypeBoolean): { - expectedType = [NSNumber class]; - if ([propertyValue isKindOfClass:expectedType]) { - BOOL boolValue = ((NSNumber *) propertyValue).boolValue; - [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId boolValue:boolValue]]; - } else if ([propertyValue isKindOfClass:[NSArray class]]) { - for (id propertyValueItemValue in propertyValue) { - if (![propertyValueItemValue isKindOfClass:expectedType]) { - validType = NO; - break; + if (validType) { + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:propertyValue type:propertyDefinition.propertyType]]; } + } else { + validType = NO; } - if (validType) { - [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:propertyValue type:propertyDefinition.propertyType]]; - } - } else { - validType = NO; + break; } - break; - } - case(CMISPropertyTypeInteger): { - expectedType = [NSNumber class]; - if ([propertyValue isKindOfClass:expectedType]) { - NSInteger intValue = ((NSNumber *) propertyValue).integerValue; - [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId integerValue:intValue]]; - } else if ([propertyValue isKindOfClass:[NSArray class]]) { - for (id propertyValueItemValue in propertyValue) { - if (![propertyValueItemValue isKindOfClass:expectedType]) { - validType = NO; - break; + case(CMISPropertyTypeBoolean): { + expectedType = [NSNumber class]; + if ([propertyValue isKindOfClass:expectedType]) { + BOOL boolValue = ((NSNumber *) propertyValue).boolValue; + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId boolValue:boolValue]]; + } else if ([propertyValue isKindOfClass:[NSArray class]]) { + for (id propertyValueItemValue in propertyValue) { + if (![propertyValueItemValue isKindOfClass:expectedType]) { + validType = NO; + break; + } } - } - if (validType) { - [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:propertyValue type:propertyDefinition.propertyType]]; - } - } else { - validType = NO; - } - break; - } - case(CMISPropertyTypeDecimal): { - expectedType = [NSNumber class]; - if ([propertyValue isKindOfClass:expectedType]) { - [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId decimalValue:propertyValue]]; - } else if ([propertyValue isKindOfClass:[NSArray class]]) { - for (id propertyValueItemValue in propertyValue) { - if (![propertyValueItemValue isKindOfClass:expectedType]) { - validType = NO; - break; + if (validType) { + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:propertyValue type:propertyDefinition.propertyType]]; } + } else { + validType = NO; } - if (validType) { - [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:propertyValue type:propertyDefinition.propertyType]]; - } - } else { - validType = NO; + break; } - break; - } - case(CMISPropertyTypeId): { - expectedType = [NSString class]; - if ([propertyValue isKindOfClass:expectedType]) { - [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId idValue:propertyValue]]; - } else if ([propertyValue isKindOfClass:[NSArray class]]) { - for (id propertyValueItemValue in propertyValue) { - if (![propertyValueItemValue isKindOfClass:expectedType]) { - validType = NO; - break; + case(CMISPropertyTypeInteger): { + expectedType = [NSNumber class]; + if ([propertyValue isKindOfClass:expectedType]) { + NSInteger intValue = ((NSNumber *) propertyValue).integerValue; + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId integerValue:intValue]]; + } else if ([propertyValue isKindOfClass:[NSArray class]]) { + for (id propertyValueItemValue in propertyValue) { + if (![propertyValueItemValue isKindOfClass:expectedType]) { + validType = NO; + break; + } } - } - if (validType) { - [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:propertyValue type:propertyDefinition.propertyType]]; - } - } else { - validType = NO; - } - break; - } - case(CMISPropertyTypeDateTime): { - if ([propertyValue isKindOfClass:[NSString class]]) { - propertyValue = [CMISDateUtil dateFromString:propertyValue]; - } - expectedType = [NSDate class]; - if ([propertyValue isKindOfClass:expectedType]) { - [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId dateTimeValue:propertyValue]]; - } else if ([propertyValue isKindOfClass:[NSArray class]]) { - for (__strong id propertyValueItemValue in propertyValue) { - if ([propertyValueItemValue isKindOfClass:[NSString class]]) { - propertyValueItemValue = [CMISDateUtil dateFromString:propertyValueItemValue]; + if (validType) { + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:propertyValue type:propertyDefinition.propertyType]]; } - if (![propertyValueItemValue isKindOfClass:expectedType]) { - validType = NO; - break; - } + } else { + validType = NO; } - if (validType) { - [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:propertyValue type:propertyDefinition.propertyType]]; - } - } else { - validType = NO; + break; } - break; - } - case(CMISPropertyTypeUri): { - if ([propertyValue isKindOfClass:[NSString class]]) { - propertyValue = [NSURL URLWithString:propertyValue]; - } - expectedType = [NSURL class]; - if ([propertyValue isKindOfClass:expectedType]) { - [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId uriValue:propertyValue]]; - } else if ([propertyValue isKindOfClass:[NSArray class]]) { - for (__strong id propertyValueItemValue in propertyValue) { - if ([propertyValueItemValue isKindOfClass:[NSString class]]) { - propertyValueItemValue = [NSURL URLWithString:propertyValueItemValue]; + case(CMISPropertyTypeDecimal): { + expectedType = [NSNumber class]; + if ([propertyValue isKindOfClass:expectedType]) { + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId decimalValue:propertyValue]]; + } else if ([propertyValue isKindOfClass:[NSArray class]]) { + for (id propertyValueItemValue in propertyValue) { + if (![propertyValueItemValue isKindOfClass:expectedType]) { + validType = NO; + break; + } } - if (![propertyValueItemValue isKindOfClass:expectedType]) { - validType = NO; - break; + if (validType) { + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:propertyValue type:propertyDefinition.propertyType]]; } + } else { + validType = NO; } - if (validType) { - [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:propertyValue type:propertyDefinition.propertyType]]; - } - } else { - validType = NO; + break; } - break; - } - case(CMISPropertyTypeHtml): { - expectedType = [NSString class]; - if ([propertyValue isKindOfClass:expectedType]) { - [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId htmlValue:propertyValue]]; - } else if ([propertyValue isKindOfClass:[NSArray class]]) { - for (id propertyValueItemValue in propertyValue) { - if (![propertyValueItemValue isKindOfClass:expectedType]) { - validType = NO; - break; + case(CMISPropertyTypeId): { + expectedType = [NSString class]; + if ([propertyValue isKindOfClass:expectedType]) { + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId idValue:propertyValue]]; + } else if ([propertyValue isKindOfClass:[NSArray class]]) { + for (id propertyValueItemValue in propertyValue) { + if (![propertyValueItemValue isKindOfClass:expectedType]) { + validType = NO; + break; + } } + if (validType) { + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:propertyValue type:propertyDefinition.propertyType]]; + } + } else { + validType = NO; } - if (validType) { - [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:propertyValue type:propertyDefinition.propertyType]]; - } - } else { - validType = NO; + break; } - break; - } - default: { - NSError *error = [CMISErrors createCMISErrorWithCode:kCMISErrorCodeInvalidArgument - detailedDescription:[NSString stringWithFormat:@"Unsupported: cannot convert property type %li", (long)propertyDefinition.propertyType]]; - completionBlock(nil, error); - return; + case(CMISPropertyTypeDateTime): { + if ([propertyValue isKindOfClass:[NSString class]]) { + propertyValue = [CMISDateUtil dateFromString:propertyValue]; + } + expectedType = [NSDate class]; + if ([propertyValue isKindOfClass:expectedType]) { + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId dateTimeValue:propertyValue]]; + } else if ([propertyValue isKindOfClass:[NSArray class]]) { + for (__strong id propertyValueItemValue in propertyValue) { + if ([propertyValueItemValue isKindOfClass:[NSString class]]) { + propertyValueItemValue = [CMISDateUtil dateFromString:propertyValueItemValue]; + } + if (![propertyValueItemValue isKindOfClass:expectedType]) { + validType = NO; + break; + } + } + if (validType) { + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:propertyValue type:propertyDefinition.propertyType]]; + } + } else { + validType = NO; + } + break; + } + case(CMISPropertyTypeUri): { + if ([propertyValue isKindOfClass:[NSString class]]) { + propertyValue = [NSURL URLWithString:propertyValue]; + } + expectedType = [NSURL class]; + if ([propertyValue isKindOfClass:expectedType]) { + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId uriValue:propertyValue]]; + } else if ([propertyValue isKindOfClass:[NSArray class]]) { + for (__strong id propertyValueItemValue in propertyValue) { + if ([propertyValueItemValue isKindOfClass:[NSString class]]) { + propertyValueItemValue = [NSURL URLWithString:propertyValueItemValue]; + } + if (![propertyValueItemValue isKindOfClass:expectedType]) { + validType = NO; + break; + } + } + if (validType) { + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:propertyValue type:propertyDefinition.propertyType]]; + } + } else { + validType = NO; + } + break; + } + case(CMISPropertyTypeHtml): { + expectedType = [NSString class]; + if ([propertyValue isKindOfClass:expectedType]) { + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId htmlValue:propertyValue]]; + } else if ([propertyValue isKindOfClass:[NSArray class]]) { + for (id propertyValueItemValue in propertyValue) { + if (![propertyValueItemValue isKindOfClass:expectedType]) { + validType = NO; + break; + } + } + if (validType) { + [convertedProperties addProperty:[CMISPropertyData createPropertyForId:propertyId arrayValue:propertyValue type:propertyDefinition.propertyType]]; + } + } else { + validType = NO; + } + break; + } + default: { + NSError *error = [CMISErrors createCMISErrorWithCode:kCMISErrorCodeInvalidArgument + detailedDescription:[NSString stringWithFormat:@"Unsupported: cannot convert property type %li", (long)propertyDefinition.propertyType]]; + completionBlock(nil, error); + return; + } } }