Change structure of EWF, to follow better categorization

This commit is contained in:
Jocelyn Fiat
2012-06-13 22:32:17 +02:00
parent 3df1a26220
commit db448001a1
134 changed files with 105 additions and 94 deletions

View File

@@ -0,0 +1,523 @@
note
description: "[
Implementation of URI Template RFC6570.
See http://tools.ietf.org/html/rfc6570
]"
legal: "See notice at end of class."
status: "See notice at end of class."
date: "$Date$"
revision: "$Revision$"
class
URI_TEMPLATE
inherit
HASHABLE
DEBUG_OUTPUT
create
make
create {URI_TEMPLATE}
make_from_uri_template
convert
make ({READABLE_STRING_8})
feature {NONE} -- Initialization
make (s: READABLE_STRING_8)
do
template := s
end
make_from_uri_template (a_tpl: like Current)
do
template := a_tpl.template.string
end
feature -- Access
template: READABLE_STRING_8
-- URI string representation
duplicate: like Current
-- Duplicate object from Current
do
create Result.make_from_uri_template (Current)
end
feature -- Element change
set_template (t: like template)
-- Set `template' to `t'
do
template := t
reset
end
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]
-- All variable names
do
analyze
if attached expressions as l_expressions then
create {ARRAYED_LIST [STRING]} Result.make (l_expressions.count)
from
l_expressions.start
until
l_expressions.after
loop
Result.append (l_expressions.item.variable_names)
l_expressions.forth
end
else
create {ARRAYED_LIST [STRING]} Result.make (0)
end
end
path_variable_names: LIST [STRING]
-- All variable names part of the path
do
analyze
if attached expressions as l_expressions then
create {ARRAYED_LIST [STRING]} Result.make (l_expressions.count)
from
l_expressions.start
until
l_expressions.after
loop
if not l_expressions.item.is_query then
Result.append (l_expressions.item.variable_names)
end
l_expressions.forth
end
else
create {ARRAYED_LIST [STRING]} Result.make (0)
end
end
query_variable_names: LIST [STRING]
-- All variable names part of the query (i.e after '?')
do
analyze
if attached expressions as l_expressions then
create {ARRAYED_LIST [STRING]} Result.make (l_expressions.count)
from
l_expressions.start
until
l_expressions.after
loop
if l_expressions.item.is_query then
Result.append (l_expressions.item.variable_names)
end
l_expressions.forth
end
else
create {ARRAYED_LIST [STRING]} Result.make (0)
end
end
feature -- Builder
expanded_string (a_ht: HASH_TABLE [detachable ANY, STRING]): STRING
-- Expanded template using variable from `a_ht'
local
tpl: like template
exp: URI_TEMPLATE_EXPRESSION
p,q: INTEGER
do
analyze
tpl := template
if attached expressions as l_expressions then
create Result.make (tpl.count)
from
l_expressions.start
p := 1
until
l_expressions.after
loop
q := l_expressions.item.position
--| Added inter variable text
Result.append (tpl.substring (p, q - 1))
--| Expand variables ...
exp := l_expressions.item
exp.append_expanded_to_string (a_ht, Result)
p := q + l_expressions.item.expression.count + 2
l_expressions.forth
end
Result.append (tpl.substring (p, tpl.count))
else
create Result.make_from_string (tpl)
end
end
expanded_string_with_base_url (a_base_url: READABLE_STRING_8; a_ht: HASH_TABLE [detachable ANY, STRING]): STRING
-- Expanded template using variable from `a_ht'
-- with based url
do
Result := a_base_url + expanded_string (a_ht)
end
feature -- Match
match (a_uri: READABLE_STRING_8): detachable URI_TEMPLATE_MATCH_RESULT
require
is_valid: is_valid
local
b: BOOLEAN
tpl: like template
l_offset: INTEGER
p,q,nb: INTEGER
exp: URI_TEMPLATE_EXPRESSION
vn, s,t: STRING
vv, path_vv: STRING
l_vars, l_path_vars, l_query_vars: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
l_uri_count: INTEGER
tpl_count: INTEGER
l_next_literal_separator: detachable STRING
do
--| Extract expansion parts "\\{([^\\}]*)\\}"
analyze
if attached expressions as l_expressions then
create l_path_vars.make (l_expressions.count)
create l_query_vars.make (l_expressions.count)
l_vars := l_path_vars
b := True
l_uri_count := a_uri.count
tpl := template
tpl_count := tpl.count
if l_expressions.is_empty then
-- b := a_uri.substring (1, tpl_count).same_string (tpl)
b := a_uri.same_string (tpl)
else
from
l_expressions.start
p := 0
l_offset := 0
until
l_expressions.after or not b
loop
exp := l_expressions.item
vn := exp.expression
q := exp.position
--| Check text between vars
if p = q then
--| There should be at least one literal between two expression
--| {var}{foobar} is ambigous for matching ...
--| unless with {/var} or {?var} ... since we can search for '/' or '?'
exp.analyze
b := exp.operator = '/' or exp.operator = '?'
p := exp.end_position
elseif q > p then
if p = 0 then
p := 1
end
t := tpl.substring (p, q - 1)
s := a_uri.substring (p + l_offset, q + l_offset - 1)
b := s.same_string (t)
p := exp.end_position
end
l_expressions.forth --| we forth `l_expressions' so be careful
--| Check related variable
if b and then not vn.is_empty then
if exp.is_query then
l_vars := l_query_vars
else
l_vars := l_path_vars
end
if q + l_offset <= l_uri_count then
inspect vn[1]
when '?' then
import_form_style_parameters_into (a_uri.substring (q + l_offset + 1, l_uri_count), l_vars)
p := tpl_count + 1
l_offset := l_offset + (l_uri_count - (q + l_offset + 1))
when ';' then
import_path_style_parameters_into (a_uri.substring (q + l_offset, l_uri_count), l_vars)
p := tpl_count + 1
else
if not l_expressions.after then
exp := l_expressions.item --| We change `exp' here
exp.analyze
if exp.operator = '/' or exp.operator = '?' then
l_next_literal_separator := Void
else
l_next_literal_separator := tpl.substring (p, exp.position -1)
end
elseif p < tpl_count then
l_next_literal_separator := tpl.substring (p, tpl_count)
else
l_next_literal_separator := Void
end
if vn[1] = '/' then
vn := vn.substring (2, vn.count)
from
create path_vv.make_empty
vv := "/"
nb := 0
until
vv.is_empty or q + l_offset + 1 > a_uri.count
loop
vv := next_path_variable_value (a_uri, q + l_offset + 1, l_next_literal_separator)
l_offset := l_offset + vv.count + 1
nb := nb + 1
if not vv.is_empty then
path_vv.extend ('/')
path_vv.append (vv)
l_vars.force (vv, vn + "[" + nb.out + "]")
end
end
l_vars.force (path_vv, vn)
l_offset := l_offset - (1 + vn.count + 2)
else
vv := next_path_variable_value (a_uri, q + l_offset, l_next_literal_separator)
l_vars.force (vv, vn)
l_offset := l_offset + vv.count - (vn.count + 2)
end
end
else
b := exp.is_query --| query are optional
end
end
if b and l_expressions.after then
if
(p < tpl_count) or
(p + l_offset < l_uri_count)
then
--| Remaining literal part
t := tpl.substring (p, tpl_count)
s := a_uri.substring (p + l_offset, l_uri_count)
b := s.same_string (t)
end
end
end
end
if b then
create Result.make (l_path_vars, l_query_vars)
end
end
end
feature -- Basic operation
parse
-- Parse template
do
reset
analyze
end
feature -- Status report
is_valid: BOOLEAN
-- Is Current URI template valid?
do
analyze
Result := not has_syntax_error
end
feature {NONE} -- Internal Access
reset
do
expressions := Void
has_syntax_error := False
end
has_syntax_error: BOOLEAN
-- Has syntax error
--| Make sense only if `analyze' was processed before
expressions: detachable LIST [URI_TEMPLATE_EXPRESSION]
-- Expansion parts
feature {NONE} -- Implementation
analyze
local
l_expressions: like expressions
c: CHARACTER
i,p,n: INTEGER
tpl: like template
in_x: BOOLEAN
in_query: BOOLEAN
x: STRING
exp: URI_TEMPLATE_EXPRESSION
l_has_query_expression: BOOLEAN
do
l_expressions := expressions
if l_expressions = Void then
tpl := template
--| Extract expansion parts "\\{([^\\}]*)\\}"
create {ARRAYED_LIST [like expressions.item]} l_expressions.make (tpl.occurrences ('{'))
from
i := 1
n := tpl.count
l_has_query_expression := False
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_expressions.force (exp)
x.wipe_out
in_x := False
if l_has_query_expression and then i < n then
--| Remaining text after {?exp}
has_syntax_error := True
end
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 l_has_query_expression then
l_has_query_expression := tpl.valid_index (i+1) and then tpl[i+1] = '?'
end
if not in_query then
in_query := l_has_query_expression
end
when '?' then
in_query := True
else
end
end
i := i + 1
end
expressions := l_expressions
end
end
import_path_style_parameters_into (a_content: STRING; res: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8])
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 [READABLE_STRING_8, READABLE_STRING_8])
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 [READABLE_STRING_8, READABLE_STRING_8])
require
a_content_attached: a_content /= Void
res_attached: res /= Void
local
n, p, i, j: INTEGER
s: READABLE_STRING_8
l_name, l_value: READABLE_STRING_8
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; a_end_token: detachable STRING): STRING
require
valid_index: a_index <= a_uri.count
local
c: CHARACTER
i,n,p: INTEGER
l_end_token_first_char: CHARACTER
l_end_token_count: INTEGER
do
from
if a_end_token /= Void and then not a_end_token.is_empty then
l_end_token_first_char := a_end_token.item (1)
l_end_token_count := a_end_token.count
end
i := a_index
n := a_uri.count
until
i > n
loop
c := a_uri[i]
inspect c
when '/', '?' then
i := n
else
if
a_end_token /= Void and then
c = l_end_token_first_char and then
a_uri.substring (i, i + l_end_token_count - 1).same_string (a_end_token)
then
i := n
else
p := i
end
end
i := i + 1
end
Result := a_uri.substring (a_index, p)
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

View File

@@ -0,0 +1,56 @@
note
description: "[
Summary description for {URI_TEMPLATE_CONSTANTS}.
see http://tools.ietf.org/html/rfc6570
]"
author: "Jocelyn Fiat"
date: "$Date$"
revision: "$Revision$"
class
URI_TEMPLATE_CONSTANTS
feature -- Operator
Reserved_operator: CHARACTER = '+'
Form_style_query_operator: CHARACTER = '?'
Form_style_query_continuation: CHARACTER = '&'
Path_style_parameters_operator: CHARACTER = ';'
Path_segment_operator: CHARACTER = '/'
Fragment_expansion: CHARACTER = '#'
Label_operator: CHARACTER = '.'
feature -- Separator
Default_delimiter: CHARACTER = '=' --| Not included in the RFC, but was part of previous Draft
feature -- Explode
Explode_plus: CHARACTER = '+'
Explode_star: CHARACTER = '*'
feature -- Modified
Modifier_substring: CHARACTER = ':'
Modifier_remainder: CHARACTER = '^'
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

View File

@@ -0,0 +1,285 @@
note
description: "Summary description for {URI_TEMPLATE_EXPRESSION}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
URI_TEMPLATE_EXPRESSION
inherit
ANY
DEBUG_OUTPUT
export {NONE} all end
URI_TEMPLATE_CONSTANTS
export {NONE} all end
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 Reserved_operator then
--| '+'
reserved := True
operator := '+'
when Label_operator then
--| '.'
operator := '.'
op_prefix := '.'
op_delimiter := '.'
when Path_segment_operator then
--| '/'
operator := '/'
op_prefix := '/'
op_delimiter := '/'
when Path_style_parameters_operator then
--| ';'
operator := ';'
op_prefix := ';'
op_delimiter := ';'
when Form_style_query_operator then
--| '?'
operator := '?'
op_prefix := '?'
op_delimiter := '&'
when form_style_query_continuation then
--| '&'
operator := '&'
op_prefix := '&'
op_delimiter := '&'
when fragment_expansion then
--| '#'
reserved := True
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 (Default_delimiter, 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 Explode_plus, Explode_star, Modifier_substring, Modifier_remainder 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 (Current, vn, s, vmodifier))
lst.forth
end
variables := vars
end
is_analyzed := True
end
end
feature -- Access
position: INTEGER
-- Character position on Current in the template
end_position: INTEGER
do
Result := position + expression.count + 2 --| '{' + `expression' + '}'
end
expression: STRING
-- Operator? + VariableName + modifier
is_query: BOOLEAN
-- Is in the query part (i.e: after '?' ?)
feature -- Status
operator: CHARACTER
-- First character of `expression' if among
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_delimiter: CHARACTER
-- When expanding list of table, delimiter character to use
--| ex: ',' for {?var}
variables: detachable LIST [URI_TEMPLATE_EXPRESSION_VARIABLE]
-- List of variables declared in `expression'
--| ex: "foo", "bar" for {?foo,bar}
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_expanded_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)
end
end
feature {NONE} -- Implementation
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.expanded_string (vdata)
if vstr = Void and vi.has_explode 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 = Form_style_query_operator or operator = form_style_query_continuation or operator = path_style_parameters_operator) and not vi.has_explode_star then
a_buffer.append (vi.name)
if vi.has_explode_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-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

