Skip to content

Commit

Permalink
Merge branch 'dulaccc-prepare-support-for-bitmasks-methods' into deve…
Browse files Browse the repository at this point in the history
…lopment
  • Loading branch information
Blake Watters committed Jul 2, 2013
2 parents 2a7fc01 + eaedf62 commit c73ac51
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 41 deletions.
7 changes: 4 additions & 3 deletions Code/Network/RKRoute.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@
@param name A unique identifying name for the route.
@param pathPattern A SOCKit pattern describing the format of URL paths generated from the route.
@param method The request method of the route.
@param method The request method of the route. The method given must specify a single HTTP method to be used for requests using the route.
@return A new named route object with the given name, path pattern and request method.
@raise NSInvalidArgumentException Raised if the given HTTP request method is not an exact match of the RKRequestMethod enum
*/
+ (instancetype)routeWithName:(NSString *)name pathPattern:(NSString *)pathPattern method:(RKRequestMethod)method;

Expand All @@ -55,7 +56,7 @@
@param objectClass The class that is represented by the route.
@param pathPattern A SOCKit pattern describing the format of URL paths generated from the route.
@param method The request method of the route.
@param method The request method of the route. More than one method may be specified via a bitwise OR.
@return A new class route object with the given object class, path pattern and request method.
*/
+ (instancetype)routeWithClass:(Class)objectClass pathPattern:(NSString *)pathPattern method:(RKRequestMethod)method;
Expand All @@ -66,7 +67,7 @@
@param name The name of the relationship represented by the route.
@param objectClass The class containing the relationship represented by the route.
@param pathPattern A SOCKit pattern describing the format of URL paths generated from the route.
@param method The request method of the route.
@param method The request method of the route. More than one method may be specified via a bitwise OR.
@return A new class route object with the given object class, path pattern and request method.
*/
+ (instancetype)routeWithRelationshipName:(NSString *)name objectClass:(Class)objectClass pathPattern:(NSString *)pathPattern method:(RKRequestMethod)method;
Expand Down
21 changes: 18 additions & 3 deletions Code/Network/RKRoute.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@

#import "RKRoute.h"

static NSString *RKStringDescribingRequestMethod(RKRequestMethod method)
{
if (method == RKRequestMethodAny) return @"*";
NSMutableArray *methods = [NSMutableArray array];
if (method & RKRequestMethodGET) [methods addObject:@"GET"];
if (method & RKRequestMethodPOST) [methods addObject:@"POST"];
if (method & RKRequestMethodPUT) [methods addObject:@"PUT"];
if (method & RKRequestMethodDELETE) [methods addObject:@"DELETE"];
if (method & RKRequestMethodHEAD) [methods addObject:@"HEAD"];
if (method & RKRequestMethodPATCH) [methods addObject:@"PATCH"];
if (method & RKRequestMethodOPTIONS) [methods addObject:@"OPTIONS"];
return [NSString stringWithFormat:@"(%@)", [methods componentsJoinedByString:@"|"]];
}

@interface RKRoute ()
@property (nonatomic, strong, readwrite) NSString *name;
@property (nonatomic, strong, readwrite) Class objectClass;
Expand All @@ -42,6 +56,7 @@ + (instancetype)routeWithName:(NSString *)name pathPattern:(NSString *)pathPatte
{
NSParameterAssert(name);
NSParameterAssert(pathPattern);
if (!RKIsSpecificRequestMethod(method)) [NSException raise:NSInvalidArgumentException format:@"The `method` parameter must specify a single, non-ambiguous HTTP method. Bitmask values and `RKRequestMethodAny` are invalid arguments."];
RKNamedRoute *route = [RKNamedRoute new];
route.name = name;
route.pathPattern = pathPattern;
Expand Down Expand Up @@ -115,7 +130,7 @@ - (BOOL)isNamedRoute
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p name=%@ method=%@ pathPattern=%@>",
NSStringFromClass([self class]), self, self.name, RKStringFromRequestMethod(self.method), self.pathPattern];
NSStringFromClass([self class]), self, self.name, RKStringDescribingRequestMethod(self.method), self.pathPattern];
}

@end
Expand All @@ -131,7 +146,7 @@ - (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p objectClass=%@ method=%@ pathPattern=%@>",
NSStringFromClass([self class]), self, NSStringFromClass(self.objectClass),
RKStringFromRequestMethod(self.method), self.pathPattern];
RKStringDescribingRequestMethod(self.method), self.pathPattern];
}

@end
Expand All @@ -147,7 +162,7 @@ - (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p relationshipName=%@ objectClass=%@ method=%@ pathPattern=%@>",
NSStringFromClass([self class]), self, self.name, NSStringFromClass(self.objectClass),
RKStringFromRequestMethod(self.method), self.pathPattern];
RKStringDescribingRequestMethod(self.method), self.pathPattern];
}

