Modified: 
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m?rev=1795295&r1=1795294&r2=1795295&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m 
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m 
Tue May 16 10:33:32 2017
@@ -232,7 +232,10 @@ const NSUInteger kRawBufferSize = 24576;
 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task 
didCompleteWithError:(NSError *)error
 {
     [super URLSession:session task:task didCompleteWithError:error];
-    
+}
+
+- (void)didCompleteWithError:(NSError *)error {
+    [super didCompleteWithError:error];
     if (self.useCombinedInputStream) {
         if (error) {
             [self stopSendWithStatus:@"connection is being terminated with 
error."];
@@ -398,7 +401,7 @@ const NSUInteger kRawBufferSize = 24576;
                 if (bytesWritten <= 0) {
                     [self stopSendWithStatus:@"Network write error"];
                     NSError *cmisError = [CMISErrors 
createCMISErrorWithCode:kCMISErrorCodeConnection detailedDescription:@"Network 
write error"];
-                    [self URLSession:nil task:nil 
didCompleteWithError:cmisError];
+                    [self didCompleteWithError:cmisError];
                 } else {
                     self.bufferOffset += bytesWritten;
                 }

Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISMimeHelper.h
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISMimeHelper.h?rev=1795295&r1=1795294&r2=1795295&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISMimeHelper.h 
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISMimeHelper.h Tue May 
16 10:33:32 2017
@@ -38,4 +38,15 @@ extern NSString * const kCMISMimeHelperD
  */
 + (NSString *)encodeContentDisposition:(NSString *)disposition 
fileName:(NSString *)filename;
 
+/**
+ * Parses a WWW-Authenticate header value.
+ *
+ * @param value
+ *            the header value to parse
+ *
+ * @return a dictionary with the (lower case) challenge name as key and as the
+ *         value a sub-dictionary with parameters of the challenge
+ */
++ (NSDictionary *)challengesFromAuthenticateHeader:(NSString 
*)authenticationHeader;
+
 @end

Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISMimeHelper.m
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISMimeHelper.m?rev=1795295&r1=1795294&r2=1795295&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISMimeHelper.m 
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISMimeHelper.m Tue May 
16 10:33:32 2017
@@ -91,4 +91,109 @@ NSString * const kCMISMimeHelperHexDigit
     return encoded;
 }
 
++ (NSDictionary *)challengesFromAuthenticateHeader:(NSString *)value
+{
+    if (value == nil || value.length == 0) {
+        return nil;
+    }
+    
+    NSString *trimValue = [value 
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
+    
+    NSMutableDictionary *result = [NSMutableDictionary new];
+    NSLocale *englishLocale = [[NSLocale alloc] 
initWithLocaleIdentifier:@"en"];
+    
+    BOOL inQuotes = NO;
+    BOOL inName = YES;
+    NSString *challenge = nil;
+    NSString *paramName = @"";
+    NSMutableString *sb = [NSMutableString new];
+    for (int i = 0; i < trimValue.length; i++) {
+        unichar c = [trimValue characterAtIndex:i];
+        
+        if (c == '\\') {
+            if (!inQuotes) {
+                return nil;
+            }
+            if (trimValue.length > i && [trimValue characterAtIndex:i + 1] == 
'\\') {
+                [sb appendFormat:@"%c", '\\'];
+                i++;
+            } else if (trimValue.length > i && [trimValue characterAtIndex:i + 
1] == '"') {
+                [sb appendFormat:@"%c", '"'];
+                i++;
+            } else {
+                return nil;
+            }
+        } else if (c == '"') {
+            if (inName) {
+                return nil;
+            }
+            if (inQuotes) {
+                NSMutableDictionary *authMap = result[challenge];
+                if (authMap == nil) {
+                    return nil;
+                }
+                authMap[paramName] = sb;
+            }
+            sb = [NSMutableString new];
+            inQuotes = !inQuotes;
+        } else if (c == '=') {
+            if (inName) {
+                paramName = [sb 
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
+                
+                NSUInteger spcIdx = [paramName rangeOfString:@" "].location;
+                if (spcIdx != NSNotFound) {
+                    challenge = [[paramName substringToIndex:spcIdx] 
lowercaseStringWithLocale:englishLocale];
+                    result[challenge] = [NSMutableDictionary new];
+                    paramName = [[paramName substringFromIndex:spcIdx] 
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
+                }
+                
+                sb = [NSMutableString new];
+                inName = NO;
+            } else if (!inQuotes) {
+                return nil;
+            }
+        } else if (c == ',') {
+            if (inName) {
+                challenge = [[sb 
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] 
lowercaseStringWithLocale:englishLocale];
+                result[challenge] = [NSMutableDictionary new];
+                sb = [NSMutableString new];
+            } else {
+                if (inQuotes) {
+                    [sb appendFormat:@"%c", c];
+                } else {
+                    NSMutableDictionary *authMap = result[challenge];
+                    if (authMap == nil) {
+                        return nil;
+                    }
+                    if (!authMap[paramName]) {
+                        authMap[paramName] = sb;
+                    }
+                    sb = [NSMutableString new];
+                    inName = YES;
+                }
+            }
+        } else {
+            [sb appendFormat:@"%c", c];
+        }
+    }
+    if (inQuotes) {
+        return nil;
+    }
+    if (inName) {
+        challenge = [[sb stringByTrimmingCharactersInSet:[NSCharacterSet 
whitespaceCharacterSet]] lowercaseStringWithLocale:englishLocale];
+        result[challenge] = [NSMutableDictionary new];
+    } else {
+        NSMutableDictionary *authMap = result[challenge];
+        if (authMap == nil) {
+            return nil;
+        }
+        if (!authMap[paramName]) {
+            authMap[paramName] = [sb 
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
+        }
+    }
+    
+    return result;
+
+}
+
 @end

Added: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISOAuthHttpRequest.h
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISOAuthHttpRequest.h?rev=1795295&view=auto
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISOAuthHttpRequest.h 
(added)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISOAuthHttpRequest.h 
Tue May 16 10:33:32 2017
@@ -0,0 +1,24 @@
+/*
+  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 "CMISHttpRequest.h"
+
+@interface CMISOAuthHttpRequest : CMISHttpRequest
+
+@end

Added: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISOAuthHttpRequest.m
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISOAuthHttpRequest.m?rev=1795295&view=auto
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISOAuthHttpRequest.m 
(added)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISOAuthHttpRequest.m 
Tue May 16 10:33:32 2017
@@ -0,0 +1,116 @@
+/*
+  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 "CMISOAuthHttpRequest.h"
+#import "CMISOAuthHttpResponse.h"
+#import "CMISLog.h"
+#import "CMISDictionaryUtil.h"
+#import "CMISErrors.h"
+#import "CMISMimeHelper.h"
+
+@implementation CMISOAuthHttpRequest
+
+-(BOOL)shouldApplyHttpHeaders
+{
+    return NO; // http headers of the CMISOAuthAuthenticationProvider should 
not be applied or else we would end up in an endless loop
+}
+
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task 
didCompleteWithError:(NSError *)error
+{
+    if (self.completionBlock) {
+        if (!error) {
+            NSError *cmisError = nil;
+            
+            // no error returned but we check if an OAuth error message was 
returned
+            CMISHttpResponse *httpResponse = [CMISOAuthHttpResponse 
responseUsingURLHTTPResponse:self.response data:self.responseBody];
+            if (httpResponse.statusCode != 200) {
+                if (httpResponse.statusCode == 401) {
+                    NSDictionary *challenges = [CMISMimeHelper 
challengesFromAuthenticateHeader:[[self.response allHeaderFields] 
objectForKey:@"WWW-Authenticate"]];
+                    
+                    if ([challenges objectForKey:@"bearer"]) {
+                        NSDictionary *params = [challenges 
objectForKey:@"bearer"];
+                        
+                        NSString *error = [params objectForKey:@"error"];
+                        NSString *description = [params 
objectForKey:@"error_description"];
+                        NSString *uri = [params objectForKey:@"error_uri"];
+                        
+                        if ([CMISLog sharedInstance].logLevel == 
CMISLogLevelDebug) {
+                            CMISLogDebug(@"Invalid OAuth token: %@", params);
+                        }
+                        
+                        NSMutableDictionary *oAuthErroUserDict = 
[NSMutableDictionary new];
+                        if (error) {
+                            
oAuthErroUserDict[kCMISErrorOAuthExceptionErrorKey] = error;
+                        }
+                        if (description) {
+                            
oAuthErroUserDict[kCMISErrorOAuthExceptionDescriptionKey] = description;
+                        }
+                        if (uri) {
+                            oAuthErroUserDict[kCMISErrorOAuthExceptionUriKey] 
= uri;
+                        }
+                        cmisError = [CMISErrors 
createCMISErrorWithCode:kCMISErrorCodeConnection detailedDescription:[NSString 
stringWithFormat:@"Unauthorized: error: %@ ,errorStr: %@", error, description] 
additionalUserInfo:oAuthErroUserDict];
+                        
+                        [self executeCompletionBlockError:cmisError];
+                    } // else: superclass will handle authorization error
+                } else {
+                    NSDictionary *jsonDictionary = [CMISOAuthHttpResponse 
parseResponse:httpResponse error:&cmisError];
+                    if (!cmisError) {
+                        if ([CMISLog sharedInstance].logLevel == 
CMISLogLevelDebug) {
+                            CMISLogDebug(@"OAuth token request failed: %@", 
jsonDictionary);
+                        }
+                        
+                        id error = [jsonDictionary 
cmis_objectForKeyNotNull:@"error"];
+                        id description = [jsonDictionary 
cmis_objectForKeyNotNull:@"error_description"];
+                        id uri = [jsonDictionary 
cmis_objectForKeyNotNull:@"error_uri"];
+                        
+                        NSMutableDictionary *oAuthErroUserDict = 
[NSMutableDictionary new];
+                        if ([error description]) {
+                            
oAuthErroUserDict[kCMISErrorOAuthExceptionErrorKey] = [error description];
+                        }
+                        if ([description description]) {
+                            
oAuthErroUserDict[kCMISErrorOAuthExceptionDescriptionKey] = [description 
description];
+                        }
+                        if ([uri description]) {
+                            oAuthErroUserDict[kCMISErrorOAuthExceptionUriKey] 
= [uri description];
+                        }
+                        cmisError = [CMISErrors 
createCMISErrorWithCode:kCMISErrorCodeConnection detailedDescription:[NSString 
stringWithFormat:@"OAuth token request failed: error=%@, description=%@, 
errorUri=%@", error, description, uri] additionalUserInfo:oAuthErroUserDict];
+                        
+                        if(cmisError) {
+                            [self executeCompletionBlockError:cmisError];
+                        } else {
+                            [self executeCompletionBlockResponse:httpResponse];
+                        }
+                    }
+                }
+            }
+        }
+    }
+    [super URLSession:session task:task didCompleteWithError:error];
+}
+
+-(BOOL)callCompletionBlockOnOriginalThread
+{
+    /* Note: calling perform selector on the original thread (spawned by the 
NSOperationQueue) does not work as the runloop is thrown away (after the main 
method finishes) without ever calling the executeCompletionBlock selector.
+     */
+    return NO;
+}
+
+
+
+@end

Added: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISOAuthHttpResponse.h
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISOAuthHttpResponse.h?rev=1795295&view=auto
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISOAuthHttpResponse.h 
(added)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISOAuthHttpResponse.h 
Tue May 16 10:33:32 2017
@@ -0,0 +1,26 @@
+/*
+  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 "CMISHttpResponse.h"
+
+@interface CMISOAuthHttpResponse : CMISHttpResponse
+
++ (NSDictionary *)parseResponse:(CMISHttpResponse *)httpResponse 
error:(NSError **)outError;
+
+@end

Added: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISOAuthHttpResponse.m
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISOAuthHttpResponse.m?rev=1795295&view=auto
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISOAuthHttpResponse.m 
(added)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISOAuthHttpResponse.m 
Tue May 16 10:33:32 2017
@@ -0,0 +1,58 @@
+/*
+  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 "CMISOAuthHttpResponse.h"
+#import "CMISErrors.h"
+
+@implementation CMISOAuthHttpResponse
+
+- (NSString*)exception
+{
+    NSString *exception = [self responseValueForKey:@"error"];
+    return exception;
+}
+
+
+- (NSString*)errorMessage
+{
+    NSString *message = [self responseValueForKey:@"error_description"];
+    return message;
+}
+
++ (NSDictionary *)parseResponse:(CMISHttpResponse *)httpResponse 
error:(NSError **)outError
+{
+    NSDictionary *jsonDictionary = nil;
+    
+    NSError *serialisationError = nil;
+    id jsonResponse = [NSJSONSerialization 
JSONObjectWithData:httpResponse.data options:0 error:&serialisationError];
+    
+    if (!serialisationError) {
+        if ([jsonResponse isKindOfClass:NSDictionary.class]) {
+            jsonDictionary = (NSDictionary *)jsonResponse;
+        } else {
+            if (outError != NULL) *outError = [CMISErrors 
createCMISErrorWithCode:kCMISErrorCodeRuntime detailedDescription:@"Invalid 
response!"];
+        }
+    } else {
+        if (outError != NULL) *outError = [CMISErrors 
cmisError:serialisationError cmisErrorCode:kCMISErrorCodeRuntime];
+    }
+    
+    return jsonDictionary;
+}
+
+@end

Modified: 
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISObjectConverter.h
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISObjectConverter.h?rev=1795295&r1=1795294&r2=1795295&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISObjectConverter.h 
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISObjectConverter.h Tue 
May 16 10:33:32 2017
@@ -22,6 +22,9 @@
 #import "CMISObjectData.h"
 
 @class CMISSession;
+@class CMISChangeEvents;
+@class CMISChangeEvent;
+@class CMISObjectList;
 
 @interface CMISObjectConverter : NSObject
 
@@ -43,4 +46,8 @@
  */
 + (NSArray *)convertExtensions:(NSDictionary *)source cmisKeys:(NSSet 
*)cmisKeys;
 
++ (CMISChangeEvents *)convertChangeEvents:(NSString *)changeLogToken 
objectList:(CMISObjectList *)objectList;
+
++ (CMISChangeEvent *)convertChangeEvent:(CMISObjectData *)objectData;
+
 @end

Modified: 
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISObjectConverter.m
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISObjectConverter.m?rev=1795295&r1=1795294&r2=1795295&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISObjectConverter.m 
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISObjectConverter.m Tue 
May 16 10:33:32 2017
@@ -27,6 +27,14 @@
 #import "CMISDateUtil.h"
 #import "CMISConstants.h"
 #import "CMISDictionaryUtil.h"
+#import "CMISChangeEvents.h"
+#import "CMISChangeEvent.h"
+#import "CMISObjectList.h"
+#import "CMISObjectData.h"
+#import "CMISChangeEventInfo.h"
+#import "CMISEnums.h"
+#import "CMISPolicyIdList.h"
+#import "CMISItem.h"
 
 @interface CMISObjectConverter ()
 @property (nonatomic, weak) CMISSession *session;
@@ -53,11 +61,19 @@
         object = [[CMISDocument alloc] initWithObjectData:objectData 
session:self.session];
     } else if (objectData.baseType == CMISBaseTypeFolder) {
         object = [[CMISFolder alloc] initWithObjectData:objectData 
session:self.session];
+    } else if (objectData.baseType == CMISBaseTypeItem) {
+        object = [[CMISItem alloc] initWithObjectData:objectData 
session:self.session];
     }
     
-    [object fetchTypeDefinitionWithCompletionBlock:^(NSError *error) {
-        completionBlock(object, error);
-    }];
+    if (object) {
+        [object fetchTypeDefinitionWithCompletionBlock:^(NSError *error) {
+            completionBlock(object, error);
+        }];    
+    } else {
+        NSError *error = [CMISErrors 
createCMISErrorWithCode:kCMISErrorCodeNotSupported
+                                         detailedDescription:[NSString 
stringWithFormat:@"Base type '%ld' not supported", (long)objectData.baseType]];
+        completionBlock(nil, error);
+    }
 }
 
 
@@ -542,5 +558,59 @@
     return extensions;
 }
 
++ (CMISChangeEvents *)convertChangeEvents:(NSString *)changeLogToken 
objectList:(CMISObjectList *)objectList
+{
+    if (objectList == nil) {
+        return nil;
+    }
+    
+    NSMutableArray *events = [NSMutableArray new];
+    for (CMISObjectData *objectData in objectList.objects) {
+        CMISChangeEvent *changeEvent = [self convertChangeEvent:objectData];
+        [events addObject:changeEvent];
+    }
+    
+    CMISChangeEvents *changeEvents = [CMISChangeEvents new];
+    changeEvents.hasMoreItems = objectList.hasMoreItems;
+    changeEvents.numItems = objectList.numItems;
+    changeEvents.changeEvents = [events copy];
+    changeEvents.latestChangeLogToken = changeLogToken;
+    
+    return changeEvents;
+}
+
++ (CMISChangeEvent *)convertChangeEvent:(CMISObjectData *)objectData
+{
+    CMISChangeEvent *changeEvent = [CMISChangeEvent new];
+    NSMutableDictionary *properties = nil;
+    
+    if (objectData.changeEventInfo) {
+        changeEvent.changeType = objectData.changeEventInfo.changeType;
+        changeEvent.changeTime = objectData.changeEventInfo.changeTime;
+    }
+    
+    if (objectData.properties.propertyList) {
+        properties = [NSMutableDictionary new];
+        
+        for (CMISPropertyData *property in objectData.properties.propertyList) 
{
+            [properties setObject:property.values forKey:property.identifier];
+        }
+        
+        changeEvent.properties = [properties copy];
+        
+        NSArray *objectIdList = [properties 
objectForKey:kCMISPropertyObjectId];
+        if (objectIdList.count > 0) {
+            changeEvent.objectId = objectIdList[0];
+        }
+        
+        changeEvent.policyIds = objectData.policyIds.policyIds;
+        
+        changeEvent.acl = objectData.acl;
+    }
+    
+    
+    
+    return changeEvent;
+}
 
 @end

Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISReachability.m
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISReachability.m?rev=1795295&r1=1795294&r2=1795295&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISReachability.m 
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISReachability.m Tue 
May 16 10:33:32 2017
@@ -74,8 +74,9 @@ void handleFlags(SCNetworkReachabilityFl
 #endif
     
     BOOL connected = !(flags & kSCNetworkReachabilityFlagsConnectionRequired);
+    BOOL connectionOnDemand = (flags & 
kSCNetworkReachabilityFlagsConnectionOnDemand); // connectionOnDemand is true 
when using e.g. per App-VPN
     
-    if (reachable && connected) {
+    if (reachable && (connected || connectionOnDemand)) {
         networkReachability->_networkConnection = YES;
     }
     else {
@@ -89,21 +90,24 @@ void handleFlags(SCNetworkReachabilityFl
 
 + (instancetype)reachabilityWithAddress:(const struct sockaddr_in 
*)hostAddress;
 {
-    CMISReachability *returnReachability = NULL;
-    
+    CMISReachability *returnReachability = nil;
+    // deactivated static analyzer because of false positive: release of 
reachabilityRef is done in dealloc method, however compiler does not recognize 
this
+#ifndef __clang_analyzer__
     SCNetworkReachabilityRef reachability = 
SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct 
sockaddr *)hostAddress);
     
     if (reachability != NULL) {
         returnReachability = [[self alloc] init];
-        if (returnReachability != NULL) {
+        if (returnReachability != nil) {
             returnReachability.networkReachabilityRef = reachability;
             [returnReachability startNotifier];
+        } else {
+            CFRelease(reachability);
         }
     }
     else {
         CMISLogWarning(@"Failed to create reachability reference for address 
%@", hostAddress);
     }
-    
+#endif
     return returnReachability;
 }
 

Added: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISURLSessionUtil.h
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISURLSessionUtil.h?rev=1795295&view=auto
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISURLSessionUtil.h 
(added)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISURLSessionUtil.h Tue 
May 16 10:33:32 2017
@@ -0,0 +1,28 @@
+/*
+  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>
+
+@class CMISBindingSession;
+
+@interface CMISURLSessionUtil : NSObject
+
++ (NSURLSession *)internalUrlSessionWithParameters:(CMISBindingSession 
*)session delegate:(id <NSURLSessionDelegate>)delegate;
+
+@end

Added: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISURLSessionUtil.m
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISURLSessionUtil.m?rev=1795295&view=auto
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISURLSessionUtil.m 
(added)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISURLSessionUtil.m Tue 
May 16 10:33:32 2017
@@ -0,0 +1,56 @@
+/*
+  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 "CMISURLSessionUtil.h"
+#import "CMISBindingSession.h"
+#import "CMISConstants.h"
+#import "CMISLog.h"
+
+@implementation CMISURLSessionUtil
+
++ (NSURLSession *)internalUrlSessionWithParameters:(CMISBindingSession 
*)session delegate:(id <NSURLSessionDelegate>)delegate
+{
+    // determine the type of session configuration to create
+    NSURLSessionConfiguration *sessionConfiguration = nil;
+    id useBackgroundSession = [session 
objectForKey:kCMISSessionParameterUseBackgroundNetworkSession];
+    if (useBackgroundSession && [useBackgroundSession boolValue]) {
+        // get session and container identifiers from session
+        NSString *backgroundId = [session 
objectForKey:kCMISSessionParameterBackgroundNetworkSessionId
+                                       
defaultValue:kCMISDefaultBackgroundNetworkSessionId];
+        NSString *containerId = [session 
objectForKey:kCMISSessionParameterBackgroundNetworkSessionSharedContainerId
+                                      
defaultValue:kCMISDefaultBackgroundNetworkSessionSharedContainerId];
+        
+        // use the background session configuration, cache settings and 
timeout will be provided by the request object
+        sessionConfiguration = [NSURLSessionConfiguration 
backgroundSessionConfigurationWithIdentifier:backgroundId];
+        sessionConfiguration.sharedContainerIdentifier = containerId;
+        
+        CMISLogDebug(@"Using background network session with identifier '%@' 
and shared container '%@'",
+                     backgroundId, containerId);
+    }
+    else {
+        // use the default session configuration, cache settings and timeout 
will be provided by the request object
+        sessionConfiguration = [NSURLSessionConfiguration 
defaultSessionConfiguration];
+    }
+    
+    //TODO: do we have a memory leak? need to call invalidateAndCancel or 
resetWithCompletionHandler when done, see also docu from 
sessionWithConfiguration:delegate:delegateQueue: method
+    // create session
+    return [NSURLSession sessionWithConfiguration:sessionConfiguration 
delegate:delegate delegateQueue:nil];
+}
+
+@end

Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISURLUtil.m
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISURLUtil.m?rev=1795295&r1=1795294&r2=1795295&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISURLUtil.m (original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISURLUtil.m Tue May 16 
10:33:32 2017
@@ -19,6 +19,7 @@
  
 #import "CMISURLUtil.h"
 #import "CMISConstants.h"
+#import "CMISLog.h"
 
 NSString * const kCMISRFC7232Reserved = @";?:@&=+$,[]";
 NSString * const kCMISRFC3986Reserved = @"!*'();:@&=+$,/?%#[]";
@@ -71,14 +72,15 @@ NSString * const kCMISRFC3986Reserved =
         path = [path substringFromIndex:1];
     }
     
-    NSURL *url = [[NSURL URLWithString:urlString] 
URLByAppendingPathComponent:path];
-
+    NSURL *url = [NSURL URLWithString:urlString];
+    if (path.length > 0) {
+        url = [url URLByAppendingPathComponent:path];
+    }
+    
     // quote some additional reserved characters
-    path = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
-                                                                     
(CFStringRef)url.path,
-                                                                     NULL,
-                                                                     
(CFStringRef)kCMISRFC7232Reserved,
-                                                                     
kCFStringEncodingUTF8));
+    NSMutableCharacterSet *characterSet = [[NSCharacterSet 
URLQueryAllowedCharacterSet] mutableCopy];
+    [characterSet removeCharactersInString:kCMISRFC7232Reserved];
+    path = [url.path 
stringByAddingPercentEncodingWithAllowedCharacters:characterSet];
     
     return [self replacePathInUrl:[url absoluteString] withPath:path];
 }
@@ -90,11 +92,10 @@ NSString * const kCMISRFC3986Reserved =
 
 + (NSString *)encodeUrlParameterValue:(NSString *)value
 {
-    NSString *encodedValue = 
CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
-                                                                               
        (CFStringRef)value,
-                                                                               
        NULL,
-                                                                               
        (CFStringRef)kCMISRFC3986Reserved,
-                                                                               
        kCFStringEncodingUTF8));
+    NSMutableCharacterSet *characterSet = [[NSCharacterSet 
URLQueryAllowedCharacterSet] mutableCopy];
+    [characterSet removeCharactersInString:kCMISRFC3986Reserved];
+    NSString *encodedValue = [value 
stringByAddingPercentEncodingWithAllowedCharacters:characterSet];
+    
     return encodedValue;
 }
 
@@ -130,4 +131,4 @@ NSString * const kCMISRFC3986Reserved =
     return serverUrl;
 }
 
-@end
\ No newline at end of file
+@end

Modified: chemistry/objectivecmis/trunk/ObjectiveCMISTests/ObjectiveCMISTests.m
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMISTests/ObjectiveCMISTests.m?rev=1795295&r1=1795294&r2=1795295&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMISTests/ObjectiveCMISTests.m 
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMISTests/ObjectiveCMISTests.m Tue 
May 16 10:33:32 2017
@@ -2711,4 +2711,77 @@
     XCTAssertEqualObjects(@"SELECT * FROM cmis:document WHERE abc:dateTime = 
TIMESTAMP '2012-02-02T03:04:05.000Z'", [st queryString], @"wrong encoded query 
statement");
 }
 
+- (void)testAuthenticateHeaderParameters {
+    NSDictionary *challenges = nil;
+    
+    challenges = [CMISMimeHelper challengesFromAuthenticateHeader:nil];
+    XCTAssertNil(challenges);
+    
+    challenges = [CMISMimeHelper challengesFromAuthenticateHeader:@""];
+    XCTAssertNil(challenges);
+    
+    challenges = [CMISMimeHelper challengesFromAuthenticateHeader:@"Basic"];
+    XCTAssertNotNil(challenges);
+    XCTAssertTrue(challenges[@"basic"]);
+    XCTAssertTrue([challenges[@"basic"] count] == 0);
+    
+    challenges = [CMISMimeHelper challengesFromAuthenticateHeader:@"Basic 
realm=\"example\""];
+    XCTAssertNotNil(challenges);
+    XCTAssertTrue(challenges[@"basic"]);
+    XCTAssertEqualObjects(@"example", challenges[@"basic"][@"realm"]);
+    
+    challenges = [CMISMimeHelper challengesFromAuthenticateHeader:@"Basic 
realm= \"example\" "];
+    XCTAssertNotNil(challenges);
+    XCTAssertTrue(challenges[@"basic"]);
+    XCTAssertEqualObjects(@"example", challenges[@"basic"][@"realm"]);
+    
+    challenges = [CMISMimeHelper challengesFromAuthenticateHeader:@"Basic 
realm=example"];
+    XCTAssertNotNil(challenges);
+    XCTAssertTrue(challenges[@"basic"]);
+    XCTAssertEqualObjects(@"example", challenges[@"basic"][@"realm"]);
+    
+    challenges = [CMISMimeHelper challengesFromAuthenticateHeader:@"Basic 
realm=\"example\",charset=\"UTF-8\""];
+    XCTAssertNotNil(challenges);
+    XCTAssertTrue(challenges[@"basic"]);
+    XCTAssertEqualObjects(@"example", challenges[@"basic"][@"realm"]);
+    XCTAssertEqualObjects(@"UTF-8", challenges[@"basic"][@"charset"]);
+    
+    challenges = [CMISMimeHelper challengesFromAuthenticateHeader:@"Bearer 
realm=\"example\", error=\"invalid_token\""];
+    XCTAssertNotNil(challenges);
+    XCTAssertTrue(challenges[@"bearer"]);
+    XCTAssertEqualObjects(@"example", challenges[@"bearer"][@"realm"]);
+    XCTAssertEqualObjects(@"invalid_token", challenges[@"bearer"][@"error"]);
+    
+    challenges = [CMISMimeHelper challengesFromAuthenticateHeader:@"Bearer 
realm=\"example\", error=invalid_token"];
+    XCTAssertNotNil(challenges);
+    XCTAssertEqualObjects(@"example", challenges[@"bearer"][@"realm"]);
+    XCTAssertEqualObjects(@"invalid_token", challenges[@"bearer"][@"error"]);
+    
+    challenges = [CMISMimeHelper challengesFromAuthenticateHeader:@"Bearer 
realm=\"example\", error=\"invalid_token\", error_description=\"The access 
token expired\""];
+    XCTAssertNotNil(challenges);
+    XCTAssertEqualObjects(@"example", challenges[@"bearer"][@"realm"]);
+    XCTAssertEqualObjects(@"invalid_token", challenges[@"bearer"][@"error"]);
+    XCTAssertEqualObjects(@"The access token expired", 
challenges[@"bearer"][@"error_description"]);
+    
+    challenges = [CMISMimeHelper challengesFromAuthenticateHeader:@"Bearer 
realm=\"example\",error_description=\"It's expired, really!\", 
error=\"invalid_token\","];
+    XCTAssertNotNil(challenges);
+    XCTAssertEqualObjects(@"example", challenges[@"bearer"][@"realm"]);
+    XCTAssertEqualObjects(@"invalid_token", challenges[@"bearer"][@"error"]);
+    XCTAssertEqualObjects(@"It's expired, really!", 
challenges[@"bearer"][@"error_description"]);
+    
+    challenges = [CMISMimeHelper challengesFromAuthenticateHeader:@"Newauth 
realm=\"apps\", type=1, title=\"Login to \\\"apps\\\"\", Basic 
realm=\"simple\""];
+    XCTAssertNotNil(challenges);
+    XCTAssertEqualObjects(@"apps", challenges[@"newauth"][@"realm"]);
+    XCTAssertEqualObjects(@"1", challenges[@"newauth"][@"type"]);
+    XCTAssertEqualObjects(@"Login to \"apps\"", 
challenges[@"newauth"][@"title"]);
+    XCTAssertEqualObjects(@"simple", challenges[@"basic"][@"realm"]);
+    
+    challenges = [CMISMimeHelper challengesFromAuthenticateHeader:@"a1, a2 ,a3 
,a4"];
+    XCTAssertNotNil(challenges);
+    XCTAssertTrue(challenges[@"a1"]);
+    XCTAssertTrue(challenges[@"a2"]);
+    XCTAssertTrue(challenges[@"a3"]);
+    XCTAssertTrue(challenges[@"a4"]);
+}
+
 @end


Reply via email to