View File

@@ -0,0 +1,420 @@
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
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
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

View 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

View File

@@ -0,0 +1,123 @@
note
description: "Summary description for {URI_TEMPLATE_MATCH_RESULT}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
URI_TEMPLATE_MATCH_RESULT
create
make,
make_empty
feature {NONE} -- Initialization
make (p: like path_variables; q: like query_variables)
do
path_variables := p
query_variables := q
end
make_empty
do
make (create {like path_variables}.make (0), create {like query_variables}.make (0))
end
feature -- Access
path_variables: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
-- Variables being part of the path segments
query_variables: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
-- Variables being part of the query segments (i.e: after the ?)
feature -- Query
path_variable (n: READABLE_STRING_8): detachable READABLE_STRING_8
-- Value related to query variable name `n'
do
Result := path_variables.item (n)
end
query_variable (n: READABLE_STRING_8): detachable READABLE_STRING_8
-- Value related to path variable name `n'
do
Result := query_variables.item (n)
end
variable (n: READABLE_STRING_8): detachable READABLE_STRING_8
-- Value related to variable name `n'
do
Result := query_variable (n)
if Result = Void then
Result := path_variable (n)
end
end
feature -- Query: url-decoded
encoded_name (n: READABLE_STRING_GENERAL): READABLE_STRING_8
-- URL encoded name `n'
-- to be used with ..._variable functions
do
if attached {READABLE_STRING_32} n as n32 then
Result := url_encoded_string (n32)
else
Result := n.as_string_8
end
end
url_decoded_query_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- Unencoded value related to variable name `n'
do
if attached query_variable (encoded_name (n)) as v then
Result := url_decoded_string (v)
end
end
url_decoded_path_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- Unencoded value related to variable name `n'
do
if attached path_variable (encoded_name (n)) as v then
Result := url_decoded_string (v)
end
end
url_decoded_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- Unencoded value related to variable name `n'
do
if attached variable (encoded_name (n)) as v then
Result := url_decoded_string (v)
end
end
feature {NONE} -- Implementation
url_decoded_string (s: READABLE_STRING_8): READABLE_STRING_32
do
Result := url_encoder.decoded_string (s)
end
url_encoded_string (s: READABLE_STRING_32): READABLE_STRING_8
do
Result := url_encoder.encoded_string (s)
end
url_encoder: URL_ENCODER
once
create Result
end
;note
copyright: "2011-2012, 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