Parameterizable routes.

Routes that can contains variables parts that will be resolved during the matching process.

Route parameters are marked with a colon :

var route = new AppParamRoute("/:id")
assert not route.match("/")
assert route.match("/user")
assert route.match("/user/")
assert not route.match("/user/10")

It is possible to use more than one parameter in the same route:

route = new AppParamRoute("/user/:userId/items/:itemId")
assert not route.match("/user/10/items/")
assert route.match("/user/10/items/e895346")
assert route.match("/user/USER/items/0/")
assert not route.match("/user/10/items/10/profile")

Introduced properties

fun parse_path_parameters(path: String)

popcorn :: AppParamRoute :: parse_path_parameters

Cut path into UriParts.
fun parse_uri_parameters(uri: String): Map[String, String]

popcorn :: AppParamRoute :: parse_uri_parameters

Extract parameter values from uri.

Redefined properties

redef type SELF: AppParamRoute

popcorn $ AppParamRoute :: SELF

Type of this instance, automatically specialized in every class
redef init init

popcorn $ AppParamRoute :: init

redef fun resolve_path(uri: String): String

popcorn $ AppParamRoute :: resolve_path

For parameterized routes, parameter names are replaced by their value in the URI.

All properties

fun !=(other: nullable Object): Bool

core :: Object :: !=

Have self and other different values?
fun ==(other: nullable Object): Bool

core :: Object :: ==

Have self and other the same value?
type CLASS: Class[SELF]

core :: Object :: CLASS

The type of the class of self.
type SELF: Object

core :: Object :: SELF

Type of this instance, automatically specialized in every class
protected fun class_factory(name: String): CLASS

core :: Object :: class_factory

Implementation used by get_class to create the specific class.
fun class_name: String

core :: Object :: class_name

The class name of the object.
fun get_class: CLASS

core :: Object :: get_class

The meta-object representing the dynamic type of self.
fun hash: Int

core :: Object :: hash

The hash code of the object.
init init

core :: Object :: init

fun inspect: String

core :: Object :: inspect

Developer readable representation of self.
protected fun inspect_head: String

core :: Object :: inspect_head

Return "CLASSNAME:#OBJECTID".
intern fun is_same_instance(other: nullable Object): Bool

core :: Object :: is_same_instance

Return true if self and other are the same instance (i.e. same identity).
fun is_same_serialized(other: nullable Object): Bool

core :: Object :: is_same_serialized

Is self the same as other in a serialization context?
intern fun is_same_type(other: Object): Bool

core :: Object :: is_same_type

Return true if self and other have the same dynamic type.
fun match(uri: String): Bool

popcorn :: AppRoute :: match

Does self match the req?
intern fun object_id: Int

core :: Object :: object_id

An internal hash code for the object based on its identity.
fun output

core :: Object :: output

Display self on stdout (debug only).
intern fun output_class_name

core :: Object :: output_class_name

Display class name on stdout (debug only).
fun parse_path_parameters(path: String)

popcorn :: AppParamRoute :: parse_path_parameters

Cut path into UriParts.
fun parse_uri_parameters(uri: String): Map[String, String]

popcorn :: AppParamRoute :: parse_uri_parameters

Extract parameter values from uri.
fun path: String

popcorn :: AppRoute :: path

Route relative path from server root.
protected fun path=(path: String)

popcorn :: AppRoute :: path=

Route relative path from server root.
fun resolve_path(uri: String): String

popcorn :: AppRoute :: resolve_path

Replace path parameters with concrete values from the uri.
fun serialization_hash: Int

core :: Object :: serialization_hash

Hash value use for serialization
intern fun sys: Sys

core :: Object :: sys

Return the global sys object, the only instance of the Sys class.
abstract fun to_jvalue(env: JniEnv): JValue

core :: Object :: to_jvalue

fun to_s: String

core :: Object :: to_s

User readable representation of self.
fun uri_root(uri: String): String

popcorn :: AppRoute :: uri_root

Remove resolved_path prefix from uri.
package_diagram popcorn::AppParamRoute AppParamRoute popcorn::AppRoute AppRoute popcorn::AppParamRoute->popcorn::AppRoute core::Object Object popcorn::AppRoute->core::Object ...core::Object ... ...core::Object->core::Object popcorn::AppGlobRoute AppGlobRoute popcorn::AppGlobRoute->popcorn::AppParamRoute

Ancestors

interface Object

core :: Object

The root of the class hierarchy.

Parents

class AppRoute

popcorn :: AppRoute

AppRoute provide services for path and uri manipulation and matching..

Children

class AppGlobRoute

popcorn :: AppGlobRoute

Route with glob.

Class definitions

popcorn $ AppParamRoute
# Parameterizable routes.
#
# Routes that can contains variables parts that will be resolved during the
# matching process.
#
# Route parameters are marked with a colon `:`
# ~~~
# var route = new AppParamRoute("/:id")
# assert not route.match("/")
# assert route.match("/user")
# assert route.match("/user/")
# assert not route.match("/user/10")
# ~~~
#
# It is possible to use more than one parameter in the same route:
# ~~~
# route = new AppParamRoute("/user/:userId/items/:itemId")
# assert not route.match("/user/10/items/")
# assert route.match("/user/10/items/e895346")
# assert route.match("/user/USER/items/0/")
# assert not route.match("/user/10/items/10/profile")
# ~~~
class AppParamRoute
	super AppRoute

	init do parse_path_parameters(path)

	# Cut `path` into `UriParts`.
	fun parse_path_parameters(path: String) do
		for part in path.split("/") do
			if not part.is_empty and part.first == ':' then
				# is an uri param
				path_parts.add new UriParam(part.substring(1, part.length))
			else
				# is a standard string
				path_parts.add new UriString(part)
			end
		end
	end

	# For parameterized routes, parameter names are replaced by their value in the URI.
	# ~~~
	# var route = new AppParamRoute("/user/:id")
	# assert route.resolve_path("/user/10/profile") == "/user/10"
	#
	# route = new AppParamRoute("/user/:userId/items/:itemId")
	# assert route.resolve_path("/user/Morriar/items/i156/desc") == "/user/Morriar/items/i156"
	# ~~~
	redef fun resolve_path(uri) do
		var uri_params = parse_uri_parameters(uri)
		var path = "/"
		for part in path_parts do
			if part isa UriString then
				path /= part.string
			else if part isa UriParam then
				path /= uri_params.get_or_default(part.name, part.name)
			end
		end
		return path.simplify_path
	end

	# Extract parameter values from `uri`.
	# ~~~
	# var route = new AppParamRoute("/user/:userId/items/:itemId")
	# var params = route.parse_uri_parameters("/user/10/items/i125/desc")
	# assert params["userId"] == "10"
	# assert params["itemId"] == "i125"
	# assert params.length == 2
	#
	# params = route.parse_uri_parameters("/")
	# assert params.is_empty
	# ~~~
	fun parse_uri_parameters(uri: String): Map[String, String] do
		var res = new HashMap[String, String]
		if path_parts.is_empty then return res
		var parts = uri.split("/")
		for i in [0 .. path_parts.length[ do
			if i >= parts.length then return res
			var ppart = path_parts[i]
			var part = parts[i]
			if not ppart.match(part) then return res
			if ppart isa UriParam then
				res[ppart.name] = part
			end
		end
		return res
	end

	private var path_parts = new Array[UriPart]
end
lib/popcorn/pop_routes.nit:87,1--176,3