123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- /* 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.
- */
- #include <objc/runtime.h>
- //#import <GoogleAPIClientForREST/GTLRQuery.h>
- //#import <GoogleAPIClientForREST/GTLRRuntimeCommon.h>
- //#import <GoogleAPIClientForREST/GTLRService.h>
- //#import <GoogleAPIClientForREST/GTLRUtilities.h>
- #import "GTLRQuery.h"
- #import "GTLRRuntimeCommon.h"
- #import "GTLRService.h"
- #import "GTLRUtilities.h"
- #import "GTLRDefines.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
|