@end
3 changes: 0 additions & 3 deletions Code/Network/RKRouteSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@

#import "RKRoute.h"

// Wildcard matches on objects
extern RKRequestMethod const RKRequestMethodAny;

/**
The `RKRouteSet` class provides for the storage and retrieval of `RKRoute` objects. Route objects are added and removed the route set to manipulate the routing table of the application.
Expand Down
8 changes: 3 additions & 5 deletions Code/Network/RKRouteSet.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
#import "RKRouteSet.h"
#import "RKPathMatcher.h"

RKRequestMethod const RKRequestMethodAny = RKRequestMethodInvalid;

@interface RKRouteSet ()

@property (nonatomic, strong) NSMutableArray *routes;
Expand Down Expand Up @@ -84,7 +82,7 @@ - (void)addRoute:(RKRoute *)route
NSAssert(![route isNamedRoute] || [self routeForName:route.name] == nil, @"Cannot add a route with the same name as an existing route.");
if ([route isClassRoute]) {
RKRoute *existingRoute = [self routeForClass:route.objectClass method:route.method];
NSAssert(existingRoute == nil || (existingRoute.method == RKRequestMethodAny && route.method != RKRequestMethodAny), @"Cannot add a route with the same class and method as an existing route.");
NSAssert(existingRoute == nil || (existingRoute.method == RKRequestMethodAny && route.method != RKRequestMethodAny) || (route.method == RKRequestMethodAny && existingRoute.method != RKRequestMethodAny), @"Cannot add a route with the same class and method as an existing route.");
} else if ([route isRelationshipRoute]) {
NSArray *routes = [self routesForRelationship:route.name ofClass:route.objectClass];
for (RKRoute *existingRoute in routes) {
Expand Down Expand Up @@ -128,7 +126,7 @@ - (RKRoute *)routeForClass:(Class)objectClass method:(RKRequestMethod)method
{
// Check for an exact match
for (RKRoute *route in [self classRoutes]) {
if ([route.objectClass isEqual:objectClass] && route.method == method) {
if ([route.objectClass isEqual:objectClass] && (route.method != RKRequestMethodAny && route.method & method)) {
return route;
}
}
Expand Down Expand Up @@ -195,7 +193,7 @@ - (RKRoute *)routeForObject:(id)object method:(RKRequestMethod)method
RKRoute *wildcardRoute = nil;
for (RKRoute *route in routes) {
if (route.method == RKRequestMethodAny) wildcardRoute = route;
if (route.method == method) return route;
if (route.method & method) return route;
}

if (wildcardRoute) return wildcardRoute;
Expand Down
35 changes: 24 additions & 11 deletions Code/ObjectMapping/RKHTTPUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,36 @@
/**
HTTP methods for requests
*/
typedef enum RKRequestMethod {
RKRequestMethodInvalid = -1,
RKRequestMethodGET,
RKRequestMethodPOST,
RKRequestMethodPUT,
RKRequestMethodDELETE,
RKRequestMethodHEAD,
RKRequestMethodPATCH,
RKRequestMethodOPTIONS
} RKRequestMethod; // RKHTTPMethod? RKStringFromHTTPMethod... RKHTTPMethodFromString
typedef NS_OPTIONS(NSInteger, RKRequestMethod) {
RKRequestMethodGET = 1 << 0,
RKRequestMethodPOST = 1 << 1,
RKRequestMethodPUT = 1 << 2,
RKRequestMethodDELETE = 1 << 3,
RKRequestMethodHEAD = 1 << 4,
RKRequestMethodPATCH = 1 << 5,
RKRequestMethodOPTIONS = 1 << 6,
RKRequestMethodAny = (RKRequestMethodGET |
RKRequestMethodPOST |
RKRequestMethodPUT |
RKRequestMethodDELETE |
RKRequestMethodHEAD |
RKRequestMethodPATCH |
RKRequestMethodOPTIONS)
};

/**
Returns YES if the given HTTP request method is an exact match of the RKRequestMethod enum, and NO if it's a bit mask combination.
*/
BOOL RKIsSpecificRequestMethod(RKRequestMethod method);

/**
Returns the corresponding string for value for a given HTTP request method.
For example, given `RKRequestMethodGET` would return `@"GET"`.
@param method The request method to return the corresponding string value for. The given request method must be specific.
*/
NSString * RKStringFromRequestMethod(RKRequestMethod);
NSString *RKStringFromRequestMethod(RKRequestMethod method);

