fixing issue with URI TEMPLATE matcher
This commit is contained in:
@@ -13,6 +13,11 @@ note
|
|||||||
class
|
class
|
||||||
URI_TEMPLATE
|
URI_TEMPLATE
|
||||||
|
|
||||||
|
inherit
|
||||||
|
HASHABLE
|
||||||
|
|
||||||
|
DEBUG_OUTPUT
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
@@ -23,17 +28,47 @@ feature {NONE} -- Initialization
|
|||||||
template := s
|
template := s
|
||||||
end
|
end
|
||||||
|
|
||||||
make_with_handler (s: STRING; a_handler: detachable URI_TEMPLATE_HANDLER)
|
|
||||||
do
|
|
||||||
make (s)
|
|
||||||
analyze (a_handler)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
template: STRING
|
template: STRING
|
||||||
-- URI string representation
|
-- URI string representation
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
debug_output: STRING
|
||||||
|
-- String that should be displayed in debugger to represent `Current'.
|
||||||
|
do
|
||||||
|
create Result.make_from_string (template)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
hash_code: INTEGER
|
||||||
|
-- Hash code value
|
||||||
|
do
|
||||||
|
Result := template.hash_code
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Structures
|
||||||
|
|
||||||
|
variable_names: LIST [STRING]
|
||||||
|
do
|
||||||
|
analyze (Void)
|
||||||
|
if attached expansion_parts as l_x_parts then
|
||||||
|
create {ARRAYED_LIST [STRING]} Result.make (l_x_parts.count)
|
||||||
|
from
|
||||||
|
l_x_parts.start
|
||||||
|
until
|
||||||
|
l_x_parts.after
|
||||||
|
loop
|
||||||
|
Result.append (l_x_parts.item.variable_names)
|
||||||
|
l_x_parts.forth
|
||||||
|
end
|
||||||
|
else
|
||||||
|
create {ARRAYED_LIST [STRING]} Result.make (0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
path_variable_names: LIST [STRING]
|
path_variable_names: LIST [STRING]
|
||||||
do
|
do
|
||||||
analyze (Void)
|
analyze (Void)
|
||||||
@@ -77,6 +112,7 @@ feature -- Access
|
|||||||
feature -- Builder
|
feature -- Builder
|
||||||
|
|
||||||
string (a_ht: HASH_TABLE [detachable ANY, STRING]): STRING
|
string (a_ht: HASH_TABLE [detachable ANY, STRING]): STRING
|
||||||
|
-- Expanded template using variable from `a_ht'
|
||||||
local
|
local
|
||||||
tpl: like template
|
tpl: like template
|
||||||
exp: URI_TEMPLATE_EXPRESSION
|
exp: URI_TEMPLATE_EXPRESSION
|
||||||
@@ -109,12 +145,7 @@ feature -- Builder
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
url_encoder: URL_ENCODER
|
feature -- Match
|
||||||
once
|
|
||||||
create Result
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Analyze
|
|
||||||
|
|
||||||
match (a_uri: STRING): detachable URI_TEMPLATE_MATCH_RESULT
|
match (a_uri: STRING): detachable URI_TEMPLATE_MATCH_RESULT
|
||||||
local
|
local
|
||||||
@@ -126,6 +157,7 @@ feature -- Analyze
|
|||||||
vn, s,t: STRING
|
vn, s,t: STRING
|
||||||
vv: STRING
|
vv: STRING
|
||||||
l_vars, l_path_vars, l_query_vars: HASH_TABLE [STRING, STRING]
|
l_vars, l_path_vars, l_query_vars: HASH_TABLE [STRING, STRING]
|
||||||
|
l_uri_count: INTEGER
|
||||||
do
|
do
|
||||||
--| Extract expansion parts "\\{([^\\}]*)\\}"
|
--| Extract expansion parts "\\{([^\\}]*)\\}"
|
||||||
analyze (Void)
|
analyze (Void)
|
||||||
@@ -133,8 +165,12 @@ feature -- Analyze
|
|||||||
create l_path_vars.make (l_x_parts.count)
|
create l_path_vars.make (l_x_parts.count)
|
||||||
create l_query_vars.make (l_x_parts.count)
|
create l_query_vars.make (l_x_parts.count)
|
||||||
l_vars := l_path_vars
|
l_vars := l_path_vars
|
||||||
tpl := template
|
|
||||||
b := True
|
b := True
|
||||||
|
l_uri_count := a_uri.count
|
||||||
|
tpl := template
|
||||||
|
if l_x_parts.is_empty then
|
||||||
|
b := a_uri.substring (1, tpl.count).same_string (tpl)
|
||||||
|
else
|
||||||
from
|
from
|
||||||
l_x_parts.start
|
l_x_parts.start
|
||||||
p := 1
|
p := 1
|
||||||
@@ -153,32 +189,43 @@ feature -- Analyze
|
|||||||
p := q + vn.count + 2
|
p := q + vn.count + 2
|
||||||
end
|
end
|
||||||
--| Check related variable
|
--| Check related variable
|
||||||
if not vn.is_empty then
|
if b and then not vn.is_empty then
|
||||||
if exp.is_query then
|
if exp.is_query then
|
||||||
l_vars := l_query_vars
|
l_vars := l_query_vars
|
||||||
else
|
else
|
||||||
l_vars := l_path_vars
|
l_vars := l_path_vars
|
||||||
end
|
end
|
||||||
|
if q + l_offset <= l_uri_count then
|
||||||
inspect vn[1]
|
inspect vn[1]
|
||||||
when '?' then
|
when '?' then
|
||||||
import_form_style_parameters_into (a_uri.substring (q + l_offset + 1, a_uri.count), l_vars)
|
import_form_style_parameters_into (a_uri.substring (q + l_offset + 1, l_uri_count), l_vars)
|
||||||
when ';' then
|
when ';' then
|
||||||
import_path_style_parameters_into (a_uri.substring (q + l_offset, a_uri.count), l_vars)
|
import_path_style_parameters_into (a_uri.substring (q + l_offset, l_uri_count), l_vars)
|
||||||
else
|
else
|
||||||
vv := next_path_variable_value (a_uri, q + l_offset)
|
vv := next_path_variable_value (a_uri, q + l_offset)
|
||||||
l_vars.force (vv, vn)
|
l_vars.force (vv, vn)
|
||||||
l_offset := l_offset + vv.count - (vn.count + 2)
|
l_offset := l_offset + vv.count - (vn.count + 2)
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
b := exp.is_query --| query are optional
|
||||||
|
end
|
||||||
end
|
end
|
||||||
l_x_parts.forth
|
l_x_parts.forth
|
||||||
end
|
end
|
||||||
|
end
|
||||||
if b then
|
if b then
|
||||||
create Result.make (l_path_vars, l_query_vars)
|
create Result.make (l_path_vars, l_query_vars)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Internal Access
|
||||||
|
|
||||||
|
expansion_parts: detachable LIST [URI_TEMPLATE_EXPRESSION]
|
||||||
|
-- Expansion parts
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
analyze (a_handler: detachable URI_TEMPLATE_HANDLER)
|
analyze (a_handler: detachable URI_TEMPLATE_HANDLER)
|
||||||
local
|
local
|
||||||
l_x_parts: like expansion_parts
|
l_x_parts: like expansion_parts
|
||||||
@@ -233,11 +280,6 @@ feature -- Analyze
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
|
||||||
|
|
||||||
expansion_parts: detachable LIST [URI_TEMPLATE_EXPRESSION]
|
|
||||||
-- Expansion parts
|
|
||||||
|
|
||||||
import_path_style_parameters_into (a_content: STRING; res: HASH_TABLE [STRING, STRING])
|
import_path_style_parameters_into (a_content: STRING; res: HASH_TABLE [STRING, STRING])
|
||||||
require
|
require
|
||||||
a_content_attached: a_content /= Void
|
a_content_attached: a_content /= Void
|
||||||
@@ -313,9 +355,9 @@ feature {NONE} -- Implementation
|
|||||||
Result := a_uri.substring (a_index, p)
|
Result := a_uri.substring (a_index, p)
|
||||||
end
|
end
|
||||||
|
|
||||||
comma_separated_variable_names (s: STRING): LIST [STRING]
|
url_encoder: URL_ENCODER
|
||||||
do
|
once
|
||||||
Result := s.split (',')
|
create Result
|
||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ class
|
|||||||
URI_TEMPLATE_MATCH_RESULT
|
URI_TEMPLATE_MATCH_RESULT
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make,
|
||||||
|
make_empty
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
@@ -18,10 +19,27 @@ feature {NONE} -- Initialization
|
|||||||
query_variables := q
|
query_variables := q
|
||||||
end
|
end
|
||||||
|
|
||||||
|
make_empty
|
||||||
|
do
|
||||||
|
make (create {like path_variables}.make (0), create {like query_variables}.make (0))
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
|
variable (n: STRING): detachable STRING
|
||||||
|
-- Value related to variable name `n'
|
||||||
|
do
|
||||||
|
Result := query_variables.item (n)
|
||||||
|
if Result = Void then
|
||||||
|
Result := path_variables.item (n)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
path_variables: HASH_TABLE [STRING, STRING]
|
path_variables: HASH_TABLE [STRING, STRING]
|
||||||
|
-- Variables being part of the path segments
|
||||||
|
|
||||||
query_variables: HASH_TABLE [STRING, STRING]
|
query_variables: HASH_TABLE [STRING, STRING]
|
||||||
|
-- Variables being part of the query segments (i.e: after the ? )
|
||||||
|
|
||||||
;note
|
;note
|
||||||
copyright: "2011-2011, Eiffel Software and others"
|
copyright: "2011-2011, Eiffel Software and others"
|
||||||
|
|||||||
@@ -30,8 +30,15 @@ feature -- Test routines
|
|||||||
tpl: URI_TEMPLATE
|
tpl: URI_TEMPLATE
|
||||||
do
|
do
|
||||||
create tpl.make ("api/foo/{foo_id}/{?id,extra}")
|
create tpl.make ("api/foo/{foo_id}/{?id,extra}")
|
||||||
|
uri_template_match (tpl, "api/foo/bar/", <<["foo_id", "bar"]>>, <<>>)
|
||||||
uri_template_match (tpl, "api/foo/bar/?id=123", <<["foo_id", "bar"]>>, <<["id", "123"]>>)
|
uri_template_match (tpl, "api/foo/bar/?id=123", <<["foo_id", "bar"]>>, <<["id", "123"]>>)
|
||||||
uri_template_match (tpl, "api/foo/bar/?id=123&extra=test", <<["foo_id", "bar"]>>, <<["id", "123"], ["extra", "test"]>>)
|
uri_template_match (tpl, "api/foo/bar/?id=123&extra=test", <<["foo_id", "bar"]>>, <<["id", "123"], ["extra", "test"]>>)
|
||||||
|
uri_template_match (tpl, "api/foo/bar/?id=123&extra=test&one=more", <<["foo_id", "bar"]>>, <<["id", "123"], ["extra", "test"]>>)
|
||||||
|
uri_template_mismatch (tpl, "")
|
||||||
|
uri_template_mismatch (tpl, "/")
|
||||||
|
uri_template_mismatch (tpl, "foo/bar/?id=123")
|
||||||
|
uri_template_mismatch (tpl, "/api/foo/bar/")
|
||||||
|
uri_template_mismatch (tpl, "api/foo/bar")
|
||||||
|
|
||||||
create tpl.make ("weather/{state}/{city}?forecast={day}")
|
create tpl.make ("weather/{state}/{city}?forecast={day}")
|
||||||
uri_template_match (tpl, "weather/California/Goleta?forecast=today", <<["state", "California"], ["city", "Goleta"]>>, <<["day", "today"]>>)
|
uri_template_match (tpl, "weather/California/Goleta?forecast=today", <<["state", "California"], ["city", "Goleta"]>>, <<["day", "today"]>>)
|
||||||
@@ -563,6 +570,14 @@ feature -- Test routines
|
|||||||
assert ("query variables matched", matched)
|
assert ("query variables matched", matched)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
uri_template_mismatch (a_uri_template: URI_TEMPLATE; a_uri: STRING)
|
||||||
|
local
|
||||||
|
l_match: detachable URI_TEMPLATE_MATCH_RESULT
|
||||||
|
do
|
||||||
|
l_match := a_uri_template.match (a_uri)
|
||||||
|
assert ("uri %"" + a_uri + "%" does not match template %"" + a_uri_template.template + "%"", l_match = Void)
|
||||||
|
end
|
||||||
|
|
||||||
uri_template_match (a_uri_template: URI_TEMPLATE; a_uri: STRING; path_res: ARRAY [TUPLE [name: STRING; value: STRING]]; query_res: ARRAY [TUPLE [name: STRING; value: STRING]])
|
uri_template_match (a_uri_template: URI_TEMPLATE; a_uri: STRING; path_res: ARRAY [TUPLE [name: STRING; value: STRING]]; query_res: ARRAY [TUPLE [name: STRING; value: STRING]])
|
||||||
local
|
local
|
||||||
b: BOOLEAN
|
b: BOOLEAN
|
||||||
@@ -584,7 +599,7 @@ feature -- Test routines
|
|||||||
assert ("uri matched path variables", b)
|
assert ("uri matched path variables", b)
|
||||||
end
|
end
|
||||||
if attached l_match.query_variables as query_ht then
|
if attached l_match.query_variables as query_ht then
|
||||||
b := query_ht.count = query_res.count
|
b := query_ht.count >= query_res.count
|
||||||
from
|
from
|
||||||
i := query_res.lower
|
i := query_res.lower
|
||||||
until
|
until
|
||||||
|
|||||||
Reference in New Issue
Block a user