| 232 | |
| 233 | |
| 234 | class Resource(AbstractResource): |
| 235 | |
| 236 | def __init__(self, *, name=None): |
| 237 | super().__init__(name=name) |
| 238 | self._routes = [] |
| 239 | |
| 240 | def add_route(self, method, handler, *, |
| 241 | expect_handler=None): |
| 242 | |
| 243 | for route in self._routes: |
| 244 | if route.method == method or route.method == hdrs.METH_ANY: |
| 245 | raise RuntimeError("Added route will never be executed, " |
| 246 | "method {route.method} is " |
| 247 | "already registered".format(route=route)) |
| 248 | |
| 249 | route = ResourceRoute(method, handler, self, |
| 250 | expect_handler=expect_handler) |
| 251 | self.register_route(route) |
| 252 | return route |
| 253 | |
| 254 | def register_route(self, route): |
| 255 | assert isinstance(route, ResourceRoute), \ |
| 256 | 'Instance of Route class is required, got {!r}'.format(route) |
| 257 | self._routes.append(route) |
| 258 | |
| 259 | @asyncio.coroutine |
| 260 | def resolve(self, method, path): |
| 261 | allowed_methods = set() |
| 262 | |
| 263 | match_dict = self._match(path) |
| 264 | if match_dict is None: |
| 265 | return None, allowed_methods |
| 266 | |
| 267 | for route in self._routes: |
| 268 | route_method = route.method |
| 269 | allowed_methods.add(route_method) |
| 270 | |
| 271 | if route_method == method or route_method == hdrs.METH_ANY: |
| 272 | return UrlMappingMatchInfo(match_dict, route), allowed_methods |
| 273 | else: |
| 274 | return None, allowed_methods |
| 275 | |
| 276 | def __len__(self): |
| 277 | return len(self._routes) |
| 278 | |
| 279 | def __iter__(self): |
| 280 | return iter(self._routes) |
| 281 | |
| 282 | |
| 283 | class PlainResource(Resource): |