/**
Returns the corresponding request method value for a given string.
Expand Down
10 changes: 9 additions & 1 deletion Code/ObjectMapping/RKHTTPUtilities.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ NSRange RKStatusCodeRangeForClass(RKStatusCodeClass statusCodeClass)
return cacheableStatusCodes;
}

BOOL RKIsSpecificRequestMethod(RKRequestMethod method)
{
// check for a power of two
return !(method & (method - 1));
}

NSString *RKStringFromRequestMethod(RKRequestMethod method)
{
switch (method) {
Expand All @@ -70,7 +76,9 @@ RKRequestMethod RKRequestMethodFromString(NSString *methodName)
else if ([methodName isEqualToString:@"HEAD"]) return RKRequestMethodHEAD;
else if ([methodName isEqualToString:@"PATCH"]) return RKRequestMethodPATCH;
else if ([methodName isEqualToString:@"OPTIONS"]) return RKRequestMethodOPTIONS;
else return RKRequestMethodInvalid;
else @throw [NSException exceptionWithName:NSInvalidArgumentException
reason:[NSString stringWithFormat:@"The given HTTP request method name `%@` does not correspond to any known request methods.", methodName]
userInfo:nil];
}

// Built from http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
Expand Down
6 changes: 6 additions & 0 deletions RestKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,8 @@
73D3907914CA1DD40093E3D6 /* channels.xml in Resources */ = {isa = PBXBuildFile; fileRef = 73D3907814CA1D710093E3D6 /* channels.xml */; };
73D3907A14CA1DD50093E3D6 /* channels.xml in Resources */ = {isa = PBXBuildFile; fileRef = 73D3907814CA1D710093E3D6 /* channels.xml */; };
7F9CBC6174004E31AEC35813 /* libPods-osx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 86EC453810D648768BF62304 /* libPods-osx.a */; };
BE05BDD11782109F00F7C9C9 /* RKRouteTest.m in Sources */ = {isa = PBXBuildFile; fileRef = BE05BDCF1782109F00F7C9C9 /* RKRouteTest.m */; };
BE05BDD2178214AA00F7C9C9 /* RKRouteTest.m in Sources */ = {isa = PBXBuildFile; fileRef = BE05BDCF1782109F00F7C9C9 /* RKRouteTest.m */; };
E2F2B89961FC462B981CEB7A /* libPods-ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E457EFC3D502479D8B4FCF2A /* libPods-ios.a */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -971,6 +973,7 @@
73D3907814CA1D710093E3D6 /* channels.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = channels.xml; sourceTree = "<group>"; };
86EC453810D648768BF62304 /* libPods-osx.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-osx.a"; sourceTree = BUILT_PRODUCTS_DIR; };
8F2DFE1E847347368405F3B5 /* Pods-ios.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios.xcconfig"; path = "Pods/Pods-ios.xcconfig"; sourceTree = SOURCE_ROOT; };
BE05BDCF1782109F00F7C9C9 /* RKRouteTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRouteTest.m; sourceTree = "<group>"; };
E457EFC3D502479D8B4FCF2A /* libPods-ios.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios.a"; sourceTree = BUILT_PRODUCTS_DIR; };
ED192D1B86AB47D7927731B0 /* Pods-osx.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-osx.xcconfig"; path = "Pods/Pods-osx.xcconfig"; sourceTree = SOURCE_ROOT; };
F66056291744FF9000A87A45 /* and_cats.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = and_cats.json; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1487,6 +1490,7 @@
isa = PBXGroup;
children = (
25CC5C58161DDADD0008BD21 /* RKResponseDescriptorTest.m */,
BE05BDCF1782109F00F7C9C9 /* RKRouteTest.m */,
252029081577C78600076FB4 /* RKRouteSetTest.m */,
25565964161FDD8800F5BB20 /* RKResponseMapperOperationTest.m */,
259AC480162B05C80012D2F9 /* RKObjectRequestOperationTest.m */,
Expand Down Expand Up @@ -2371,6 +2375,7 @@
25A9827516A5FF4F0088A3CA /* RKConnectionDescriptionTest.m in Sources */,
2550DA2316B1FB62005A0CB8 /* RKPost.m in Sources */,
2582F56D173038760043B8BB /* RKInMemoryManagedObjectCacheTest.m in Sources */,
BE05BDD11782109F00F7C9C9 /* RKRouteTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -2529,6 +2534,7 @@
25A73363169C8C230090A930 /* VersionedModel.xcdatamodeld in Sources */,
2550DA2416B1FB62005A0CB8 /* RKPost.m in Sources */,
2582F56E173038760043B8BB /* RKInMemoryManagedObjectCacheTest.m in Sources */,
BE05BDD2178214AA00F7C9C9 /* RKRouteTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Loading

0 comments on commit c73ac51

Please sign in to comment.