GBA-8-19/Pods/GoogleAPIClientForREST/Source/Objects/GTLRQuery.m
2024-06-14 17:15:51 +08:00

314 lines
10 KiB
Objective-C

/* Copyright (c) 2011 Google Inc.
*
* Licensed 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.
*/
#if !__has_feature(objc_arc)
#error "This file needs to be compiled with ARC enabled."
#endif
#include <objc/runtime.h>
#import "GTLRQuery.h"
#import "GTLRRuntimeCommon.h"
#import "GTLRService.h"
#import "GTLRUtilities.h"
@interface GTLRQuery () <GTLRRuntimeCommon>
@end
@implementation GTLRQuery {
NSMutableDictionary *_childCache;
GTLRServiceExecutionParameters *_executionParameters;
}
@synthesize additionalURLQueryParameters = _additionalURLQueryParameters,
additionalHTTPHeaders = _additionalHTTPHeaders,
bodyObject = _bodyObject,
completionBlock = _completionBlock,
downloadAsDataObjectType = _downloadAsDataObjectType,
expectedObjectClass = _expectedObjectClass,
httpMethod = _httpMethod,
JSON = _json,
loggingName = _loggingName,
pathParameterNames = _pathParameterNames,
pathURITemplate = _pathURITemplate,
queryInvalid = _queryInvalid,
requestID = _requestID,
resumableUploadPathURITemplateOverride = _resumableUploadPathURITemplateOverride,
shouldSkipAuthorization = _shouldSkipAuthorization,
simpleUploadPathURITemplateOverride = _simpleUploadPathURITemplateOverride,
uploadParameters = _uploadParameters,
useMediaDownloadService = _useMediaDownloadService;
#if DEBUG
- (instancetype)init {
[self doesNotRecognizeSelector:_cmd];
self = nil;
return self;
}
#endif
- (instancetype)initWithPathURITemplate:(NSString *)pathURITemplate
HTTPMethod:(nullable NSString *)httpMethod
pathParameterNames:(nullable NSArray<NSString *> *)pathParameterNames {
self = [super init];
if (self) {
_requestID = [[self class] nextRequestID];
_pathURITemplate = [pathURITemplate copy];
_httpMethod = [httpMethod copy];
_pathParameterNames = [pathParameterNames copy];
if (_pathURITemplate.length == 0) {
self = nil;
}
}
return self;
}
- (id)copyWithZone:(NSZone *)zone {
GTLR_DEBUG_ASSERT(!self.queryInvalid, @"Cannot copy an executed query: %@", self);
GTLRQuery *query =
[[[self class] allocWithZone:zone] initWithPathURITemplate:self.pathURITemplate
HTTPMethod:self.httpMethod
pathParameterNames:self.pathParameterNames];
if (_json.count > 0) {
// Deep copy the parameters
CFPropertyListRef ref = CFPropertyListCreateDeepCopy(kCFAllocatorDefault,
(__bridge CFPropertyListRef)(_json),
kCFPropertyListMutableContainers);
query.JSON = CFBridgingRelease(ref);
}
// Using the executionParameters ivar avoids creating the object.
query.executionParameters = self.executionParameters;
// Copied in the same order as synthesized above.
query.additionalHTTPHeaders = self.additionalHTTPHeaders;
query.additionalURLQueryParameters = self.additionalURLQueryParameters;
query.bodyObject = self.bodyObject;
query.completionBlock = self.completionBlock;
query.downloadAsDataObjectType = self.downloadAsDataObjectType;
query.expectedObjectClass = self.expectedObjectClass;
// http method passed to init above.
// JSON copied above.
query.loggingName = self.loggingName;
// pathParameterNames passed to init above.
// pathURITemplate passed to init above.
query.queryInvalid = self.queryInvalid;
query.requestID = self.requestID;
query.resumableUploadPathURITemplateOverride = self.resumableUploadPathURITemplateOverride;
query.shouldSkipAuthorization = self.shouldSkipAuthorization;
query.simpleUploadPathURITemplateOverride = self.simpleUploadPathURITemplateOverride;
query.uploadParameters = self.uploadParameters;
query.useMediaDownloadService = self.useMediaDownloadService;
return query;
}
#if DEBUG
- (NSString *)description {
NSArray *keys = self.JSON.allKeys;
NSArray *params = [keys sortedArrayUsingSelector:@selector(compare:)];
NSString *paramsSummary = @"";
if (params.count > 0) {
paramsSummary = [NSString stringWithFormat:@" params:(%@)",
[params componentsJoinedByString:@","]];
}
NSString *invalidStr = @"";
if (self.queryInvalid) {
invalidStr = @" [callbacks released]";
}
keys = self.additionalURLQueryParameters.allKeys;
NSArray *urlQParams = [keys sortedArrayUsingSelector:@selector(compare:)];
NSString *urlQParamsSummary = @"";
if (urlQParams.count > 0) {
urlQParamsSummary = [NSString stringWithFormat:@" urlQParams:(%@)",
[urlQParams componentsJoinedByString:@","]];
}
GTLRObject *bodyObj = self.bodyObject;
NSString *bodyObjSummary = @"";
if (bodyObj != nil) {
bodyObjSummary = [NSString stringWithFormat:@" bodyObject:%@", [bodyObj class]];
}
NSString *uploadStr = @"";
GTLRUploadParameters *uploadParams = self.uploadParameters;
if (uploadParams) {
uploadStr = [NSString stringWithFormat:@" %@", uploadParams];
}
NSString *httpMethod = self.httpMethod;
if (httpMethod == nil) {
httpMethod = @"GET";
}
NSString *dataObjectType = self.downloadAsDataObjectType;
NSString *downloadStr = @"";
if (dataObjectType.length > 0) {
downloadStr =
[NSString stringWithFormat:@" downloadDataAs:%@", dataObjectType];
}
return [NSString stringWithFormat:@"%@ %p:%@%@ {%@ pathTemplate:%@%@%@%@%@}",
[self class], self, invalidStr, downloadStr,
httpMethod, self.pathURITemplate,
paramsSummary, urlQParamsSummary, bodyObjSummary, uploadStr];
}
#endif // DEBUG
- (BOOL)isBatchQuery {
return NO;
}
- (void)invalidateQuery {
self.queryInvalid = YES;
self.completionBlock = nil;
self.executionParameters = nil;
}
- (GTLRServiceExecutionParameters *)executionParameters {
@synchronized(self) {
if (!_executionParameters) {
_executionParameters = [[GTLRServiceExecutionParameters alloc] init];
}
return _executionParameters;
}
}
- (void)setExecutionParameters:(nullable GTLRServiceExecutionParameters *)executionParameters {
@synchronized(self) {
_executionParameters = executionParameters;
}
}
- (BOOL)hasExecutionParameters {
return self.executionParameters.hasParameters;
}
+ (NSString *)nextRequestID {
static NSUInteger lastRequestID = 0;
NSString *result;
@synchronized([GTLRQuery class]) {
++lastRequestID;
result = [NSString stringWithFormat:@"gtlr_%lu", (unsigned long)lastRequestID];
}
return result;
}
#pragma mark GTLRRuntimeCommon Support
- (void)setJSONValue:(id)obj forKey:(NSString *)key {
NSMutableDictionary *dict = self.JSON;
if (dict == nil && obj != nil) {
dict = [NSMutableDictionary dictionaryWithCapacity:1];
self.JSON = dict;
}
[dict setValue:obj forKey:key];
}
- (id)JSONValueForKey:(NSString *)key {
id obj = [self.JSON objectForKey:key];
return obj;
}
// There is no property for _childCache as there shouldn't be KVC/KVO
// support for it, since it's an implementation detail.
- (void)setCacheChild:(id)obj forKey:(NSString *)key {
if (_childCache == nil && obj != nil) {
_childCache = [[NSMutableDictionary alloc] initWithObjectsAndKeys:obj, key, nil];
} else {
[_childCache setValue:obj forKey:key];
}
}
- (id)cacheChildForKey:(NSString *)key {
id obj = [_childCache objectForKey:key];
return obj;
}
#pragma mark Methods for Subclasses to Override
+ (NSDictionary<NSString *, NSString *> *)parameterNameMap {
return nil;
}
+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap {
return nil;
}
#pragma mark Runtime Utilities
static NSMutableDictionary *gQueryParameterNameMapCache = nil;
static NSMutableDictionary *gQueryArrayPropertyToClassMapCache = nil;
+ (void)initialize {
// Note that +initialize is guaranteed by the runtime to be called in a thread-safe manner.
if (gQueryParameterNameMapCache == nil) {
gQueryParameterNameMapCache = [[NSMutableDictionary alloc] init];
}
if (gQueryArrayPropertyToClassMapCache == nil) {
gQueryArrayPropertyToClassMapCache = [[NSMutableDictionary alloc] init];
}
}
+ (NSDictionary *)propertyToJSONKeyMapForClass:(Class<GTLRRuntimeCommon>)aClass {
NSDictionary *resultMap =
[GTLRRuntimeCommon mergedClassDictionaryForSelector:@selector(parameterNameMap)
startClass:aClass
ancestorClass:[GTLRQuery class]
cache:gQueryParameterNameMapCache];
return resultMap;
}
+ (NSDictionary *)arrayPropertyToClassMapForClass:(Class<GTLRRuntimeCommon>)aClass {
NSDictionary *resultMap =
[GTLRRuntimeCommon mergedClassDictionaryForSelector:@selector(arrayPropertyToClassMap)
startClass:aClass
ancestorClass:[GTLRQuery class]
cache:gQueryArrayPropertyToClassMapCache];
return resultMap;
}
#pragma mark Runtime Support
- (id<GTLRObjectClassResolver>)objectClassResolver {
// Stub method just needed for RuntimeCommon.
return nil;
}
+ (Class<GTLRRuntimeCommon>)ancestorClass {
return [GTLRQuery class];
}
+ (BOOL)resolveInstanceMethod:(SEL)sel {
BOOL resolved = [GTLRRuntimeCommon resolveInstanceMethod:sel onClass:self];
if (resolved) return YES;
return [super resolveInstanceMethod:sel];
}
@end
@implementation GTLRQueryCollectionImpl
@dynamic pageToken;
@end