Files
EWF/library/protocol/uri_template/src/uri_template_expression_variable.e
2012-05-14 18:11:12 +02:00

440 lines
11 KiB
Plaintext

note
description: "Summary description for {URI_TEMPLATE_EXPRESSION_VARIABLE}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
URI_TEMPLATE_EXPRESSION_VARIABLE
inherit
ANY
URI_TEMPLATE_CONSTANTS
export {NONE} all end
create
make
feature {NONE} -- Initialization
make (exp: like expression; n: like name; d: like default_value; em: detachable STRING)
-- Create based on expression `exp', variable name `n', default value `d' if any
-- and explode or modifier string `em'
do
expression := exp
operator := exp.operator
name := n
default_value := d
if em /= Void and then em.count > 0 then
inspect em[1]
when Explode_star, Explode_plus then
explode := em[1]
when Modifier_substring, Modifier_remainder then
modifier := em
else
end
end
op_prefix := '%U'
op_separator := ','
inspect operator
when Reserved_operator then --| '+'
reserved := True
when Form_style_query_operator then --| '?'
op_prefix := '?'
op_separator := '&'
when form_style_query_continuation then --| '&'
op_prefix := '&'
op_separator := '&'
when Path_style_parameters_operator then --| ';'
op_prefix := ';'
op_separator := ';'
when Path_segment_operator then --| '/'
op_prefix := '/'
op_separator := '/'
when fragment_expansion then --| '#'
reserved := True
op_prefix := '#'
op_separator := ','
when Label_operator then --| '.'
op_prefix := '.'
op_separator := '.'
else
end
end
feature -- Access
expression: URI_TEMPLATE_EXPRESSION
-- Parent expression
operator: CHARACTER
-- First character of related `expression'
name: STRING
-- variable name
default_value: detachable STRING
-- default value if any
reserved: BOOLEAN
-- Is reserved?
-- i.e: do not url-encode the reserved character
op_prefix: CHARACTER
-- When expanding list of table, first character to use
--| ex: '?' for {?var}
op_separator: CHARACTER
-- When expanding list of table, delimiter character to use
--| ex: ',' for {?var}
explode: CHARACTER
-- Explode character , '*' or '+'
modifier: detachable STRING
-- Modifier expression, starting by ':' or '^'
--| ":3" , "-3", "^4", ...
modified_string (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 then
n := s.count
t := m.substring (2, m.count)
if t.is_integer then
i := t.to_integer
inspect m[1]
when Modifier_substring then
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
when Modifier_remainder then
if i > 0 then
if i < n then
Result := s.substring (i + 1, n)
end
elseif i < 0 then
Result := s.substring (1, n + i) --| n + i = n - (-i)
end
else
check Known_modified: False end
-- Unchanged
end
end
end
end
has_explode: BOOLEAN
do
Result := explode = Explode_plus or explode = Explode_star
end
has_explode_plus: BOOLEAN
do
Result := explode = Explode_plus
end
has_explode_star: BOOLEAN
do
Result := explode = Explode_star
end
feature -- Report
expanded_string (d: detachable ANY): detachable STRING
local
l_delimiter: CHARACTER
v_enc: detachable STRING
k_enc: STRING
l_obj: detachable ANY
i,n: INTEGER
explode_is_plus: BOOLEAN
explode_is_star: BOOLEAN
l_has_explode: BOOLEAN
dft: detachable ANY
has_list_op: BOOLEAN
op: like operator
do
l_has_explode := has_explode
if l_has_explode then
explode_is_plus := has_explode_plus
explode_is_star := has_explode_star
end
op := operator
has_list_op := op /= '%U' and op /= Reserved_operator
dft := default_value
create Result.make (20)
if attached {READABLE_STRING_GENERAL} d as l_string then
v_enc := url_encoded_string (modified_string (l_string), not reserved)
if op = Form_style_query_operator or op = form_style_query_continuation then
Result.append (name)
Result.append_character ('=')
elseif op = Path_style_parameters_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 op
when Path_style_parameters_operator,Form_style_query_operator, form_style_query_continuation then
if not l_has_explode then
Result.append (name)
Result.append_character ('=')
Result.append (dft.out)
else
if explode_is_plus then
Result.append (name)
Result.append_character ('.')
end
Result.append (dft.out)
end
-- if not explode_is_plus then
-- Result.append (name)
-- Result.append_character ('=')
-- Result.append (dft.out)
-- else
-- Result.append (name)
-- Result.append_character ('.')
-- Result.append (dft.out)
-- end
when Path_segment_operator then
if explode_is_plus then
Result.append (name)
Result.append_character ('.')
end
Result.append (dft.out)
when Label_operator then
else
if l_has_explode then
if explode_is_plus then
Result.append (name)
Result.append_character ('.')
end
Result.append (dft.out)
end
end
else
-- nothing ...
end
else
if l_has_explode then
l_delimiter := op_separator
else
l_delimiter := ','
inspect op
when Form_style_query_operator, form_style_query_continuation, path_style_parameters_operator then
Result.append (name)
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 explode_is_plus then
if
(op = Form_style_query_operator and explode_is_plus) or
(op = form_style_query_continuation and explode_is_plus) or
(op = Path_style_parameters_operator and l_has_explode)
then
Result.append (name)
Result.append_character ('=')
else
Result.append (name)
Result.append_character ('.')
end
elseif explode_is_star and (op = Form_style_query_operator or op = form_style_query_continuation or op = path_style_parameters_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 l_table.is_empty then
if dft /= Void then
inspect op
when Path_style_parameters_operator, Form_style_query_operator, form_style_query_continuation then
if not l_has_explode then
Result.append (name)
Result.append_character ('=')
Result.append (dft.out)
else
if explode_is_plus then
Result.append (name)
Result.append_character ('.')
end
Result.append (dft.out)
end
-- if not explode_is_plus then
-- Result.append (name)
-- Result.append_character ('=')
-- Result.append (dft.out)
-- else
-- Result.append (name)
-- Result.append_character ('.')
-- Result.append (dft.out)
-- end
when Path_segment_operator then
if explode_is_plus then
Result.append (name)
Result.append_character ('.')
end
Result.append (dft.out)
when Label_operator then
else
if l_has_explode then
if explode_is_plus then
Result.append (name)
Result.append_character ('.')
end
Result.append (dft.out)
end
end
else
-- nothing ...
end
else
if l_has_explode then
l_delimiter := op_separator
else
l_delimiter := ','
inspect op
when Form_style_query_operator, form_style_query_continuation, path_style_parameters_operator then
Result.append (name)
Result.append_character ('=')
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 explode_is_plus then
Result.append (name)
Result.append_character ('.')
end
if
l_has_explode
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 op = Form_style_query_operator or op = form_style_query_continuation then
Result.append (name)
if v_enc /= Void then
Result.append_character ('=')
end
elseif op = Path_style_parameters_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, <<
':', ',',
Reserved_operator,
Label_operator,
Path_segment_operator,
Path_style_parameters_operator,
Form_style_query_operator,
'|', '!', '@'
>>)
end
end
url_encoder: URL_ENCODER
once
create Result
end
;note
copyright: "2011-2012, Jocelyn Fiat, 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