First version of URI Template library
as specified by http://tools.ietf.org/html/draft-gregorio-uritemplate-05 (it seems to contains some error in the spec .. or minor incoherences, to double check) The matcher is basic, it does not handle all the details of the string builder, but that seems ok for now.
This commit is contained in:
332
library/protocol/uri_template/src/uri_template.e
Normal file
332
library/protocol/uri_template/src/uri_template.e
Normal file
@@ -0,0 +1,332 @@
|
||||
note
|
||||
description: "[
|
||||
Summary description for {URI_TEMPLATE}.
|
||||
|
||||
See http://tools.ietf.org/html/draft-gregorio-uritemplate-05
|
||||
|
||||
]"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
URI_TEMPLATE
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (s: STRING)
|
||||
do
|
||||
template := s
|
||||
end
|
||||
|
||||
make_with_handler (s: STRING; a_handler: detachable URI_TEMPLATE_HANDLER)
|
||||
do
|
||||
make (s)
|
||||
analyze (a_handler)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
template: STRING
|
||||
-- URI string representation
|
||||
|
||||
path_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
|
||||
if not l_x_parts.item.is_query then
|
||||
Result.append (l_x_parts.item.variable_names)
|
||||
end
|
||||
l_x_parts.forth
|
||||
end
|
||||
else
|
||||
create {ARRAYED_LIST [STRING]} Result.make (0)
|
||||
end
|
||||
end
|
||||
|
||||
query_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
|
||||
if l_x_parts.item.is_query then
|
||||
Result.append (l_x_parts.item.variable_names)
|
||||
end
|
||||
l_x_parts.forth
|
||||
end
|
||||
else
|
||||
create {ARRAYED_LIST [STRING]} Result.make (0)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Builder
|
||||
|
||||
string (a_ht: HASH_TABLE [detachable ANY, STRING]): STRING
|
||||
local
|
||||
tpl: like template
|
||||
exp: URI_TEMPLATE_EXPRESSION
|
||||
p,q: INTEGER
|
||||
do
|
||||
analyze (Void)
|
||||
tpl := template
|
||||
if attached expansion_parts as l_x_parts then
|
||||
create Result.make (tpl.count)
|
||||
from
|
||||
l_x_parts.start
|
||||
p := 1
|
||||
until
|
||||
l_x_parts.after
|
||||
loop
|
||||
q := l_x_parts.item.position
|
||||
--| Added inter variable text
|
||||
Result.append (tpl.substring (p, q - 1))
|
||||
--| Expand variables ...
|
||||
exp := l_x_parts.item
|
||||
exp.append_to_string (a_ht, Result)
|
||||
|
||||
p := q + l_x_parts.item.expression.count + 2
|
||||
|
||||
l_x_parts.forth
|
||||
end
|
||||
Result.append (tpl.substring (p, tpl.count))
|
||||
else
|
||||
create Result.make_from_string (tpl)
|
||||
end
|
||||
end
|
||||
|
||||
url_encoder: URL_ENCODER
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
feature -- Analyze
|
||||
|
||||
match (a_uri: STRING): detachable TUPLE [path_variables: HASH_TABLE [STRING, STRING]; query_variables: HASH_TABLE [STRING, STRING]]
|
||||
local
|
||||
b: BOOLEAN
|
||||
tpl: like template
|
||||
l_offset: INTEGER
|
||||
p,q: INTEGER
|
||||
exp: URI_TEMPLATE_EXPRESSION
|
||||
vn, s,t: STRING
|
||||
vv: STRING
|
||||
l_vars, l_path_vars, l_query_vars: HASH_TABLE [STRING, STRING]
|
||||
do
|
||||
--| Extract expansion parts "\\{([^\\}]*)\\}"
|
||||
analyze (Void)
|
||||
if attached expansion_parts as l_x_parts then
|
||||
create l_path_vars.make (l_x_parts.count)
|
||||
create l_query_vars.make (l_x_parts.count)
|
||||
l_vars := l_path_vars
|
||||
tpl := template
|
||||
b := True
|
||||
from
|
||||
l_x_parts.start
|
||||
p := 1
|
||||
l_offset := 0
|
||||
until
|
||||
l_x_parts.after or not b
|
||||
loop
|
||||
exp := l_x_parts.item
|
||||
vn := exp.expression
|
||||
q := exp.position
|
||||
--| Check text between vars
|
||||
if q > p then
|
||||
t := tpl.substring (p, q - 1)
|
||||
s := a_uri.substring (p + l_offset, q + l_offset - 1)
|
||||
b := s.same_string (t)
|
||||
p := q + vn.count + 2
|
||||
end
|
||||
--| Check related variable
|
||||
if not vn.is_empty then
|
||||
if exp.is_query then
|
||||
l_vars := l_query_vars
|
||||
else
|
||||
l_vars := l_path_vars
|
||||
end
|
||||
|
||||
inspect vn[1]
|
||||
when '?' then
|
||||
import_form_style_parameters_into (a_uri.substring (q + l_offset + 1, a_uri.count), l_vars)
|
||||
when ';' then
|
||||
import_path_style_parameters_into (a_uri.substring (q + l_offset, a_uri.count), l_vars)
|
||||
else
|
||||
vv := next_path_variable_value (a_uri, q + l_offset)
|
||||
l_vars.force (vv, vn)
|
||||
l_offset := l_offset + vv.count - (vn.count + 2)
|
||||
end
|
||||
end
|
||||
l_x_parts.forth
|
||||
end
|
||||
if b then
|
||||
Result := [l_path_vars, l_query_vars]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
analyze (a_handler: detachable URI_TEMPLATE_HANDLER)
|
||||
local
|
||||
l_x_parts: like expansion_parts
|
||||
c: CHARACTER
|
||||
i,p,n: INTEGER
|
||||
tpl: like template
|
||||
in_x: BOOLEAN
|
||||
in_query: BOOLEAN
|
||||
x: STRING
|
||||
exp: URI_TEMPLATE_EXPRESSION
|
||||
do
|
||||
l_x_parts := expansion_parts
|
||||
if l_x_parts = Void then
|
||||
tpl := template
|
||||
|
||||
--| Extract expansion parts "\\{([^\\}]*)\\}"
|
||||
create {ARRAYED_LIST [like expansion_parts.item]} l_x_parts.make (tpl.occurrences ('{'))
|
||||
from
|
||||
i := 1
|
||||
n := tpl.count
|
||||
create x.make_empty
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
c := tpl[i]
|
||||
if in_x then
|
||||
if c = '}' then
|
||||
create exp.make (p, x.twin, in_query)
|
||||
l_x_parts.force (exp)
|
||||
x.wipe_out
|
||||
in_x := False
|
||||
else
|
||||
x.extend (c)
|
||||
end
|
||||
else
|
||||
inspect c
|
||||
when '{' then
|
||||
check x_is_empty: x.is_empty end
|
||||
p := i
|
||||
in_x := True
|
||||
if not in_query then
|
||||
in_query := tpl.valid_index (i+1) and then tpl[i+1] = '?'
|
||||
end
|
||||
when '?' then
|
||||
in_query := True
|
||||
else
|
||||
end
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
expansion_parts := l_x_parts
|
||||
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])
|
||||
require
|
||||
a_content_attached: a_content /= Void
|
||||
res_attached: res /= Void
|
||||
do
|
||||
import_custom_style_parameters_into (a_content, ';', res)
|
||||
end
|
||||
|
||||
import_form_style_parameters_into (a_content: STRING; res: HASH_TABLE [STRING, STRING])
|
||||
require
|
||||
a_content_attached: a_content /= Void
|
||||
res_attached: res /= Void
|
||||
do
|
||||
import_custom_style_parameters_into (a_content, '&', res)
|
||||
end
|
||||
|
||||
import_custom_style_parameters_into (a_content: STRING; a_separator: CHARACTER; res: HASH_TABLE [STRING, STRING])
|
||||
require
|
||||
a_content_attached: a_content /= Void
|
||||
res_attached: res /= Void
|
||||
local
|
||||
n, p, i, j: INTEGER
|
||||
s: STRING
|
||||
l_name,l_value: STRING
|
||||
do
|
||||
n := a_content.count
|
||||
if n > 0 then
|
||||
from
|
||||
p := 1
|
||||
until
|
||||
p = 0
|
||||
loop
|
||||
i := a_content.index_of (a_separator, p)
|
||||
if i = 0 then
|
||||
s := a_content.substring (p, n)
|
||||
p := 0
|
||||
else
|
||||
s := a_content.substring (p, i - 1)
|
||||
p := i + 1
|
||||
end
|
||||
if not s.is_empty then
|
||||
j := s.index_of ('=', 1)
|
||||
if j > 0 then
|
||||
l_name := s.substring (1, j - 1)
|
||||
l_value := s.substring (j + 1, s.count)
|
||||
res.force (l_value, l_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
next_path_variable_value (a_uri: STRING; a_index: INTEGER): STRING
|
||||
require
|
||||
valid_index: a_index <= a_uri.count
|
||||
local
|
||||
i,n,p: INTEGER
|
||||
do
|
||||
from
|
||||
i := a_index
|
||||
n := a_uri.count
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
inspect a_uri[i]
|
||||
when '/', '?' then
|
||||
i := n
|
||||
else
|
||||
p := i
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
Result := a_uri.substring (a_index, p)
|
||||
end
|
||||
|
||||
comma_separated_variable_names (s: STRING): LIST [STRING]
|
||||
do
|
||||
Result := s.split (',')
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
|
||||
end
|
||||
286
library/protocol/uri_template/src/uri_template_expression.e
Normal file
286
library/protocol/uri_template/src/uri_template_expression.e
Normal file
@@ -0,0 +1,286 @@
|
||||
note
|
||||
description: "Summary description for {URI_TEMPLATE_EXPRESSION}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
URI_TEMPLATE_EXPRESSION
|
||||
|
||||
inherit
|
||||
DEBUG_OUTPUT
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_position: INTEGER; a_expression: STRING; a_is_query: BOOLEAN)
|
||||
do
|
||||
position := a_position
|
||||
expression := a_expression
|
||||
is_query := a_is_query
|
||||
operator := '%U'
|
||||
end
|
||||
|
||||
feature -- Processing
|
||||
|
||||
analyze
|
||||
local
|
||||
exp: like expression
|
||||
s: detachable STRING
|
||||
lst: LIST [STRING]
|
||||
p: INTEGER
|
||||
vars: like variables
|
||||
vn: STRING
|
||||
vmodifier: detachable STRING
|
||||
i,n: INTEGER
|
||||
do
|
||||
if not is_analyzed then
|
||||
exp := expression
|
||||
if not exp.is_empty then
|
||||
op_prefix := '%U'
|
||||
op_delimiter := ','
|
||||
inspect exp[1]
|
||||
when '+' then
|
||||
reserved := True
|
||||
operator := '+'
|
||||
when '.' then
|
||||
operator := '.'
|
||||
op_prefix := '.'
|
||||
op_delimiter := '.'
|
||||
when '/' then
|
||||
operator := '/'
|
||||
op_prefix := '/'
|
||||
op_delimiter := '/'
|
||||
when ';' then
|
||||
operator := ';'
|
||||
op_prefix := ';'
|
||||
op_delimiter := ';'
|
||||
when '?' then
|
||||
operator := '?'
|
||||
op_prefix := '?'
|
||||
op_delimiter := '&'
|
||||
when '|', '!', '@' then
|
||||
operator := exp[1]
|
||||
else
|
||||
operator := '%U'
|
||||
end
|
||||
if operator /= '%U' then
|
||||
s := exp.substring (2, exp.count)
|
||||
else
|
||||
s := exp
|
||||
end
|
||||
|
||||
lst := s.split (',')
|
||||
from
|
||||
create {ARRAYED_LIST [like variables.item]} vars.make (lst.count)
|
||||
lst.start
|
||||
until
|
||||
lst.after
|
||||
loop
|
||||
s := lst.item
|
||||
vmodifier := Void
|
||||
p := s.index_of ('|', 1)
|
||||
if p > 0 then
|
||||
vn := s.substring (1, p - 1)
|
||||
s := s.substring (p + 1, s.count)
|
||||
else
|
||||
vn := s
|
||||
s := Void
|
||||
end
|
||||
from
|
||||
vmodifier := Void
|
||||
i := 1
|
||||
n := vn.count
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
inspect vn[i]
|
||||
when '*', '+', ':', '^' then
|
||||
vmodifier := vn.substring (i, n)
|
||||
vn := vn.substring (1, i - 1)
|
||||
i := n + 1 --| exit
|
||||
else
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
vars.force (create {URI_TEMPLATE_EXPRESSION_VARIABLE}.make (operator, vn, s, vmodifier))
|
||||
lst.forth
|
||||
end
|
||||
variables := vars
|
||||
end
|
||||
is_analyzed := True
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
position: INTEGER
|
||||
|
||||
expression: STRING
|
||||
|
||||
is_query: BOOLEAN
|
||||
|
||||
feature -- Status
|
||||
|
||||
operator: CHARACTER
|
||||
|
||||
has_operator: BOOLEAN
|
||||
do
|
||||
Result := operator /= '%U'
|
||||
end
|
||||
|
||||
reserved: BOOLEAN
|
||||
|
||||
has_op_prefix: BOOLEAN
|
||||
do
|
||||
Result := op_prefix /= '%U'
|
||||
end
|
||||
|
||||
op_prefix: CHARACTER
|
||||
|
||||
op_delimiter: CHARACTER
|
||||
|
||||
variables: detachable LIST [URI_TEMPLATE_EXPRESSION_VARIABLE]
|
||||
|
||||
variable_names: LIST [STRING]
|
||||
do
|
||||
analyze
|
||||
if attached variables as vars then
|
||||
create {ARRAYED_LIST [STRING]} Result.make (vars.count)
|
||||
from
|
||||
vars.start
|
||||
until
|
||||
vars.after
|
||||
loop
|
||||
Result.force (vars.item.name)
|
||||
vars.forth
|
||||
end
|
||||
else
|
||||
create {ARRAYED_LIST [STRING]} Result.make (0)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_analyzed: BOOLEAN
|
||||
|
||||
feature -- Report
|
||||
|
||||
append_to_string (a_ht: HASH_TABLE [detachable ANY, STRING]; a_buffer: STRING)
|
||||
do
|
||||
analyze
|
||||
if attached variables as vars then
|
||||
append_custom_variables_to_string (a_ht, vars, op_prefix, op_delimiter, True, a_buffer)
|
||||
-- inspect operator
|
||||
-- when '?' then
|
||||
-- append_custom_variables_to_string (a_ht, vars, '?', '&', True, a_buffer)
|
||||
-- when ';' then
|
||||
-- append_custom_variables_to_string (a_ht, vars, ';', ';', False, a_buffer)
|
||||
-- when '.' then
|
||||
-- append_custom_variables_to_string (a_ht, vars, '.', ',', True, a_buffer)
|
||||
-- when '/' then
|
||||
-- append_custom_variables_to_string (a_ht, vars, '/', '/', True, a_buffer)
|
||||
-- else
|
||||
-- append_custom_variables_to_string (a_ht, vars, '%U', ',', False, a_buffer)
|
||||
-- end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
url_encoded_string (s: READABLE_STRING_GENERAL; a_encoded: BOOLEAN): STRING
|
||||
do
|
||||
if a_encoded then
|
||||
Result := url_encoder.encoded_string (s.as_string_32)
|
||||
else
|
||||
Result := url_encoder.partial_encoded_string (s.as_string_32, <<
|
||||
':', ',',
|
||||
'+', '.', '/', ';', '?',
|
||||
'|', '!', '@'
|
||||
>>)
|
||||
end
|
||||
end
|
||||
|
||||
url_encoder: URL_ENCODER
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
append_custom_variables_to_string (a_ht: HASH_TABLE [detachable ANY, STRING]; vars: like variables; prefix_char, delimiter_char: CHARACTER; a_include_name: BOOLEAN; a_buffer: STRING)
|
||||
-- If `first_char' is '%U' do not print any first character
|
||||
local
|
||||
vi: like variables.item
|
||||
l_is_first: BOOLEAN
|
||||
vdata: detachable ANY
|
||||
vstr: detachable STRING
|
||||
l_use_default: BOOLEAN
|
||||
do
|
||||
if vars /= Void then
|
||||
from
|
||||
vars.start
|
||||
l_is_first := True
|
||||
until
|
||||
vars.after
|
||||
loop
|
||||
vi := vars.item
|
||||
vdata := a_ht.item (vi.name)
|
||||
vstr := Void
|
||||
if vdata /= Void then
|
||||
vstr := vi.string (vdata)
|
||||
if vstr = Void and vi.has_explode_modifier then
|
||||
--| Missing or list empty
|
||||
vstr := vi.default_value
|
||||
l_use_default := True
|
||||
else
|
||||
l_use_default := False
|
||||
end
|
||||
else
|
||||
--| Missing
|
||||
vstr := vi.default_value
|
||||
l_use_default := True
|
||||
end
|
||||
if vstr /= Void then
|
||||
if l_is_first then
|
||||
if prefix_char /= '%U' then
|
||||
a_buffer.append_character (prefix_char)
|
||||
end
|
||||
l_is_first := False
|
||||
else
|
||||
a_buffer.append_character (delimiter_char)
|
||||
end
|
||||
if l_use_default and (operator = '?') and not vi.has_explode_modifier_star then
|
||||
a_buffer.append (vi.name)
|
||||
if vi.has_explode_modifier_plus then
|
||||
a_buffer.append_character ('.')
|
||||
else
|
||||
a_buffer.append_character ('=')
|
||||
end
|
||||
end
|
||||
a_buffer.append (vstr)
|
||||
end
|
||||
vars.forth
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
debug_output: STRING
|
||||
-- String that should be displayed in debugger to represent `Current'.
|
||||
do
|
||||
Result := expression
|
||||
end
|
||||
|
||||
;note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
@@ -0,0 +1,398 @@
|
||||
note
|
||||
description: "Summary description for {URI_TEMPLATE_EXPRESSION_VARIABLE}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
URI_TEMPLATE_EXPRESSION_VARIABLE
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (op: like operator; n: like name; d: like default_value; m: like modifier)
|
||||
do
|
||||
operator := op
|
||||
name := n
|
||||
default_value := d
|
||||
modifier := m
|
||||
|
||||
|
||||
op_prefix := '%U'
|
||||
op_separator := ','
|
||||
|
||||
inspect op
|
||||
when '+' then
|
||||
reserved := True
|
||||
when '?' then
|
||||
op_prefix := '?'
|
||||
op_separator := '&'
|
||||
when ';' then
|
||||
op_prefix := ';'
|
||||
op_separator := ';'
|
||||
when '/' then
|
||||
op_prefix := '/'
|
||||
op_separator := '/'
|
||||
when '.' then
|
||||
op_prefix := '.'
|
||||
op_separator := '.'
|
||||
else
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
operator: CHARACTER
|
||||
|
||||
name: STRING
|
||||
|
||||
default_value: detachable STRING
|
||||
|
||||
reserved: BOOLEAN
|
||||
|
||||
op_prefix: CHARACTER
|
||||
|
||||
op_separator: CHARACTER
|
||||
|
||||
modifier: detachable STRING
|
||||
|
||||
has_modifier: BOOLEAN
|
||||
do
|
||||
Result := modifier /= Void
|
||||
end
|
||||
|
||||
modified (s: READABLE_STRING_GENERAL): READABLE_STRING_GENERAL
|
||||
local
|
||||
t: STRING
|
||||
i,n: INTEGER
|
||||
do
|
||||
Result := s
|
||||
if attached modifier as m and then m.count > 1 and then m[1] = ':' then
|
||||
n := s.count
|
||||
t := m.substring (2, m.count)
|
||||
if t.is_integer then
|
||||
i := t.to_integer
|
||||
if i > 0 then
|
||||
if i < n then
|
||||
Result := s.substring (1, i)
|
||||
end
|
||||
elseif i < 0 then
|
||||
Result := s.substring (n - i, n)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
has_explode_modifier: BOOLEAN
|
||||
do
|
||||
Result := attached modifier as m and then m.count = 1 and then (
|
||||
m[1] = '+' or m[1] = '*'
|
||||
)
|
||||
end
|
||||
|
||||
has_explode_modifier_plus: BOOLEAN
|
||||
do
|
||||
Result := attached modifier as m and then m.count = 1 and then
|
||||
m[1] = '+'
|
||||
end
|
||||
|
||||
has_explode_modifier_star: BOOLEAN
|
||||
do
|
||||
Result := attached modifier as m and then m.count = 1 and then
|
||||
m[1] = '*'
|
||||
end
|
||||
|
||||
feature -- Report
|
||||
|
||||
string (d: detachable ANY): detachable STRING
|
||||
local
|
||||
l_delimiter: CHARACTER
|
||||
v_enc: detachable STRING
|
||||
k_enc: STRING
|
||||
l_obj: detachable ANY
|
||||
i,n: INTEGER
|
||||
modifier_is_plus: BOOLEAN
|
||||
modifier_is_star: BOOLEAN
|
||||
modifier_has_explode: BOOLEAN
|
||||
dft: detachable ANY
|
||||
has_list_op: BOOLEAN
|
||||
do
|
||||
modifier_has_explode := has_explode_modifier
|
||||
if modifier_has_explode then
|
||||
modifier_is_plus := has_explode_modifier_plus
|
||||
modifier_is_star := has_explode_modifier_star
|
||||
end
|
||||
has_list_op := operator /= '%U' and operator /= '+'
|
||||
dft := default_value
|
||||
create Result.make (20)
|
||||
if attached {READABLE_STRING_GENERAL} d as l_string then
|
||||
v_enc := url_encoded_string (modified (l_string), not reserved)
|
||||
if operator = '?' then
|
||||
Result.append (name)
|
||||
Result.append_character ('=')
|
||||
elseif operator = ';' then
|
||||
Result.append (name)
|
||||
if not v_enc.is_empty then
|
||||
Result.append_character ('=')
|
||||
end
|
||||
end
|
||||
Result.append (v_enc)
|
||||
elseif attached {ARRAY [detachable ANY]} d as l_array then
|
||||
if l_array.is_empty then
|
||||
if dft /= Void then
|
||||
inspect operator
|
||||
when '?',';' then
|
||||
if not modifier_has_explode then
|
||||
Result.append (name)
|
||||
Result.append_character ('=')
|
||||
Result.append (dft.out)
|
||||
else
|
||||
if modifier_is_plus then
|
||||
Result.append (name)
|
||||
Result.append_character ('.')
|
||||
end
|
||||
Result.append (dft.out)
|
||||
end
|
||||
when '/' then
|
||||
if modifier_is_plus then
|
||||
Result.append (name)
|
||||
Result.append_character ('.')
|
||||
end
|
||||
Result.append (dft.out)
|
||||
when '.' then
|
||||
else
|
||||
if modifier_has_explode then
|
||||
if modifier_is_plus then
|
||||
Result.append (name)
|
||||
Result.append_character ('.')
|
||||
end
|
||||
Result.append (dft.out)
|
||||
end
|
||||
end
|
||||
else
|
||||
-- nothing ...
|
||||
end
|
||||
else
|
||||
if modifier_has_explode then
|
||||
l_delimiter := op_separator
|
||||
else
|
||||
l_delimiter := ','
|
||||
inspect operator
|
||||
when '?' then
|
||||
Result.append (name)
|
||||
Result.append_character ('=')
|
||||
when ';' then
|
||||
when '/' then
|
||||
-- Result.append_character ('/')
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
from
|
||||
i := l_array.lower
|
||||
n := l_array.upper
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
l_obj := l_array[i]
|
||||
if l_obj /= Void then
|
||||
v_enc := url_encoded_string (l_obj.out, not reserved)
|
||||
else
|
||||
v_enc := ""
|
||||
end
|
||||
if modifier_is_plus then
|
||||
if
|
||||
(operator = '?' and modifier_is_plus) or
|
||||
(operator = ';' and modifier_has_explode)
|
||||
then
|
||||
Result.append (name)
|
||||
Result.append_character ('=')
|
||||
else
|
||||
Result.append (name)
|
||||
Result.append_character ('.')
|
||||
end
|
||||
elseif modifier_is_star and operator = '?' then
|
||||
Result.append (name)
|
||||
Result.append_character ('=')
|
||||
end
|
||||
Result.append (v_enc)
|
||||
if i < n then
|
||||
Result.append_character (l_delimiter)
|
||||
end
|
||||
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
if Result.is_empty then
|
||||
Result := Void
|
||||
end
|
||||
elseif attached {HASH_TABLE [detachable ANY, STRING]} d as l_table then
|
||||
-- if operator = '?' and not modifier_has_explode and l_table.is_empty and dft = Void then
|
||||
-- elseif operator = '?' and not modifier_has_explode then
|
||||
-- Result.append (name)
|
||||
-- Result.append_character ('=')
|
||||
-- if l_table.is_empty and dft /= Void then
|
||||
-- Result.append (dft.out)
|
||||
-- end
|
||||
-- elseif l_table.is_empty and dft /= Void then
|
||||
-- if modifier_has_explode then
|
||||
-- if modifier_is_plus then
|
||||
-- Result.append (name)
|
||||
-- Result.append_character ('.')
|
||||
-- end
|
||||
-- Result.append (dft.out)
|
||||
-- end
|
||||
-- end
|
||||
if l_table.is_empty then
|
||||
if dft /= Void then
|
||||
inspect operator
|
||||
when '?',';' then
|
||||
if not modifier_has_explode then
|
||||
Result.append (name)
|
||||
Result.append_character ('=')
|
||||
Result.append (dft.out)
|
||||
else
|
||||
if modifier_is_plus then
|
||||
Result.append (name)
|
||||
Result.append_character ('.')
|
||||
end
|
||||
Result.append (dft.out)
|
||||
end
|
||||
when '/' then
|
||||
if modifier_is_plus then
|
||||
Result.append (name)
|
||||
Result.append_character ('.')
|
||||
end
|
||||
Result.append (dft.out)
|
||||
when '.' then
|
||||
else
|
||||
if modifier_has_explode then
|
||||
if modifier_is_plus then
|
||||
Result.append (name)
|
||||
Result.append_character ('.')
|
||||
end
|
||||
Result.append (dft.out)
|
||||
end
|
||||
end
|
||||
else
|
||||
-- nothing ...
|
||||
end
|
||||
else
|
||||
if modifier_has_explode then
|
||||
l_delimiter := op_separator
|
||||
else
|
||||
l_delimiter := ','
|
||||
inspect operator
|
||||
when '?' then
|
||||
Result.append (name)
|
||||
Result.append_character ('=')
|
||||
when ';' then
|
||||
when '/' then
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
from
|
||||
l_table.start
|
||||
until
|
||||
l_table.after
|
||||
loop
|
||||
k_enc := url_encoded_string (l_table.key_for_iteration, not reserved)
|
||||
l_obj := l_table.item_for_iteration
|
||||
if l_obj /= Void then
|
||||
v_enc := url_encoded_string (l_obj.out, not reserved)
|
||||
else
|
||||
v_enc := ""
|
||||
end
|
||||
|
||||
if modifier_is_plus then
|
||||
Result.append (name)
|
||||
Result.append_character ('.')
|
||||
end
|
||||
if
|
||||
modifier_has_explode and
|
||||
(
|
||||
operator = '%U' or
|
||||
operator = '+' or
|
||||
operator = '?' or
|
||||
operator = '.' or
|
||||
operator = ';' or
|
||||
operator = '/'
|
||||
)
|
||||
then
|
||||
Result.append (k_enc)
|
||||
Result.append_character ('=')
|
||||
else
|
||||
Result.append (k_enc)
|
||||
Result.append_character (l_delimiter)
|
||||
end
|
||||
Result.append (v_enc)
|
||||
|
||||
l_table.forth
|
||||
if not l_table.after then
|
||||
Result.append_character (l_delimiter)
|
||||
end
|
||||
end
|
||||
end
|
||||
if Result.is_empty then
|
||||
Result := Void
|
||||
end
|
||||
else
|
||||
if d /= Void then
|
||||
v_enc := url_encoded_string (d.out, not reserved)
|
||||
elseif dft /= Void then
|
||||
v_enc := url_encoded_string (dft.out, not reserved)
|
||||
else
|
||||
v_enc := default_value
|
||||
end
|
||||
if operator = '?' then
|
||||
Result.append (name)
|
||||
if v_enc /= Void then
|
||||
Result.append_character ('=')
|
||||
end
|
||||
elseif operator = ';' then
|
||||
Result.append (name)
|
||||
if v_enc /= Void and then not v_enc.is_empty then
|
||||
Result.append_character ('=')
|
||||
end
|
||||
end
|
||||
if v_enc /= Void then
|
||||
Result.append (v_enc)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
url_encoded_string (s: READABLE_STRING_GENERAL; a_encoded: BOOLEAN): STRING
|
||||
do
|
||||
if a_encoded then
|
||||
Result := url_encoder.encoded_string (s.as_string_32)
|
||||
else
|
||||
Result := url_encoder.partial_encoded_string (s.as_string_32, <<
|
||||
':', ',',
|
||||
'+', '.', '/', ';', '?',
|
||||
'|', '!', '@'
|
||||
>>)
|
||||
end
|
||||
end
|
||||
|
||||
url_encoder: URL_ENCODER
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
;note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
25
library/protocol/uri_template/src/uri_template_handler.e
Normal file
25
library/protocol/uri_template/src/uri_template_handler.e
Normal file
@@ -0,0 +1,25 @@
|
||||
note
|
||||
description: "Summary description for {URI_TEMPLATE_HANDLER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
URI_TEMPLATE_HANDLER
|
||||
|
||||
feature -- Events
|
||||
|
||||
|
||||
|
||||
|
||||
note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
Reference in New Issue
Block a user