Files
EWF/library/protocol/uri_template/src/uri_template_expression_variable.e
Jocelyn Fiat 51b70a2490 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.
2011-07-20 12:11:05 +02:00

399 lines
9.1 KiB
Plaintext

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